From afa684f6fda6086b229348f0ea21df7c8ad17964 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Mon, 24 Sep 2007 21:24:41 -0700 Subject: fix "mspec: handle shrinking virtual memory areas" The vma_data structure may be shared by vma's from multiple tasks, with no way of knowing which areas are shared or not shared, so release/clear pages only when the refcount (of vma's) goes to zero. Signed-off-by: Cliff Wickman Cc: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/mspec.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 049a46cc9f87..04ac155d3a07 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -155,23 +155,22 @@ mspec_open(struct vm_area_struct *vma) * mspec_close * * Called when unmapping a device mapping. Frees all mspec pages - * belonging to the vma. + * belonging to all the vma's sharing this vma_data structure. */ static void mspec_close(struct vm_area_struct *vma) { struct vma_data *vdata; - int index, last_index, result; + int index, last_index; unsigned long my_page; vdata = vma->vm_private_data; - BUG_ON(vma->vm_start < vdata->vm_start || vma->vm_end > vdata->vm_end); + if (!atomic_dec_and_test(&vdata->refcnt)) + return; - spin_lock(&vdata->lock); - index = (vma->vm_start - vdata->vm_start) >> PAGE_SHIFT; - last_index = (vma->vm_end - vdata->vm_start) >> PAGE_SHIFT; - for (; index < last_index; index++) { + last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT; + for (index = 0; index < last_index; index++) { if (vdata->maddr[index] == 0) continue; /* @@ -180,20 +179,12 @@ mspec_close(struct vm_area_struct *vma) */ my_page = vdata->maddr[index]; vdata->maddr[index] = 0; - spin_unlock(&vdata->lock); - result = mspec_zero_block(my_page, PAGE_SIZE); - if (!result) + if (!mspec_zero_block(my_page, PAGE_SIZE)) uncached_free_page(my_page); else printk(KERN_WARNING "mspec_close(): " - "failed to zero page %i\n", - result); - spin_lock(&vdata->lock); + "failed to zero page %ld\n", my_page); } - spin_unlock(&vdata->lock); - - if (!atomic_dec_and_test(&vdata->refcnt)) - return; if (vdata->flags & VMD_VMALLOCED) vfree(vdata); @@ -201,7 +192,6 @@ mspec_close(struct vm_area_struct *vma) kfree(vdata); } - /* * mspec_nopfn * -- cgit v1.2.1 From 78e1ca49c7ead5cd00882ed0c776260857613122 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Thu, 20 Sep 2007 21:23:13 -0400 Subject: ACPI: hpet: ACPI Error (utglobal-0126): Unknown exception code: 0xFFFFFFF0 If hpet has been initialized before registering hpet driver, the callback function of hpet_resources will return the status code of -EBUSY, which is not defined in the ACPI exception table. So when ACPI checks the status code of callback function, it will report the unknown exception code. So the status code in ACPI is used instead of the generic error code in the ACPI callback function of hpet_resources. For example: -EBUSY is replaced by AE_ALREADY_EXISTS -EINVAL is replaced by AE_NO_MEMORY http://bugzilla.kernel.org/show_bug.cgi?id=8630 Signed-off-by: Zhao Yakui Signed-off-by: Len Brown --- drivers/char/hpet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 7ecffc9c738f..fd51554ab081 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -943,14 +943,14 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) printk(KERN_DEBUG "%s: 0x%lx is busy\n", __FUNCTION__, hdp->hd_phys_address); iounmap(hdp->hd_address); - return -EBUSY; + return AE_ALREADY_EXISTS; } } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { struct acpi_resource_fixed_memory32 *fixmem32; fixmem32 = &res->data.fixed_memory32; if (!fixmem32) - return -EINVAL; + return AE_NO_MEMORY; hdp->hd_phys_address = fixmem32->address; hdp->hd_address = ioremap(fixmem32->address, @@ -960,7 +960,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) printk(KERN_DEBUG "%s: 0x%lx is busy\n", __FUNCTION__, hdp->hd_phys_address); iounmap(hdp->hd_address); - return -EBUSY; + return AE_ALREADY_EXISTS; } } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { struct acpi_resource_extended_irq *irqp; -- cgit v1.2.1 From 3dffec45c2742961dd27f55aba426cb9cf3f0dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Wed, 26 Sep 2007 12:15:33 +0300 Subject: Silent drivers/char/hpet.c build warnings on i386 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following patch silents; ... drivers/char/hpet.c:72: warning: 'clocksource_hpet' defined but not used drivers/char/hpet.c:81: warning: 'hpet_clocksource' defined but not used ... build warnings on i386, they appeared after commit 3b2b64fd311c92f2137eb7cee7025794cd854057 Signed-off-by: S.Çağlar Onur Signed-off-by: Linus Torvalds -- drivers/char/hpet.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) --- drivers/char/hpet.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/char') diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index fd51554ab081..4c16778e3f84 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -62,6 +62,8 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; +/* This clocksource driver currently only works on ia64 */ +#ifdef CONFIG_IA64 static void __iomem *hpet_mctr; static cycle_t read_hpet(void) @@ -79,6 +81,7 @@ static struct clocksource clocksource_hpet = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static struct clocksource *hpet_clocksource; +#endif /* A lock for concurrent access by app and isr hpet activity. */ static DEFINE_SPINLOCK(hpet_lock); -- cgit v1.2.1 From e4a7b1d1d90d202a030688ab5b177c3c0f15ee3e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 28 Sep 2007 11:46:28 +1000 Subject: i915: make vbl interrupts work properly on i965g/gm hw. This code is ported from the DRM git tree and allows the vblank interrupts to function on the i965 hw. It also requires a change in Mesa's 965 driver to actually use them. [ Without this patch, my 965GM drops vblank interrupts - Jesse ] Signed-off-by: Dave Airlie Acked-by: Jesse Barnes Signed-off-by: Linus Torvalds --- drivers/char/drm/i915_drv.h | 6 ++++++ drivers/char/drm/i915_irq.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers/char') diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 737088bd0780..28b98733beb8 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 +#define I915REG_PIPEASTAT 0x70024 +#define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) + #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 4b4b2ce89863..bb8e9e9c8201 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c @@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; + u32 pipea_stats, pipeb_stats; + + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); temp = I915_READ16(I915REG_INT_IDENTITY_R); @@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; -- cgit v1.2.1 From a64314e62d89562b6fc77593648bec3acc35bf61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Sat, 29 Sep 2007 18:47:51 +0200 Subject: fix console change race exposed by CFS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new behaviour of CFS exposes a race which occurs if a switch is requested when vt_mode.mode is VT_PROCESS. The process with vc->vt_pid is signaled before vc->vt_newvt is set. This causes the switch to fail when triggered by the monitoing process because the target is still -1. [ If the signal sending fails, the subsequent "reset_vc(vc)" will then reset vt_newvt to -1, so this works for that case too. - Linus ] Signed-off-by: Jan Lübbe Signed-off-by: Linus Torvalds --- drivers/char/vt_ioctl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c6f6f4209739..045e6888d15b 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -1208,15 +1208,18 @@ void change_console(struct vc_data *new_vc) /* * Send the signal as privileged - kill_pid() will * tell us if the process has gone or something else - * is awry + * is awry. + * + * We need to set vt_newvt *before* sending the signal or we + * have a race. */ + vc->vt_newvt = new_vc->vc_num; if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { /* * It worked. Mark the vt to switch to and * return. The process needs to send us a * VT_RELDISP ioctl to complete the switch. */ - vc->vt_newvt = new_vc->vc_num; return; } -- cgit v1.2.1 From 8792f961ba8057d9f27987def3600253a3ba060f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 1 Oct 2007 01:20:12 -0700 Subject: VT ioctl race fix When calling the RELDISP VT ioctl, we are reading vt_newvt while the console workqueue could be messing with it (through change_console()). We fix this race by taking the console semaphore before reading vt_newvt. Signed-off-by: Samuel Ortiz Acked-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/vt_ioctl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 045e6888d15b..c799b7f7bbb3 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * Switching-from response */ + acquire_console_sem(); if (vc->vt_newvt >= 0) { if (arg == 0) /* @@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * complete the switch. */ int newvt; - acquire_console_sem(); newvt = vc->vt_newvt; vc->vt_newvt = -1; i = vc_allocate(newvt); @@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * other console switches.. */ complete_change_console(vc_cons[newvt].d); - release_console_sem(); } } @@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * If it's just an ACK, ignore it */ - if (arg != VT_ACKACQ) + if (arg != VT_ACKACQ) { + release_console_sem(); return -EINVAL; + } } + release_console_sem(); return 0; -- cgit v1.2.1 From 9b42c336d06411e6463949d2dac63949f66ff70b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 1 Oct 2007 13:58:36 -0700 Subject: [TCP]: secure_tcp_sequence_number() should not use a too fast clock TCP V4 sequence numbers are 32bits, and RFC 793 assumed a 250 KHz clock. In order to follow network speed increase, we can use a faster clock, but we should limit this clock so that the delay between two rollovers is greater than MSL (TCP Maximum Segment Lifetime : 2 minutes) Choosing a 64 nsec clock should be OK, since the rollovers occur every 274 seconds. Problem spotted by Denys Fedoryshchenko [ This bug was introduced by f85958151900f9d30fa5ff941b0ce71eaa45a7de ] Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/char/random.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/random.c b/drivers/char/random.c index 397c714cf2ba..af274e5a25ee 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1550,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, * As close as possible to RFC 793, which * suggests using a 250 kHz clock. * Further reading shows this assumes 2 Mb/s networks. - * For 10 Gb/s Ethernet, a 1 GHz clock is appropriate. - * That's funny, Linux has one built in! Use it! - * (Networks are faster now - should this be increased?) + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but + * we also need to limit the resolution so that the u32 seq + * overlaps less than one time per MSL (2 minutes). + * Choosing a clock of 64 ns period is OK. (period of 274 s) */ - seq += ktime_get_real().tv64; + seq += ktime_get_real().tv64 >> 6; #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", saddr, daddr, sport, dport, seq); -- cgit v1.2.1