2.6.32.12-stable review
Subsystems (68)
cover 2.6.32.12-stable review
This is the start of the stable review cycle for the 2.6.32.12 release. There are 197 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Saturday, April 24, 15:00:00 UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.32.12-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Documentation/i2c/busses/i2c-i801 | 3 +- Documentation/laptops/thinkpad-acpi.txt | 55 +--- Makefile | 2 +- arch/arm/boot/compressed/head.S | 2 +- arch/ia64/kvm/kvm-ia64.c | 9 +- arch/mips/mm/tlbex.c | 22 +- arch/mips/mm/uasm.c | 4 +- arch/mips/mm/uasm.h | 1 + arch/sh/include/asm/elf.h | 6 +- arch/sh/kernel/smp.c | 1 + arch/um/sys-x86_64/Makefile | 3 +- arch/x86/Kconfig.cpu | 2 +- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/include/asm/kvm_emulate.h | 15 +- arch/x86/include/asm/kvm_host.h | 11 +- arch/x86/include/asm/msr-index.h | 1 + arch/x86/include/asm/rwsem.h | 81 +++-- arch/x86/include/asm/smp.h | 9 + arch/x86/kernel/amd_iommu.c | 4 +- arch/x86/kernel/amd_iommu_init.c | 6 +- arch/x86/kernel/aperture_64.c | 15 +- arch/x86/kernel/apic/apic.c | 2 + arch/x86/kernel/cpu/amd.c | 53 +--- arch/x86/kernel/cpu/intel_cacheinfo.c | 250 ++++++++++------ arch/x86/kernel/cpu/perf_event.c | 104 +++++++- arch/x86/kernel/crash.c | 6 - arch/x86/kernel/hpet.c | 25 ++- arch/x86/kernel/pci-gart_64.c | 3 + arch/x86/kvm/emulate.c | 192 ++++++++++--- arch/x86/kvm/mmu.c | 28 +- arch/x86/kvm/mmu.h | 6 + arch/x86/kvm/paging_tmpl.h | 11 +- arch/x86/kvm/svm.c | 34 ++- arch/x86/kvm/vmx.c | 43 ++- arch/x86/kvm/x86.c | 366 +++++++++++++++++------ arch/x86/lib/Makefile | 3 +- arch/x86/lib/cache-smp.c | 19 ++ arch/x86/lib/rwsem_64.S | 81 +++++ arch/x86/pci/irq.c | 2 + arch/x86/power/hibernate_asm_32.S | 15 +- drivers/acpi/acpica/exprep.c | 17 + drivers/acpi/ec.c | 35 +-- drivers/ata/ahci.c | 6 + drivers/ata/ata_piix.c | 8 + drivers/ata/libata-core.c | 3 + drivers/ata/pata_ali.c | 4 +- drivers/ata/pata_via.c | 1 + drivers/char/agp/hp-agp.c | 3 +- drivers/char/agp/intel-agp.c | 15 +- drivers/char/raw.c | 1 + drivers/char/tpm/tpm_tis.c | 1 + drivers/char/tty_io.c | 2 + drivers/gpu/drm/drm_crtc_helper.c | 1 + drivers/gpu/drm/drm_edid.c | 11 +- drivers/gpu/drm/drm_fops.c | 16 +- drivers/gpu/drm/i915/intel_lvds.c | 8 + drivers/gpu/drm/radeon/r300.c | 5 +- drivers/gpu/drm/radeon/radeon_connectors.c | 7 +- drivers/gpu/drm/radeon/radeon_cp.c | 10 +- drivers/gpu/drm/radeon/radeon_cs.c | 3 +- drivers/gpu/drm/radeon/radeon_encoders.c | 8 +- drivers/gpu/drm/radeon/radeon_legacy_tv.c | 29 ++- drivers/gpu/drm/radeon/rs600.c | 2 +- drivers/gpu/vga/vgaarb.c | 27 ++- drivers/hid/hid-gyration.c | 5 +- drivers/hwmon/lis3lv02d.c | 24 +- drivers/hwmon/lis3lv02d.h | 1 + drivers/hwmon/sht15.c | 13 +- drivers/i2c/busses/Kconfig | 5 +- drivers/i2c/busses/i2c-i801.c | 5 +- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 + drivers/infiniband/ulp/iser/iser_memory.c | 122 ++++---- drivers/input/tablet/wacom_sys.c | 10 +- drivers/md/dm.c | 21 +- drivers/md/linear.c | 12 +- drivers/md/multipath.c | 20 +- drivers/md/raid0.c | 13 +- drivers/md/raid10.c | 28 +- drivers/md/raid5.c | 19 +- drivers/message/fusion/mptctl.c | 5 +- drivers/message/fusion/mptscsih.c | 86 +++++- drivers/net/e1000e/netdev.c | 2 + drivers/net/igb/e1000_82575.c | 1 + drivers/net/igb/e1000_hw.h | 1 + drivers/net/igb/igb_main.c | 1 + drivers/net/r8169.c | 29 ++- drivers/net/wireless/ath/ar9170/usb.c | 2 +- drivers/net/wireless/b43/Kconfig | 6 +- drivers/net/wireless/b43/Makefile | 2 +- drivers/net/wireless/b43/b43.h | 28 +-- drivers/net/wireless/b43/dma.c | 2 - drivers/net/wireless/b43/main.c | 10 +- drivers/net/wireless/b43/pio.c | 79 +++-- drivers/net/wireless/b43/pio.h | 40 --- drivers/net/wireless/b43/xmit.c | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 11 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 + drivers/net/wireless/iwlwifi/iwl-scan.c | 27 +- drivers/net/wireless/iwlwifi/iwl-tx.c | 1 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- drivers/pci/pci.c | 24 ++- drivers/pci/pcie/aer/aer_inject.c | 20 ++- drivers/platform/x86/Kconfig | 10 +- drivers/platform/x86/eeepc-laptop.c | 110 +++++++ drivers/platform/x86/thinkpad_acpi.c | 439 +++++++++++++++------------ drivers/scsi/libiscsi.c | 5 +- drivers/scsi/scsi_ioctl.c | 3 + drivers/scsi/scsi_transport_fc.c | 5 +- drivers/staging/comedi/drivers/usbdux.c | 20 +- drivers/usb/class/cdc-acm.c | 43 ++-- drivers/usb/class/cdc-acm.h | 1 - drivers/video/backlight/mbp_nvidia_bl.c | 45 +++ drivers/watchdog/hpwdt.c | 2 +- drivers/watchdog/iTCO_wdt.c | 99 ++++++- fs/9p/vfs_file.c | 2 +- fs/block_dev.c | 3 +- fs/cifs/cifssmb.c | 19 ++- fs/ecryptfs/inode.c | 108 ++++---- fs/ecryptfs/super.c | 1 - fs/ext3/super.c | 2 - fs/ext3/xattr.c | 7 +- fs/ext4/ext4.h | 6 +- fs/ext4/extents.c | 2 +- fs/ext4/inode.c | 13 +- fs/fat/namei_vfat.c | 6 +- fs/fs-writeback.c | 17 + fs/nfs/client.c | 3 +- fs/nfs/dir.c | 2 +- fs/nfs/nfs4proc.c | 4 +- fs/nfsd/nfs4xdr.c | 12 +- fs/ocfs2/acl.c | 77 +++++- fs/ocfs2/suballoc.c | 13 +- fs/proc/base.c | 5 +- fs/quota/dquot.c | 12 +- fs/xfs/linux-2.6/xfs_acl.c | 3 +- fs/xfs/linux-2.6/xfs_aops.c | 118 +++++--- fs/xfs/linux-2.6/xfs_iops.c | 6 +- fs/xfs/linux-2.6/xfs_super.c | 60 ++++- fs/xfs/linux-2.6/xfs_sync.c | 194 ++++++------- fs/xfs/linux-2.6/xfs_sync.h | 3 +- fs/xfs/quota/xfs_qm_bhv.c | 2 +- fs/xfs/quota/xfs_qm_syscalls.c | 2 +- fs/xfs/xfs_alloc.c | 52 ++-- fs/xfs/xfs_dfrag.c | 106 ++++++- fs/xfs/xfs_fsops.c | 2 +- fs/xfs/xfs_iget.c | 31 ++- fs/xfs/xfs_inode.c | 17 +- fs/xfs/xfs_iomap.c | 9 +- fs/xfs/xfs_log_recover.c | 24 +- fs/xfs/xfs_mount.c | 2 +- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_rw.h | 7 - fs/xfs/xfs_trans.c | 7 +- fs/xfs/xfs_trans.h | 2 +- fs/xfs/xfs_vnodeops.c | 179 ++++------- fs/xfs/xfs_vnodeops.h | 1 - include/drm/drm_pciids.h | 2 + include/linux/freezer.h | 7 +- include/linux/fs.h | 1 + include/linux/kvm_host.h | 7 +- include/linux/module.h | 2 +- include/linux/nfs_fs_sb.h | 1 + include/linux/pci.h | 5 + include/linux/pci_ids.h | 3 + include/linux/resource.h | 8 +- include/linux/writeback.h | 1 + include/scsi/scsi_bsg_fc.h | 2 +- kernel/cgroup_freezer.c | 9 +- kernel/irq/manage.c | 10 + kernel/lockdep.c | 6 +- kernel/module.c | 2 +- kernel/power/process.c | 2 +- kernel/sched.c | 19 +- mm/readahead.c | 2 +- net/ipv4/tcp_input.c | 6 +- net/mac80211/scan.c | 18 +- net/mac80211/tx.c | 6 + net/mac80211/util.c | 20 +- net/sunrpc/svc_xprt.c | 13 +- net/sunrpc/svcauth_unix.c | 53 ++-- net/sunrpc/svcsock.c | 1 + sound/pci/hda/hda_intel.c | 8 + sound/pci/hda/patch_analog.c | 8 + sound/pci/hda/patch_realtek.c | 11 +- sound/pci/mixart/mixart.c | 24 +- sound/usb/usbmidi.c | 24 ++- virt/kvm/kvm_main.c | 13 +- 187 files changed, 3063 insertions(+), 1557 deletions(-)
PATCH 1/197 drm/edid: allow certain bogus edids to hit a fixup path rather than fail
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Skeggs <[email protected]>
commit 44fef22416886a04d432043f741a6faf2c6ffefd upstream.
--- drivers/gpu/drm/drm_edid.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/gpu/drm/drm_edid.c +0 -9
@@ -653,15 +653,6 @@ static struct drm_display_mode *drm_mode mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; -/* perform the basic check for the detailed timing */ -if (mode->hsync_end > mode->htotal || - mode->vsync_end > mode->vtotal) { -drm_mode_destroy (dev, mode); -DRM_DEBUG_KMS ("Incorrect detailed timing. " -"Sync is beyond the blank.\n" ); -return NULL ; - } -/* Some EDIDs have bogus h/vtotal values */ if (mode->hsync_end > mode->htotal) mode->htotal = mode->hsync_end +1 ;
PATCH 2/197 drm/radeon: add new RS880 pci id
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 338e2b1d571e4873908b199c90d6a31f65137fe3 upstream.
This should go to 2.6.33 stable as well.
--- include/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+)
include/drm/drm_pciids.h +1 -0
@@ -375,6 +375,7 @@ {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \
PATCH 3/197 drm: remove the EDID blob stored in the EDID property when it is disconnected
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Zhao Yakui <[email protected]>
commit 725398322d05486109375fbb85c3404108881e17 upstream.
Now the EDID property will be updated when the corresponding EDID can be obtained from the external display device. But after the external device is plugged-out, the EDID property is not updated. In such case we still get the corresponding EDID property although it is already detected as disconnected.
https://bugs.freedesktop.org/show_bug.cgi?id=26743
--- drivers/gpu/drm/drm_crtc_helper.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_crtc_helper.c +1 -0
@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_moif (connector->status == connector_status_disconnected) {DRM_DEBUG_KMS ("%s is disconnected\n" ,drm_get_connector_name (connector)); +drm_mode_connector_update_edid_property (connector,NULL ); goto prune; }
PATCH 4/197 fat: fix buffer overflow in vfat_create_shortname()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nikolaus Schulz <[email protected]>
commit 30d1872d9eb3663b4cf7bdebcbf5cd465674cced upstream.
When using the string representation of a random counter as part of the base name, ensure that it is no longer than 4 bytes.
Since we are repeatedly decrementing the counter in a loop until we have found a unique base name, the counter may wrap around zero; therefore, it is not enough to mask its higher bits before entering the loop, this must be done inside the loop.
--- fs/fat/namei_vfat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/fat/namei_vfat.c +3 -3
@@ -309,7 +309,7 @@ static int vfat_create_shortname(struct {struct fat_mount_options *opts = &MSDOS_SB (dir->i_sb)->options;wchar_t *ip, *ext_start, *end, *name_start; -unsigned char base[9 ], ext[4 ], buf[8 ], *p; +unsigned char base[9 ], ext[4 ], buf[5 ], *p;unsigned char charbuf[NLS_MAX_CHARSET_SIZE ];int chl, chi;int sz =0 , extlen, baselen, i, numtail_baselen, numtail2_baselen;
@@ -467,7 +467,7 @@ static int vfat_create_shortname(structreturn 0 ; } - i = jiffies &0xffff ; + i = jiffies; sz = (jiffies >>16 ) &0x7 ;if (baselen >2 ) { baselen = numtail2_baselen;
@@ -476,7 +476,7 @@ static int vfat_create_shortname(struct name_res[baselen +4 ] ='~' ; name_res[baselen +5 ] ='1' + sz;while (1 ) { -sprintf (buf,"%04X" , i); +snprintf (buf,sizeof (buf),"%04X" , i &0xffff );memcpy (&name_res[baselen], buf,4 );if (vfat_find_form (dir, name_res) <0 )break ;
PATCH 5/197 oom: fix the unsafe usage of badness() in proc_oom_score()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Oleg Nesterov <[email protected]>
commit b95c35e76b29ba812e5dabdd91592e25ec640e93 upstream.
proc_oom_score(task) has a reference to task_struct, but that is all. If this task was already released before we take tasklist_lock
- we can't use task->group_leader, it points to nowhere
- it is not safe to call badness() even if this task is ->group_leader, has_intersects_mems_allowed() assumes it is safe to iterate over ->thread_group list.
- even worse, badness() can hit ->signal == NULL
Add the pid_alive() check to ensure __unhash_process() was not called.
Also, use "task" instead of task->group_leader. badness() should return the same result for any sub-thread. Currently this is not true, but this should be changed anyway.
--- fs/proc/base.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/proc/base.c +3 -2
@@ -442,12 +442,13 @@ static const struct file_operations procunsigned long badness (struct task_struct *p,unsigned long uptime);static int proc_oom_score (struct task_struct *task,char *buffer) { -unsigned long points; +unsigned long points =0 ;struct timespec uptime;do_posix_clock_monotonic_gettime (&uptime);read_lock (&tasklist_lock); - points =badness (task->group_leader, uptime.tv_sec); +if (pid_alive (task)) + points =badness (task, uptime.tv_sec);read_unlock (&tasklist_lock);return sprintf (buffer,"%lu\n" , points); }
PATCH 6/197 drm/radeon/kms: dont print error on -ERESTARTSYS.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Airlie <[email protected]>
commit 97f23b3d85a4d734a8584dade3a34579931c8f8d upstream.
We can get this if the user moves the mouse when we are waiting to move some stuff around in the validate. Don't fail.
--- drivers/gpu/drm/radeon/radeon_cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_cs.c +2 -1
@@ -247,7 +247,8 @@ int radeon_cs_ioctl(struct drm_device *d } r =radeon_cs_parser_relocs (&parser);if (r) { -DRM_ERROR ("Failed to parse relocation !\n" ); +if (r != -ERESTARTSYS ) +DRM_ERROR ("Failed to parse relocation %d!\n" , r);radeon_cs_parser_fini (&parser, r);mutex_unlock (&rdev->cs_mutex);return r;
PATCH 7/197 drm/radeon/kms: fix pal tv-out support on legacy IGP chips
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 15f7207761cfcf8f53fb6e5cacffe060478782c3 upstream.
Based on ddx patch by Andrzej Hajda.
--- drivers/gpu/drm/radeon/radeon_legacy_tv.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
drivers/gpu/drm/radeon/radeon_legacy_tv.c +24 -5
@@ -57,6 +57,10 @@#define NTSC_TV_PLL_N_14 693#define NTSC_TV_PLL_P_14 7 +#define PAL_TV_PLL_M_14 19 +#define PAL_TV_PLL_N_14 353 +#define PAL_TV_PLL_P_14 5 +#define VERT_LEAD_IN_LINES 2#define FRAC_BITS 0xe#define FRAC_MASK 0x3fff
@@ -205,9 +209,24 @@ static const struct radeon_tv_mode_const 630627, /* defRestart */ 347, /* crtcPLL_N */ 14, /* crtcPLL_M */ - 8, /* crtcPLL_postDiv */ + 8, /* crtcPLL_postDiv */ 1022, /* pixToTV */ }, + {/* PAL timing for 14 Mhz ref clk */ +800 ,/* horResolution */ +600 ,/* verResolution */ +TV_STD_PAL ,/* standard */ +1131 ,/* horTotal */ +742 ,/* verTotal */ +813 ,/* horStart */ +840 ,/* horSyncStart */ +633 ,/* verSyncStart */ +708369 ,/* defRestart */ +211 ,/* crtcPLL_N */ +9 ,/* crtcPLL_M */ +8 ,/* crtcPLL_postDiv */ + 759, /* pixToTV */ + }, };#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
@@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constif (pll->reference_freq ==2700 ) const_ptr = &available_tv_modes[1 ];else - const_ptr = &available_tv_modes[1 ];/* FIX ME */ + const_ptr = &available_tv_modes[3 ]; }return const_ptr; }
@@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct dr n =PAL_TV_PLL_N_27 ; p =PAL_TV_PLL_P_27 ; }else { - m =PAL_TV_PLL_M_27 ; - n =PAL_TV_PLL_N_27 ; - p =PAL_TV_PLL_P_27 ; + m =PAL_TV_PLL_M_14 ; + n =PAL_TV_PLL_N_14 ; + p =PAL_TV_PLL_P_14 ; } }
PATCH 8/197 drm: Return ENODEV if the inode mapping changes
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Chris Wilson <[email protected]>
commit da58405860b992d2bb21ebae5d685fe3204dd3f0 upstream.
Replace a BUG_ON with an error code in the event that the inode mapping changes between calls to drm_open. This may happen for instance if udev is loaded subsequent to the original opening of the device:
[ 644.291870] kernel BUG at drivers/gpu/drm/drm_fops.c:146! [ 644.291876] invalid opcode: 0000 [#1] SMP [ 644.291882] last sysfs file: /sys/kernel/uevent_seqnum [ 644.291888] [ 644.291895] Pid: 7276, comm: lt-cairo-test-s Not tainted 2.6.34-rc1 #2 N150/N210/N220 /N150/N210/N220 [ 644.291903] EIP: 0060:[<c11c70e3>] EFLAGS: 00210283 CPU: 0 [ 644.291912] EIP is at drm_open+0x4b1/0x4e2 [ 644.291918] EAX: f72d8d18 EBX: f790a400 ECX: f73176b8 EDX: 00000000 [ 644.291923] ESI: f790a414 EDI: f790a414 EBP: f647ae20 ESP: f647adfc [ 644.291929] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 644.291937] Process lt-cairo-test-s (pid: 7276, ti=f647a000 task=f73f5c80 task.ti=f647a000) [ 644.291941] Stack: [ 644.291945] 00000000 f7bb7400 00000080 f6451100 f73176b8 f6479214 f6451100 f73176b8 [ 644.291957] <0> c1297ce0 f647ae34 c11c6c04 f73176b8 f7949800 00000000 f647ae54 c1080ac5 [ 644.291969] <0> f7949800 f6451100 00000000 f6451100 f73176b8 f6452780 f647ae70 c107d1e6 [ 644.291982] Call Trace: [ 644.291991] [<c11c6c04>] ? drm_stub_open+0x8a/0xb8 [ 644.292000] [<c1080ac5>] ? chrdev_open+0xef/0x106 [ 644.292008] [<c107d1e6>] ? __dentry_open+0xd4/0x1a6 [ 644.292015] [<c107d35b>] ? nameidata_to_filp+0x31/0x45 [ 644.292022] [<c10809d6>] ? chrdev_open+0x0/0x106 [ 644.292030] [<c10864e2>] ? do_last+0x346/0x423 [ 644.292037] [<c108789f>] ? do_filp_open+0x190/0x415 [ 644.292046] [<c1071eb5>] ? handle_mm_fault+0x214/0x710 [ 644.292053] [<c107d008>] ? do_sys_open+0x4d/0xe9 [ 644.292061] [<c1016462>] ? do_page_fault+0x211/0x23f [ 644.292068] [<c107d0f0>] ? sys_open+0x23/0x2b [ 644.292075] [<c1002650>] ? sysenter_do_call+0x12/0x26 [ 644.292079] Code: 89 f0 89 55 dc e8 8d 96 0a 00 8b 45 e0 8b 55 dc 83 78 04 01 75 28 8b 83 18 02 00 00 85 c0 74 0f 8b 4d ec 3b 81 ac 00 00 00 74 13 <0f> 0b eb fe 8b 4d ec 8b 81 ac 00 00 00 89 83 18 02 00 00 89 f0 [ 644.292143] EIP: [<c11c70e3>] drm_open+0x4b1/0x4e2 SS:ESP 0068:f647adfc [ 644.292175] ---[ end trace 2ddd476af89a60fa ]---
drivers/gpu/drm/drm_fops.c +9 -7
@@ -140,14 +140,16 @@ int drm_open(struct inode *inode, struct file *filp)spin_unlock (&dev->count_lock); } out: -mutex_lock (&dev->struct_mutex); -if (minor->type ==DRM_MINOR_LEGACY ) { -BUG_ON ((dev->dev_mapping !=NULL ) && - (dev->dev_mapping != inode->i_mapping)); -if (dev->dev_mapping ==NULL ) - dev->dev_mapping = inode->i_mapping; +if (!retcode) { +mutex_lock (&dev->struct_mutex); +if (minor->type ==DRM_MINOR_LEGACY ) { +if (dev->dev_mapping ==NULL ) + dev->dev_mapping = inode->i_mapping; +else if (dev->dev_mapping != inode->i_mapping) + retcode = -ENODEV ; + } +mutex_unlock (&dev->struct_mutex); } -mutex_unlock (&dev->struct_mutex);return retcode; }
PATCH 9/197 xfs: simplify inode teardown
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit 848ce8f731aed0a2d4ab5884a4f6664af73d2dd0 upstream
Currently the reclaim code for the case where we don't reclaim the final reclaim is overly complicated. We know that the inode is clean but instead of just directly reclaiming the clean inode we go through the whole process of marking the inode reclaimable just to directly reclaim it from the calling context. Besides being overly complicated this introduces a race where iget could recycle an inode between marked reclaimable and actually being reclaimed leading to panics.
This patch gets rid of the existing reclaim path, and replaces it with a simple call to xfs_ireclaim if the inode was clean. While we're at it we also use the slightly more lax xfs_inode_clean check we'd use later to determine if we need to flush the inode here.
Finally get rid of xfs_reclaim function and place the remaining small bits of reclaim code directly into xfs_fs_destroy_inode.
--- fs/xfs/linux-2.6/xfs_super.c | 34 ++++++++++++++++++++++++++++++---- fs/xfs/linux-2.6/xfs_sync.c | 15 ++++----------- fs/xfs/linux-2.6/xfs_sync.h | 1 - fs/xfs/xfs_vnodeops.c | 40 ---------------------------------------- fs/xfs/xfs_vnodeops.h | 1 - 5 files changed, 34 insertions(+), 57 deletions(-)
fs/xfs/linux-2.6/xfs_super.c +30 -4
@@ -930,13 +930,39 @@ xfs_fs_alloc_inode(*/ STATIC voidxfs_fs_destroy_inode ( -struct inode *inode) +struct inode *inode) { -xfs_inode_t *ip =XFS_I (inode); +struct xfs_inode *ip =XFS_I (inode); + +xfs_itrace_entry (ip);XFS_STATS_INC (vn_reclaim); -if (xfs_reclaim (ip)) -panic ("%s: cannot reclaim 0x%p\n" , __func__, inode); + +/* bad inode, get out here ASAP */ +if (is_bad_inode (inode)) + goto out_reclaim; + +xfs_ioend_wait (ip); + +ASSERT (XFS_FORCED_SHUTDOWN (ip->i_mount) || ip->i_delayed_blks ==0 ); + +/* +* We should never get here with one of the reclaim flags already set. +*/ +ASSERT_ALWAYS (!xfs_iflags_test (ip,XFS_IRECLAIMABLE )); +ASSERT_ALWAYS (!xfs_iflags_test (ip,XFS_IRECLAIM )); + +/* +* If we have nothing to flush with this inode then complete the +* teardown now, otherwise delay the flush operation. +*/ +if (!xfs_inode_clean (ip)) { +xfs_inode_set_reclaim_tag (ip); +return ; + } + +out_reclaim: +xfs_ireclaim (ip); }/*
fs/xfs/linux-2.6/xfs_sync.c +4 -11
@@ -663,10 +663,9 @@ xfs_syncd_stop(kthread_stop (mp->m_sync_task); } -int +STATIC intxfs_reclaim_inode (xfs_inode_t *ip, -int locked,int sync_mode) {xfs_perag_t *pag =xfs_get_perag (ip->i_mount, ip->i_ino);
@@ -682,10 +681,6 @@ xfs_reclaim_inode( !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {spin_unlock (&ip->i_flags_lock);write_unlock (&pag->pag_ici_lock); -if (locked) { -xfs_ifunlock (ip); -xfs_iunlock (ip,XFS_ILOCK_EXCL ); - }return -EAGAIN ; }__xfs_iflags_set (ip,XFS_IRECLAIM );
@@ -704,10 +699,8 @@ xfs_reclaim_inode(* We get the flush lock regardless, though, just to make sure * we don't free it while it is being flushed. */ -if (!locked) { -xfs_ilock (ip,XFS_ILOCK_EXCL ); -xfs_iflock (ip); - } +xfs_ilock (ip,XFS_ILOCK_EXCL ); +xfs_iflock (ip);/* * In the case of a forced shutdown we rely on xfs_iflush() to
@@ -778,7 +771,7 @@ xfs_reclaim_inode_now( }read_unlock (&pag->pag_ici_lock); -return xfs_reclaim_inode (ip,0 , flags); +return xfs_reclaim_inode (ip, flags); }int
fs/xfs/linux-2.6/xfs_sync.h +0 -1
@@ -44,7 +44,6 @@ void xfs_quiesce_attr(struct xfs_mount *void xfs_flush_inodes (struct xfs_inode *ip); -int xfs_reclaim_inode (struct xfs_inode *ip,int locked,int sync_mode);int xfs_reclaim_inodes (struct xfs_mount *mp,int mode);void xfs_inode_set_reclaim_tag (struct xfs_inode *ip);
fs/xfs/xfs_vnodeops.c +0 -40
@@ -2456,46 +2456,6 @@ xfs_set_dmattrs(return error; } -int -xfs_reclaim ( -xfs_inode_t *ip) -{ - -xfs_itrace_entry (ip); - -ASSERT (!VN_MAPPED (VFS_I (ip))); - -/* bad inode, get out here ASAP */ -if (is_bad_inode (VFS_I (ip))) { -xfs_ireclaim (ip); -return 0 ; - } - -xfs_ioend_wait (ip); - -ASSERT (XFS_FORCED_SHUTDOWN (ip->i_mount) || ip->i_delayed_blks ==0 ); - -/* -* If we have nothing to flush with this inode then complete the -* teardown now, otherwise break the link between the xfs inode and the -* linux inode and clean up the xfs inode later. This avoids flushing -* the inode to disk during the delete operation itself. -* -* When breaking the link, we need to set the XFS_IRECLAIMABLE flag -* first to ensure that xfs_iunpin() will never see an xfs inode -* that has a linux inode being reclaimed. Synchronisation is provided -* by the i_flags_lock. -*/ -if (!ip->i_update_core && (ip->i_itemp ==NULL )) { -xfs_ilock (ip,XFS_ILOCK_EXCL ); -xfs_iflock (ip); -xfs_iflags_set (ip,XFS_IRECLAIMABLE ); -return xfs_reclaim_inode (ip,1 ,XFS_IFLUSH_DELWRI_ELSE_SYNC ); - } -xfs_inode_set_reclaim_tag (ip); -return 0 ; -} -/* * xfs_alloc_file_space() * This routine allocates disk space for the given file.
fs/xfs/xfs_vnodeops.h +0 -1
@@ -38,7 +38,6 @@ int xfs_symlink(struct xfs_inode *dp, st const char *target_path, mode_t mode, struct xfs_inode **ipp, cred_t *credp);int xfs_set_dmattrs (struct xfs_inode *ip,u_int evmask,u_int16_t state); -int xfs_reclaim (struct xfs_inode *ip);int xfs_change_file_space (struct xfs_inode *ip,int cmd,xfs_flock64_t *bf,xfs_off_t offset,int attr_flags); int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 10/197 xfs: fix mmap_sem/iolock inversion in xfs_free_eofblocks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit c56c9631cbe88f08854a56ff9776c1f310916830 upstream
When xfs_free_eofblocks is called from ->release the VM might already hold the mmap_sem, but in the write path we take the iolock before taking the mmap_sem in the generic write code.
Switch xfs_free_eofblocks to only trylock the iolock if called from ->release and skip trimming the prellocated blocks in that case. We'll still free them later on the final iput.
--- fs/xfs/xfs_rw.h | 7 ------- fs/xfs/xfs_vnodeops.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-)
fs/xfs/xfs_rw.h +0 -7
@@ -37,13 +37,6 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_ }/* -* Flags for xfs_free_eofblocks -*/ -#define XFS_FREE_EOF_LOCK (1<<0) -#define XFS_FREE_EOF_NOLOCK (1<<1) - - -/* * helper function to extract extent size hint from inode */ STATIC_INLINE xfs_extlen_t
fs/xfs/xfs_vnodeops.c +26 -8
@@ -709,6 +709,11 @@ xfs_fsync( }/* +* Flags for xfs_free_eofblocks +*/ +#define XFS_FREE_EOF_TRYLOCK (1<<0) + +/* * This is called by xfs_inactive to free any blocks beyond eof * when the link count isn't zero and by xfs_dm_punch_hole() when * punching a hole to EOF.
@@ -726,7 +731,6 @@ xfs_free_eofblocks(xfs_filblks_t map_len;int nimaps;xfs_bmbt_irec_t imap; -int use_iolock = (flags &XFS_FREE_EOF_LOCK );/* * Figure out if there are any blocks beyond the end
@@ -768,14 +772,19 @@ xfs_free_eofblocks(* cache and we can't * do that within a transaction. */ -if (use_iolock) +if (flags &XFS_FREE_EOF_TRYLOCK ) { +if (!xfs_ilock_nowait (ip,XFS_IOLOCK_EXCL )) { +xfs_trans_cancel (tp,0 ); +return 0 ; + } + }else {xfs_ilock (ip,XFS_IOLOCK_EXCL ); + } error =xfs_itruncate_start (ip,XFS_ITRUNC_DEFINITE , ip->i_size);if (error) {xfs_trans_cancel (tp,0 ); -if (use_iolock) -xfs_iunlock (ip,XFS_IOLOCK_EXCL ); +xfs_iunlock (ip,XFS_IOLOCK_EXCL );return error; }
@@ -812,8 +821,7 @@ xfs_free_eofblocks( error =xfs_trans_commit (tp,XFS_TRANS_RELEASE_LOG_RES ); } -xfs_iunlock (ip, (use_iolock ? (XFS_IOLOCK_EXCL |XFS_ILOCK_EXCL ) - :XFS_ILOCK_EXCL )); +xfs_iunlock (ip,XFS_IOLOCK_EXCL |XFS_ILOCK_EXCL ); }return error; }
@@ -1113,7 +1121,17 @@ xfs_release( (ip->i_df.if_flags & XFS_IFEXTENTS)) && (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { - error =xfs_free_eofblocks (mp, ip,XFS_FREE_EOF_LOCK ); + +/* +* If we can't get the iolock just skip truncating +* the blocks past EOF because we could deadlock +* with the mmap_sem otherwise. We'll get another +* chance to drop them once the last reference to +* the inode is dropped, so we'll never leak blocks +* permanently. +*/ + error =xfs_free_eofblocks (mp, ip, +XFS_FREE_EOF_TRYLOCK );if (error)return error; }
@@ -1184,7 +1202,7 @@ xfs_inactive( (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || (ip->i_delayed_blks != 0)))) { - error =xfs_free_eofblocks (mp, ip,XFS_FREE_EOF_LOCK ); + error =xfs_free_eofblocks (mp, ip,0 );if (error)return VN_INACTIVE_CACHE ; }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 11/197 xfs: I/O completion handlers must use NOFS allocations
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit 80641dc66a2d6dfb22af4413227a92b8ab84c7bb upstream
When completing I/O requests we must not allow the memory allocator to recurse into the filesystem, as we might deadlock on waiting for the I/O completion otherwise. The only thing currently allocating normal GFP_KERNEL memory is the allocation of the transaction structure for the unwritten extent conversion. Add a memflags argument to _xfs_trans_alloc to allow controlling the allocator behaviour.
--- fs/xfs/xfs_fsops.c | 2 +- fs/xfs/xfs_iomap.c | 9 ++++++++- fs/xfs/xfs_mount.c | 2 +- fs/xfs/xfs_trans.c | 7 ++++--- fs/xfs/xfs_trans.h | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-)
fs/xfs/xfs_fsops.c +1 -1
@@ -611,7 +611,7 @@ xfs_fs_log_dummy(xfs_inode_t *ip;int error; - tp =_xfs_trans_alloc (mp,XFS_TRANS_DUMMY1 ); + tp =_xfs_trans_alloc (mp,XFS_TRANS_DUMMY1 ,KM_SLEEP ); error =xfs_trans_reserve (tp,0 ,XFS_ICHANGE_LOG_RES (mp),0 ,0 ,0 );if (error) {xfs_trans_cancel (tp,0 );
fs/xfs/xfs_iomap.c +8 -1
@@ -860,8 +860,15 @@ xfs_iomap_write_unwritten(* set up a transaction to convert the range of extents * from unwritten to real. Do allocations in a loop until * we have covered the range passed in. +* +* Note that we open code the transaction allocation here +* to pass KM_NOFS--we can't risk to recursing back into +* the filesystem here as we might be asked to write out +* the same inode that we complete here and might deadlock +* on the iolock. */ - tp =xfs_trans_alloc (mp,XFS_TRANS_STRAT_WRITE ); +xfs_wait_for_freeze (mp,SB_FREEZE_TRANS ); + tp =_xfs_trans_alloc (mp,XFS_TRANS_STRAT_WRITE ,KM_NOFS ); tp->t_flags |=XFS_TRANS_RESERVE ; error = xfs_trans_reserve(tp, resblks, XFS_WRITE_LOG_RES(mp), 0,
fs/xfs/xfs_mount.c +1 -1
@@ -1471,7 +1471,7 @@ xfs_log_sbcount(if (!xfs_sb_version_haslazysbcount (&mp->m_sb))return 0 ; - tp =_xfs_trans_alloc (mp,XFS_TRANS_SB_COUNT ); + tp =_xfs_trans_alloc (mp,XFS_TRANS_SB_COUNT ,KM_SLEEP ); error =xfs_trans_reserve (tp,0 , mp->m_sb.sb_sectsize +128 ,0 ,0 ,XFS_DEFAULT_LOG_COUNT );if (error) {
fs/xfs/xfs_trans.c +4 -3
@@ -236,19 +236,20 @@ xfs_trans_alloc( uint type) {xfs_wait_for_freeze (mp,SB_FREEZE_TRANS ); -return _xfs_trans_alloc (mp, type); +return _xfs_trans_alloc (mp, type,KM_SLEEP ); }xfs_trans_t *_xfs_trans_alloc (xfs_mount_t *mp, -uint type) +uint type, +uint memflags) {xfs_trans_t *tp;atomic_inc (&mp->m_active_trans); - tp =kmem_zone_zalloc (xfs_trans_zone,KM_SLEEP ); + tp =kmem_zone_zalloc (xfs_trans_zone, memflags); tp->t_magic =XFS_TRANS_MAGIC ; tp->t_type = type; tp->t_mountp = mp;
fs/xfs/xfs_trans.h +1 -1
@@ -924,7 +924,7 @@ typedef struct xfs_trans {* XFS transaction mechanism exported interfaces. */ xfs_trans_t *xfs_trans_alloc (struct xfs_mount *,uint ); -xfs_trans_t *_xfs_trans_alloc (struct xfs_mount *,uint ); +xfs_trans_t *_xfs_trans_alloc (struct xfs_mount *,uint ,uint );xfs_trans_t *xfs_trans_dup (xfs_trans_t *);int xfs_trans_reserve (xfs_trans_t *,uint ,uint ,uint ,uint ,uint );
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 12/197 xfs: Wrapped journal record corruption on read at recovery
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andy Poling <[email protected]>
commit fc5bc4c85c45f0bf854404e5736aa8b65720a18d upstream
Summary of problem:
If a journal record wraps at the physical end of the journal, it has to be read in two parts in xlog_do_recovery_pass(): a read at the physical end and a read at the physical beginning. If xlog_bread() has to re-align the first read, the second read request does not take that re-alignment into account. If the first read was re-aligned, the second read over-writes the end of the data from the first read, effectively corrupting it. This can happen either when reading the record header or reading the record data.
The first sanity check in xlog_recover_process_data() is to check for a valid clientid, so that is the error reported.
Summary of fix:
If there was a first read at the physical end, XFS_BUF_PTR() returns where the data was requested to begin. Conversely, because it is the result of xlog_align(), offset indicates where the requested data for the first read actually begins - whether or not xlog_bread() has re-aligned it.
Using offset as the base for the calculation of where to place the second read data ensures that it will be correctly placed immediately following the data from the first read instead of sometimes over-writing the end of it.
The attached patch has resolved the reported problem of occasional inability to recover the journal (reporting "bad clientid").
--- fs/xfs/xfs_log_recover.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-)
fs/xfs/xfs_log_recover.c +7 -17
@@ -3517,7 +3517,7 @@ xlog_do_recovery_pass( {xlog_rec_header_t *rhead;xfs_daddr_t blk_no; -xfs_caddr_t bufaddr, offset; +xfs_caddr_t offset;xfs_buf_t *hbp, *dbp;int error =0 , h_size;int bblks, split_bblks;
@@ -3610,7 +3610,7 @@ xlog_do_recovery_pass(/* * Check for header wrapping around physical end-of-log */ - offset =NULL ; + offset =XFS_BUF_PTR (hbp); split_hblks =0 ; wrapped_hblks =0 ;if (blk_no + hblks <= log->l_logBBsize) {
@@ -3646,9 +3646,8 @@ xlog_do_recovery_pass(* - order is important. */ wrapped_hblks = hblks - split_hblks; - bufaddr =XFS_BUF_PTR (hbp); error =XFS_BUF_SET_PTR (hbp, - bufaddr +BBTOB (split_hblks), + offset +BBTOB (split_hblks),BBTOB (hblks - split_hblks));if (error) goto bread_err2;
@@ -3658,14 +3657,10 @@ xlog_do_recovery_pass(if (error) goto bread_err2; - error =XFS_BUF_SET_PTR (hbp, bufaddr, + error =XFS_BUF_SET_PTR (hbp, offset,BBTOB (hblks));if (error) goto bread_err2; - -if (!offset) - offset =xlog_align (log,0 , - wrapped_hblks, hbp); } rhead = (xlog_rec_header_t *)offset; error = xlog_valid_rec_header(log, rhead,
@@ -3685,7 +3680,7 @@ xlog_do_recovery_pass( }else {/* This log record is split across the * physical end of log */ - offset =NULL ; + offset =XFS_BUF_PTR (dbp); split_bblks =0 ;if (blk_no != log->l_logBBsize) {/* some data is before the physical
@@ -3714,9 +3709,8 @@ xlog_do_recovery_pass(* _first_, then the log start (LR header end) * - order is important. */ - bufaddr =XFS_BUF_PTR (dbp); error =XFS_BUF_SET_PTR (dbp, - bufaddr +BBTOB (split_bblks), + offset +BBTOB (split_bblks),BBTOB (bblks - split_bblks));if (error) goto bread_err2;
@@ -3727,13 +3721,9 @@ xlog_do_recovery_pass(if (error) goto bread_err2; - error =XFS_BUF_SET_PTR (dbp, bufaddr, h_size); + error =XFS_BUF_SET_PTR (dbp, offset, h_size);if (error) goto bread_err2; - -if (!offset) - offset =xlog_align (log, wrapped_hblks, - bblks - split_bblks, dbp); }xlog_unpack_data (rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 13/197 xfs: Fix error return for fallocate() on XFS
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jason Gunthorpe <[email protected]>
commit 44a743f68705c681439f264deb05f8f38e9048d3 upstream
Noticed that through glibc fallocate would return 28 rather than -1 and errno = 28 for ENOSPC. The xfs routines uses XFS_ERROR format positive return error codes while the syscalls use negative return codes. Fixup the two cases in xfs_vn_fallocate syscall to convert to negative.
--- fs/xfs/linux-2.6/xfs_iops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/xfs/linux-2.6/xfs_iops.c +3 -3
@@ -573,8 +573,8 @@ xfs_vn_fallocate( bf.l_len = len;xfs_ilock (ip,XFS_IOLOCK_EXCL ); - error =xfs_change_file_space (ip,XFS_IOC_RESVSP , &bf, -0 ,XFS_ATTR_NOLOCK ); + error = -xfs_change_file_space (ip,XFS_IOC_RESVSP , &bf, +0 ,XFS_ATTR_NOLOCK );if (!error && !(mode &FALLOC_FL_KEEP_SIZE ) && offset + len >i_size_read (inode)) new_size = offset + len;
@@ -585,7 +585,7 @@ xfs_vn_fallocate( iattr.ia_valid =ATTR_SIZE ; iattr.ia_size = new_size; - error =xfs_setattr (ip, &iattr,XFS_ATTR_NOLOCK ); + error = -xfs_setattr (ip, &iattr,XFS_ATTR_NOLOCK ); }xfs_iunlock (ip,XFS_IOLOCK_EXCL );
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 14/197 xfs: check for not fully initialized inodes in xfs_ireclaim
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit b44b1126279b60597f96bbe77507b1650f88a969 upstream
Add an assert for inodes not added to the inode cache in xfs_ireclaim, to make sure we're not going to introduce something like the famous nfsd inode cache bug again.
--- fs/xfs/xfs_iget.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
fs/xfs/xfs_iget.c +8 -4
@@ -511,17 +511,21 @@ xfs_ireclaim( {struct xfs_mount *mp = ip->i_mount;struct xfs_perag *pag; +xfs_agino_t agino =XFS_INO_TO_AGINO (mp, ip->i_ino);XFS_STATS_INC (xs_ig_reclaims);/* -* Remove the inode from the per-AG radix tree. It doesn't matter -* if it was never added to it because radix_tree_delete can deal -* with that case just fine. +* Remove the inode from the per-AG radix tree. +* +* Because radix_tree_delete won't complain even if the item was never +* added to the tree assert that it's been there before to catch +* problems with the inode life time early on. */ pag =xfs_get_perag (mp, ip->i_ino);write_lock (&pag->pag_ici_lock); -radix_tree_delete (&pag->pag_ici_root,XFS_INO_TO_AGINO (mp, ip->i_ino)); +if (!radix_tree_delete (&pag->pag_ici_root, agino)) +ASSERT (0 );write_unlock (&pag->pag_ici_lock);xfs_put_perag (mp, pag);
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 15/197 xfs: fix timestamp handling in xfs_setattr
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit d6d59bada372bcf8bd36c3bbc71c485c29dd2a4b upstream
We currently have some rather odd code in xfs_setattr for updating the a/c/mtime timestamps:
- first we do a non-transaction update if all three are updated together
- second we implicitly update the ctime for various changes instead of relying on the ATTR_CTIME flag
- third we set the timestamps to the current time instead of the arguments in the iattr structure in many cases.
This patch makes sure we update it in a consistent way:
- always transactional
- ctime is only updated if ATTR_CTIME is set or we do a size update, which is a special case
- always to the times passed in from the caller instead of the current time
The only non-size caller of xfs_setattr that doesn't come from the VFS is updated to set ATTR_CTIME and pass in a valid ctime value.
--- fs/xfs/linux-2.6/xfs_acl.c | 3 - fs/xfs/xfs_vnodeops.c | 93 ++++++++++++++++++--------------------------- 2 files changed, 41 insertions(+), 55 deletions(-)
fs/xfs/linux-2.6/xfs_acl.c +2 -1
@@ -250,8 +250,9 @@ xfs_set_mode(struct inode *inode, mode_tif (mode != inode->i_mode) {struct iattr iattr; - iattr.ia_valid =ATTR_MODE ; + iattr.ia_valid =ATTR_MODE |ATTR_CTIME ; iattr.ia_mode = mode; + iattr.ia_ctime =current_fs_time (inode->i_sb); error = -xfs_setattr (XFS_I (inode), &iattr,XFS_ATTR_NOACL ); }
fs/xfs/xfs_vnodeops.c +39 -54
149 lines not on this page · raw message
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 16/197 xfs: Dont flush stale inodes
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit 44e08c45cc14e6190a424be8d450070c8e508fad upstream
Because inodes remain in cache much longer than inode buffers do under memory pressure, we can get the situation where we have stale, dirty inodes being reclaimed but the backing storage has been freed. Hence we should never, ever flush XFS_ISTALE inodes to disk as there is no guarantee that the backing buffer is in cache and still marked stale when the flush occurs.
--- fs/xfs/xfs_inode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/xfs/xfs_inode.c +7 -3
@@ -2877,10 +2877,14 @@ xfs_iflush( mp = ip->i_mount;/* -* If the inode isn't dirty, then just release the inode -* flush lock and do nothing. +* If the inode isn't dirty, then just release the inode flush lock and +* do nothing. Treat stale inodes the same; we cannot rely on the +* backing buffer remaining stale in cache for the remaining life of +* the stale inode and so xfs_itobp() below may give us a buffer that +* no longer contains inodes below. Doing this stale check here also +* avoids forcing the log on pinned, stale inodes. */ -if (xfs_inode_clean (ip)) { +if (xfs_inode_clean (ip) ||xfs_iflags_test (ip,XFS_ISTALE )) {xfs_ifunlock (ip);return 0 ; }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 17/197 xfs: Ensure we force all busy extents in range to disk
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit fd45e4784164d1017521086524e3442318c67370 upstream
When we search for and find a busy extent during allocation we force the log out to ensure the extent free transaction is on disk before the allocation transaction. The current implementation has a subtle bug in it--it does not handle multiple overlapping ranges.
That is, if we free lots of little extents into a single contiguous extent, then allocate the contiguous extent, the busy search code stops searching at the first extent it finds that overlaps the allocated range. It then uses the commit LSN of the transaction to force the log out to.
Unfortunately, the other busy ranges might have more recent commit LSNs than the first busy extent that is found, and this results in xfs_alloc_search_busy() returning before all the extent free transactions are on disk for the range being allocated. This can lead to potential metadata corruption or stale data exposure after a crash because log replay won't replay all the extent free transactions that cover the allocation range.
(Dropped the "found" argument from the xfs_alloc_busysearch trace event.)
--- fs/xfs/xfs_alloc.c | 52 +++++++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 31 deletions(-)
fs/xfs/xfs_alloc.c +21 -31
@@ -2703,45 +2703,35 @@ xfs_alloc_search_busy(xfs_trans_t *tp,xfs_mount_t *mp;xfs_perag_busy_t *bsy;xfs_agblock_t uend, bend; -xfs_lsn_t lsn; +xfs_lsn_t lsn =0 ;int cnt; mp = tp->t_mountp;spin_lock (&mp->m_perag[agno].pagb_lock); - cnt = mp->m_perag[agno].pagb_count; - uend = bno + len -1 ; -/* search pagb_list for this slot, skipping open slots */ -for (bsy = mp->m_perag[agno].pagb_list; cnt; bsy++) { - -/* -* (start1,length1) within (start2, length2) -*/ -if (bsy->busy_tp !=NULL ) { - bend = bsy->busy_start + bsy->busy_length -1 ; -if ((bno > bend) || (uend < bsy->busy_start)) { - cnt--; - }else { -TRACE_BUSYSEARCH ("xfs_alloc_search_busy" , -"found1" , agno, bno, len, tp); -break ; - } - } - } -/* -* If a block was found, force the log through the LSN of the -* transaction that freed the block +* search pagb_list for this slot, skipping open slots. We have to +* search the entire array as there may be multiple overlaps and +* we have to get the most recent LSN for the log force to push out +* all the transactions that span the range. */ -if (cnt) { -TRACE_BUSYSEARCH ("xfs_alloc_search_busy" ,"found" , agno, bno, len, tp); - lsn = bsy->busy_tp->t_commit_lsn; -spin_unlock (&mp->m_perag[agno].pagb_lock); -xfs_log_force (mp, lsn,XFS_LOG_FORCE |XFS_LOG_SYNC ); - }else { -TRACE_BUSYSEARCH ("xfs_alloc_search_busy" ,"not-found" , agno, bno, len, tp); -spin_unlock (&mp->m_perag[agno].pagb_lock); +for (cnt =0 ; cnt < mp->m_perag[agno].pagb_count; cnt++) { + bsy = &mp->m_perag[agno].pagb_list[cnt]; +if (!bsy->busy_tp) +continue ; + bend = bsy->busy_start + bsy->busy_length -1 ; +if (bno > bend || uend < bsy->busy_start) +continue ; + +/* (start1,length1) within (start2, length2) */ +if (XFS_LSN_CMP (bsy->busy_tp->t_commit_lsn, lsn) >0 ) + lsn = bsy->busy_tp->t_commit_lsn; } +spin_unlock (&mp->m_perag[agno].pagb_lock); +TRACE_BUSYSEARCH ("xfs_alloc_search_busy" , lsn ?"found" :"not-found" , + agno, bno, len, tp); +if (lsn) +xfs_log_force (mp, lsn,XFS_LOG_FORCE |XFS_LOG_SYNC ); }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 18/197 xfs: reclaim inodes under a write lock
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit c8e20be020f234c8d492927a424a7d8bbefd5b5d upstream
Make the inode tree reclaim walk exclusive to avoid races with concurrent sync walkers and lookups. This is a version of a patch posted by Christoph Hellwig that avoids all the code duplication.
--- fs/xfs/linux-2.6/xfs_sync.c | 154 ++++++++++++++++++----------------------- fs/xfs/linux-2.6/xfs_sync.h | 2 fs/xfs/quota/xfs_qm_syscalls.c | 2 3 files changed, 71 insertions(+), 87 deletions(-)
fs/xfs/linux-2.6/xfs_sync.c +69 -85
@@ -64,7 +64,6 @@ xfs_inode_ag_lookup(* as the tree is sparse and a gang lookup walks to find * the number of objects requested. */ -read_lock (&pag->pag_ici_lock);if (tag ==XFS_ICI_NO_TAG ) { nr_found =radix_tree_gang_lookup (&pag->pag_ici_root, (void **)&ip, *first_index,1 );
@@ -73,7 +72,7 @@ xfs_inode_ag_lookup( (void **)&ip, *first_index, 1, tag); }if (!nr_found) - goto unlock; +return NULL ;/* * Update the index for the next lookup. Catch overflows
@@ -83,13 +82,8 @@ xfs_inode_ag_lookup(*/ *first_index =XFS_INO_TO_AGINO (mp, ip->i_ino +1 );if (*first_index <XFS_INO_TO_AGINO (mp, ip->i_ino)) - goto unlock; - +return NULL ;return ip; - -unlock: -read_unlock (&pag->pag_ici_lock); -return NULL ; }STATIC int
@@ -99,7 +93,8 @@ xfs_inode_ag_walk(int (*execute)(struct xfs_inode *ip,struct xfs_perag *pag,int flags), int flags, - int tag) + int tag, + int exclusive) { struct xfs_perag *pag = &mp->m_perag[ag];uint32_t first_index;
@@ -113,10 +108,20 @@ restart:int error =0 ;xfs_inode_t *ip; +if (exclusive) +write_lock (&pag->pag_ici_lock); +else +read_lock (&pag->pag_ici_lock); ip =xfs_inode_ag_lookup (mp, pag, &first_index, tag); -if (!ip) +if (!ip) { +if (exclusive) +write_unlock (&pag->pag_ici_lock); +else +read_unlock (&pag->pag_ici_lock);break ; + } +/* execute releases pag->pag_ici_lock */ error =execute (ip, pag, flags);if (error ==EAGAIN ) { skipped++;
@@ -124,9 +129,8 @@ restart: }if (error) last_error = error; -/* -* bail out if the filesystem is corrupted. -*/ + +/* bail out if the filesystem is corrupted. */ if (error ==EFSCORRUPTED )break ;
@@ -147,7 +151,8 @@ xfs_inode_ag_iterator(int (*execute)(struct xfs_inode *ip,struct xfs_perag *pag,int flags), int flags, - int tag) + int tag, + int exclusive) { int error = 0;int last_error =0 ;
@@ -156,7 +161,8 @@ xfs_inode_ag_iterator(for (ag =0 ; ag < mp->m_sb.sb_agcount; ag++) {if (!mp->m_perag[ag].pag_ici_init)continue ; - error =xfs_inode_ag_walk (mp, ag, execute, flags, tag); + error =xfs_inode_ag_walk (mp, ag, execute, flags, tag, + exclusive);if (error) { last_error = error;if (error ==EFSCORRUPTED )
@@ -180,11 +186,7 @@ xfs_sync_inode_valid(return EFSCORRUPTED ; } -/* -* If we can't get a reference on the inode, it must be in reclaim. -* Leave it for the reclaim code to flush. Also avoid inodes that -* haven't been fully initialised. -*/ +/* If we can't get a reference on the inode, it must be in reclaim. */ if (!igrab (inode)) {read_unlock (&pag->pag_ici_lock);return ENOENT ;
@@ -281,7 +283,7 @@ xfs_sync_data(ASSERT ((flags & ~(SYNC_TRYLOCK |SYNC_WAIT )) ==0 ); error =xfs_inode_ag_iterator (mp, xfs_sync_inode_data, flags, -XFS_ICI_NO_TAG ); +XFS_ICI_NO_TAG ,0 );if (error)return XFS_ERROR (error);
@@ -303,7 +305,7 @@ xfs_sync_attr(ASSERT ((flags & ~SYNC_WAIT ) ==0 );return xfs_inode_ag_iterator (mp, xfs_sync_inode_attr, flags, -XFS_ICI_NO_TAG ); +XFS_ICI_NO_TAG ,0 ); }STATIC int
@@ -663,60 +665,6 @@ xfs_syncd_stop(kthread_stop (mp->m_sync_task); } -STATIC int -xfs_reclaim_inode ( -xfs_inode_t *ip, -int sync_mode) -{ -xfs_perag_t *pag =xfs_get_perag (ip->i_mount, ip->i_ino); - -/* The hash lock here protects a thread in xfs_iget_core from -* racing with us on linking the inode back with a vnode. -* Once we have the XFS_IRECLAIM flag set it will not touch -* us. -*/ -write_lock (&pag->pag_ici_lock); -spin_lock (&ip->i_flags_lock); -if (__xfs_iflags_test (ip,XFS_IRECLAIM ) || - !__xfs_iflags_test (ip,XFS_IRECLAIMABLE )) { -spin_unlock (&ip->i_flags_lock); -write_unlock (&pag->pag_ici_lock); -return -EAGAIN ; - } -__xfs_iflags_set (ip,XFS_IRECLAIM ); -spin_unlock (&ip->i_flags_lock); -write_unlock (&pag->pag_ici_lock); -xfs_put_perag (ip->i_mount, pag); - -/* -* If the inode is still dirty, then flush it out. If the inode -* is not in the AIL, then it will be OK to flush it delwri as -* long as xfs_iflush() does not keep any references to the inode. -* We leave that decision up to xfs_iflush() since it has the -* knowledge of whether it's OK to simply do a delwri flush of -* the inode or whether we need to wait until the inode is -* pulled from the AIL. -* We get the flush lock regardless, though, just to make sure -* we don't free it while it is being flushed. -*/ -xfs_ilock (ip,XFS_ILOCK_EXCL ); -xfs_iflock (ip); - -/* -* In the case of a forced shutdown we rely on xfs_iflush() to -* wait for the inode to be unpinned before returning an error. -*/ -if (!is_bad_inode (VFS_I (ip)) &&xfs_iflush (ip, sync_mode) ==0 ) { -/* synchronize with xfs_iflush_done */ -xfs_iflock (ip); -xfs_ifunlock (ip); - } - -xfs_iunlock (ip,XFS_ILOCK_EXCL ); -xfs_ireclaim (ip); -return 0 ; -} - void __xfs_inode_set_reclaim_tag( struct xfs_perag *pag,
@@ -759,19 +707,55 @@ __xfs_inode_clear_reclaim_tag( } STATIC int -xfs_reclaim_inode_now ( +xfs_reclaim_inode (struct xfs_inode *ip,struct xfs_perag *pag, -int flags) +int sync_mode) { -/* ignore if already under reclaim */ -if (xfs_iflags_test (ip,XFS_IRECLAIM )) { -read_unlock (&pag->pag_ici_lock); +/* +* The radix tree lock here protects a thread in xfs_iget from racing +* with us starting reclaim on the inode. Once we have the +* XFS_IRECLAIM flag set it will not touch us. +*/ +spin_lock (&ip->i_flags_lock); +ASSERT_ALWAYS (__xfs_iflags_test (ip,XFS_IRECLAIMABLE )); +if (__xfs_iflags_test (ip,XFS_IRECLAIM )) { +/* ignore as it is already under reclaim */ +spin_unlock (&ip->i_flags_lock); +write_unlock (&pag->pag_ici_lock);return 0 ; } -read_unlock (&pag->pag_ici_lock); +__xfs_iflags_set (ip,XFS_IRECLAIM ); +spin_unlock (&ip->i_flags_lock); +write_unlock (&pag->pag_ici_lock); -return xfs_reclaim_inode (ip, flags); +/* +* If the inode is still dirty, then flush it out. If the inode +* is not in the AIL, then it will be OK to flush it delwri as +* long as xfs_iflush() does not keep any references to the inode. +* We leave that decision up to xfs_iflush() since it has the +* knowledge of whether it's OK to simply do a delwri flush of +* the inode or whether we need to wait until the inode is +* pulled from the AIL. +* We get the flush lock regardless, though, just to make sure +* we don't free it while it is being flushed. +*/ +xfs_ilock (ip,XFS_ILOCK_EXCL ); +xfs_iflock (ip); + +/* +* In the case of a forced shutdown we rely on xfs_iflush() to +* wait for the inode to be unpinned before returning an error. +*/ +if (!is_bad_inode (VFS_I (ip)) &&xfs_iflush (ip, sync_mode) ==0 ) { +/* synchronize with xfs_iflush_done */ +xfs_iflock (ip); +xfs_ifunlock (ip); + } + +xfs_iunlock (ip,XFS_ILOCK_EXCL ); +xfs_ireclaim (ip); +return 0 ; }int
@@ -779,6 +763,6 @@ xfs_reclaim_inodes( xfs_mount_t *mp, int mode) { -return xfs_inode_ag_iterator (mp, xfs_reclaim_inode_now, mode, -XFS_ICI_RECLAIM_TAG ); +return xfs_inode_ag_iterator (mp, xfs_reclaim_inode, mode, +XFS_ICI_RECLAIM_TAG ,1 ); }
fs/xfs/linux-2.6/xfs_sync.h +1 -1
@@ -54,6 +54,6 @@ void __xfs_inode_clear_reclaim_tag(strucint xfs_sync_inode_valid (struct xfs_inode *ip,struct xfs_perag *pag);int xfs_inode_ag_iterator (struct xfs_mount *mp,int (*execute)(struct xfs_inode *ip,struct xfs_perag *pag,int flags), -int flags,int tag); +int flags,int tag,int write_lock);#endif
fs/xfs/quota/xfs_qm_syscalls.c +1 -1
@@ -893,7 +893,7 @@ xfs_qm_dqrele_all_inodes( uint flags) {ASSERT (mp->m_quotainfo); -xfs_inode_ag_iterator (mp, xfs_dqrele_inode, flags,XFS_ICI_NO_TAG ); +xfs_inode_ag_iterator (mp, xfs_dqrele_inode, flags,XFS_ICI_NO_TAG ,0 ); }/*------------------------------------------------------------------------*/
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 19/197 xfs: Avoid inodes in reclaim when flushing from inode cache
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit 018027be90a6946e8cf3f9b17b5582384f7ed117 upstream
The reclaim code will handle flushing of dirty inodes before reclaim occurs, so avoid them when determining whether an inode is a candidate for flushing to disk when walking the radix trees. This is based on a test patch from Christoph Hellwig.
--- fs/xfs/linux-2.6/xfs_sync.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
fs/xfs/linux-2.6/xfs_sync.c +18 -13
@@ -179,26 +179,31 @@ xfs_sync_inode_valid( struct xfs_perag *pag) {struct inode *inode =VFS_I (ip); +int error =EFSCORRUPTED ;/* nothing to sync during shutdown */ -if (XFS_FORCED_SHUTDOWN (ip->i_mount)) { -read_unlock (&pag->pag_ici_lock); -return EFSCORRUPTED ; - } +if (XFS_FORCED_SHUTDOWN (ip->i_mount)) + goto out_unlock; -/* If we can't get a reference on the inode, it must be in reclaim. */ -if (!igrab (inode)) { -read_unlock (&pag->pag_ici_lock); -return ENOENT ; - } -read_unlock (&pag->pag_ici_lock); +/* avoid new or reclaimable inodes. Leave for reclaim code to flush */ + error =ENOENT ; +if (xfs_iflags_test (ip,XFS_INEW |XFS_IRECLAIMABLE |XFS_IRECLAIM )) + goto out_unlock; -if (is_bad_inode (inode) ||xfs_iflags_test (ip,XFS_INEW )) { +/* If we can't grab the inode, it must on it's way to reclaim. */ +if (!igrab (inode)) + goto out_unlock; + +if (is_bad_inode (inode)) {IRELE (ip); -return ENOENT ; + goto out_unlock; } -return 0 ; +/* inode is valid */ + error =0 ; +out_unlock: +read_unlock (&pag->pag_ici_lock); +return error; }STATIC int
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 20/197 xfs: reclaim all inodes by background tree walks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit 57817c68229984818fea9e614d6f95249c3fb098 upstream
We cannot do direct inode reclaim without taking the flush lock to ensure that we do not reclaim an inode under IO. We check the inode is clean before doing direct reclaim, but this is not good enough because the inode flush code marks the inode clean once it has copied the in-core dirty state to the backing buffer.
It is the flush lock that determines whether the inode is still under IO, even though it is marked clean, and the inode is still required at IO completion so we can't reclaim it even though it is clean in core. Hence the requirement that we need to take the flush lock even on clean inodes because this guarantees that the inode writeback IO has completed and it is safe to reclaim the inode.
With delayed write inode flushing, we could end up waiting a long time on the flush lock even for a clean inode. The background reclaim already handles this efficiently, so avoid all the problems by killing the direct reclaim path altogether.
--- fs/xfs/linux-2.6/xfs_super.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
fs/xfs/linux-2.6/xfs_super.c +6 -8
@@ -953,16 +953,14 @@ xfs_fs_destroy_inode(ASSERT_ALWAYS (!xfs_iflags_test (ip,XFS_IRECLAIM ));/* -* If we have nothing to flush with this inode then complete the -* teardown now, otherwise delay the flush operation. +* We always use background reclaim here because even if the +* inode is clean, it still may be under IO and hence we have +* to take the flush lock. The background reclaim path handles +* this more efficiently than we can here, so simply let background +* reclaim tear down all inodes. */ -if (!xfs_inode_clean (ip)) { -xfs_inode_set_reclaim_tag (ip); -return ; - } - out_reclaim: -xfs_ireclaim (ip); +xfs_inode_set_reclaim_tag (ip); }/*
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 21/197 xfs: fix stale inode flush avoidance
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit 4b6a46882cca8349e8942e2650c33b11bc571c92 upstream
When reclaiming stale inodes, we need to guarantee that inodes are unpinned before returning with a "clean" status. If we don't we can reclaim inodes that are pinned, leading to use after free in the transaction subsystem as transactions complete.
--- fs/xfs/xfs_inode.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
fs/xfs/xfs_inode.c +15 -6
@@ -2878,13 +2878,9 @@ xfs_iflush(/* * If the inode isn't dirty, then just release the inode flush lock and -* do nothing. Treat stale inodes the same; we cannot rely on the -* backing buffer remaining stale in cache for the remaining life of -* the stale inode and so xfs_itobp() below may give us a buffer that -* no longer contains inodes below. Doing this stale check here also -* avoids forcing the log on pinned, stale inodes. +* do nothing. */ -if (xfs_inode_clean (ip) ||xfs_iflags_test (ip,XFS_ISTALE )) { +if (xfs_inode_clean (ip)) {xfs_ifunlock (ip);return 0 ; }
@@ -2908,6 +2904,19 @@ xfs_iflush(xfs_iunpin_wait (ip);/* +* For stale inodes we cannot rely on the backing buffer remaining +* stale in cache for the remaining life of the stale inode and so +* xfs_itobp() below may give us a buffer that no longer contains +* inodes below. We have to check this after ensuring the inode is +* unpinned so that it is safe to reclaim the stale inode after the +* flush call. +*/ +if (xfs_iflags_test (ip,XFS_ISTALE )) { +xfs_ifunlock (ip); +return 0 ; + } + +/* * This may have been unpinned because the filesystem is shutting * down forcibly. If that's the case we must not write this inode * to disk, because the log record didn't make it to disk!
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 22/197 xfs: xfs_swap_extents needs to handle dynamic fork offsets
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit e09f98606dcc156de1146c209d45a0d6d5f51c3f upstream
When swapping extents, we can corrupt inodes by swapping data forks that are in incompatible formats. This is caused by the two indoes having different fork offsets due to the presence of an attribute fork on an attr2 filesystem. xfs_fsr tries to be smart about setting the fork offset, but the trick it plays only works on attr1 (old fixed format attribute fork) filesystems.
Changing the way xfs_fsr sets up the attribute fork will prevent this situation from ever occurring, so in the kernel code we can get by with a preventative fix - check that the data fork in the defragmented inode is in a format valid for the inode it is being swapped into. This will lead to files that will silently and potentially repeatedly fail defragmentation, so issue a warning to the log when this particular failure occurs to let us know that xfs_fsr needs updating/fixing.
To help identify how to improve xfs_fsr to avoid this issue, add trace points for the inodes being swapped so that we can determine why the swap was rejected and to confirm that the code is making the right decisions and modifications when swapping forks.
A further complication is even when the swap is allowed to proceed when the fork offset is different between the two inodes then value for the maximum number of extents the data fork can hold can be wrong. Make sure these are also set correctly after the swap occurs.
--- fs/xfs/xfs_dfrag.c | 106 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 16 deletions(-)
fs/xfs/xfs_dfrag.c +90 -16
@@ -113,10 +113,82 @@ xfs_swapext(return error; } +/* +* We need to check that the format of the data fork in the temporary inode is +* valid for the target inode before doing the swap. This is not a problem with +* attr1 because of the fixed fork offset, but attr2 has a dynamically sized +* data fork depending on the space the attribute fork is taking so we can get +* invalid formats on the target inode. +* +* E.g. target has space for 7 extents in extent format, temp inode only has +* space for 6. If we defragment down to 7 extents, then the tmp format is a +* btree, but when swapped it needs to be in extent format. Hence we can't just +* blindly swap data forks on attr2 filesystems. +* +* Note that we check the swap in both directions so that we don't end up with +* a corrupt temporary inode, either. +* +* Note that fixing the way xfs_fsr sets up the attribute fork in the source +* inode will prevent this situation from occurring, so all we do here is +* reject and log the attempt. basically we are putting the responsibility on +* userspace to get this right. +*/ +static int +xfs_swap_extents_check_format ( +xfs_inode_t *ip,/* target inode */ +xfs_inode_t *tip)/* tmp inode */ +{ + +/* Should never get a local format */ +if (ip->i_d.di_format ==XFS_DINODE_FMT_LOCAL || + tip->i_d.di_format ==XFS_DINODE_FMT_LOCAL ) +return EINVAL ; + +/* +* if the target inode has less extents that then temporary inode then +* why did userspace call us? +*/ +if (ip->i_d.di_nextents < tip->i_d.di_nextents) +return EINVAL ; + +/* +* if the target inode is in extent form and the temp inode is in btree +* form then we will end up with the target inode in the wrong format +* as we already know there are less extents in the temp inode. +*/ +if (ip->i_d.di_format ==XFS_DINODE_FMT_EXTENTS && + tip->i_d.di_format ==XFS_DINODE_FMT_BTREE ) +return EINVAL ; + +/* Check temp in extent form to max in target */ +if (tip->i_d.di_format ==XFS_DINODE_FMT_EXTENTS && +XFS_IFORK_NEXTENTS (tip,XFS_DATA_FORK ) > ip->i_df.if_ext_max) +return EINVAL ; + +/* Check target in extent form to max in temp */ +if (ip->i_d.di_format ==XFS_DINODE_FMT_EXTENTS && +XFS_IFORK_NEXTENTS (ip,XFS_DATA_FORK ) > tip->i_df.if_ext_max) +return EINVAL ; + +/* Check root block of temp in btree form to max in target */ +if (tip->i_d.di_format ==XFS_DINODE_FMT_BTREE && +XFS_IFORK_BOFF (ip) && + tip->i_df.if_broot_bytes >XFS_IFORK_BOFF (ip)) +return EINVAL ; + +/* Check root block of target in btree form to max in temp */ +if (ip->i_d.di_format ==XFS_DINODE_FMT_BTREE && +XFS_IFORK_BOFF (tip) && + ip->i_df.if_broot_bytes >XFS_IFORK_BOFF (tip)) +return EINVAL ; + +return 0 ; +} +int xfs_swap_extents ( -xfs_inode_t *ip, -xfs_inode_t *tip, +xfs_inode_t *ip,/* target inode */ +xfs_inode_t *tip,/* tmp inode */ xfs_swapext_t *sxp) {xfs_mount_t *mp;
@@ -160,13 +232,6 @@ xfs_swap_extents( goto out_unlock; } -/* Should never get a local format */ -if (ip->i_d.di_format ==XFS_DINODE_FMT_LOCAL || - tip->i_d.di_format ==XFS_DINODE_FMT_LOCAL ) { - error =XFS_ERROR (EINVAL ); - goto out_unlock; - } -if (VN_CACHED (VFS_I (tip)) !=0 ) {xfs_inval_cached_trace (tip,0 ,-1 ,0 ,-1 ); error = xfs_flushinval_pages(tip, 0, -1,
@@ -189,13 +254,12 @@ xfs_swap_extents( goto out_unlock; } -/* -* If the target has extended attributes, the tmp file -* must also in order to ensure the correct data fork -* format. -*/ -if (XFS_IFORK_Q (ip) !=XFS_IFORK_Q (tip) ) { - error =XFS_ERROR (EINVAL ); +/* check inode formats now that data is flushed */ + error =xfs_swap_extents_check_format (ip, tip); +if (error) { +xfs_fs_cmn_err (CE_NOTE , mp, +"%s: inode 0x%llx format is incompatible for exchanging." , + __FILE__, ip->i_ino); goto out_unlock; }
@@ -276,6 +340,16 @@ xfs_swap_extents( *tifp = *tempifp;/* struct copy */ /* +* Fix the in-memory data fork values that are dependent on the fork +* offset in the inode. We can't assume they remain the same as attr2 +* has dynamic fork offsets. +*/ + ifp->if_ext_max =XFS_IFORK_SIZE (ip,XFS_DATA_FORK ) / + (uint )sizeof (xfs_bmbt_rec_t); + tifp->if_ext_max =XFS_IFORK_SIZE (tip,XFS_DATA_FORK ) / + (uint )sizeof (xfs_bmbt_rec_t); + +/* * Fix the on-disk inode values */ tmp = (__uint64_t )ip->i_d.di_nblocks;
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 23/197 xfs: quota limit statvfs available blocks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit 9b00f30762fe9f914eb6e03057a616ed63a4e8ca upstream
A "df" run on an NFS client of an exported XFS file system reports the wrong information for "available" blocks. When a block quota is enforced, the amount reported as free is limited by the quota, but the amount reported available is not (and should be).
--- fs/xfs/quota/xfs_qm_bhv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/quota/xfs_qm_bhv.c +1 -1
@@ -59,7 +59,7 @@ xfs_fill_statvfs_from_dquot(be64_to_cpu (dp->d_blk_hardlimit);if (limit && statp->f_blocks > limit) { statp->f_blocks = limit; - statp->f_bfree = + statp->f_bfree = statp->f_bavail = (statp->f_blocks >be64_to_cpu (dp->d_bcount)) ? (statp->f_blocks -be64_to_cpu (dp->d_bcount)) :0 ; }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 24/197 xfs: dont hold onto reserved blocks on remount, ro
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit cbe132a8bdcff0f9afd9060948fb50597c7400b8 upstream
If we hold onto reserved blocks when doing a remount,ro we end up writing the blocks used count to disk that includes the reserved blocks. Reserved blocks are not actually used, so this results in the values in the superblock being incorrect.
Hence if we run xfs_check or xfs_repair -n while the filesystem is mounted remount,ro we end up with an inconsistent filesystem being reported. Also, running xfs_copy on the remount,ro filesystem will result in an inconsistent image being generated.
To fix this, unreserve the blocks when doing the remount,ro, and reserved them again on remount,rw. This way a remount,ro filesystem will appear consistent on disk to all utilities.
--- fs/xfs/linux-2.6/xfs_super.c | 28 ++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 1 + 2 files changed, 29 insertions(+)
fs/xfs/linux-2.6/xfs_super.c +28 -0
@@ -1323,6 +1323,8 @@ xfs_fs_remount(/* ro -> rw */ if ((mp->m_flags &XFS_MOUNT_RDONLY ) && !(*flags &MS_RDONLY )) { +__uint64_t resblks; + mp->m_flags &= ~XFS_MOUNT_RDONLY ;if (mp->m_flags &XFS_MOUNT_BARRIER )xfs_mountfs_check_barriers (mp);
@@ -1340,11 +1342,37 @@ xfs_fs_remount( } mp->m_update_flags =0 ; } + +/* +* Fill out the reserve pool if it is empty. Use the stashed +* value if it is non-zero, otherwise go with the default. +*/ +if (mp->m_resblks_save) { + resblks = mp->m_resblks_save; + mp->m_resblks_save =0 ; + }else { + resblks = mp->m_sb.sb_dblocks; +do_div (resblks,20 ); + resblks =min_t (__uint64_t, resblks,1024 ); + } +xfs_reserve_blocks (mp, &resblks,NULL ); }/* rw -> ro */ if (!(mp->m_flags &XFS_MOUNT_RDONLY ) && (*flags &MS_RDONLY )) { +/* +* After we have synced the data but before we sync the +* metadata, we need to free up the reserve block pool so that +* the used block count in the superblock on disk is correct at +* the end of the remount. Stash the current reserve pool size +* so that if we get remounted rw, we can return it to the same +* size. +*/ +__uint64_t resblks =0 ; +xfs_quiesce_data (mp); + mp->m_resblks_save = mp->m_resblks; +xfs_reserve_blocks (mp, &resblks,NULL );xfs_quiesce_attr (mp); mp->m_flags |=XFS_MOUNT_RDONLY ; }
fs/xfs/xfs_mount.h +1 -0
@@ -209,6 +209,7 @@ typedef struct xfs_mount {__uint64_t m_maxioffset;/* maximum inode offset */ __uint64_t m_resblks;/* total reserved blocks */ __uint64_t m_resblks_avail;/* available reserved blocks */ +__uint64_t m_resblks_save;/* reserved blks @ remount,ro */ int m_dalign;/* stripe unit */ int m_swidth;/* stripe width */ int m_sinoalign;/* stripe unit inode alignment */
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 25/197 xfs: remove invalid barrier optimization from xfs_fsync
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit e8b217e7530c6a073ac69f1c85b922d93fdf5647 upstream
Date: Tue, 2 Feb 2010 10:16:26 +1100
We always need to flush the disk write cache and can't skip it just because the no inode attributes have changed.
--- fs/xfs/xfs_vnodeops.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
fs/xfs/xfs_vnodeops.c +2 -10
@@ -597,7 +597,7 @@ xfs_fsync( {xfs_trans_t *tp;int error =0 ; -int log_flushed =0 , changed =1 ; +int log_flushed =0 ;xfs_itrace_entry (ip);
@@ -627,19 +627,11 @@ xfs_fsync(* disk yet, the inode will be still be pinned. If it is, * force the log. */ -xfs_iunlock (ip,XFS_ILOCK_SHARED ); -if (xfs_ipincount (ip)) { error =_xfs_log_force (ip->i_mount, (xfs_lsn_t )0 ,XFS_LOG_FORCE |XFS_LOG_SYNC , &log_flushed); - }else { -/* -* If the inode is not pinned and nothing has changed -* we don't need to flush the cache. -*/ - changed =0 ; } }else {/*
@@ -674,7 +666,7 @@ xfs_fsync(xfs_iunlock (ip,XFS_ILOCK_EXCL ); } -if ((ip->i_mount->m_flags &XFS_MOUNT_BARRIER ) && changed) { +if (ip->i_mount->m_flags &XFS_MOUNT_BARRIER ) {/* * If the log write didn't issue an ordered tag we need * to flush the disk cache for the data device now.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 26/197 xfs: Non-blocking inode locking in IO completion
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Chinner <[email protected]>
commit 77d7a0c2eeb285c9069e15396703d0cb9690ac50 upstream
The introduction of barriers to loop devices has created a new IO order completion dependency that XFS does not handle. The loop device implements barriers using fsync and so turns a log IO in the XFS filesystem on the loop device into a data IO in the backing filesystem. That is, the completion of log IOs in the loop filesystem are now dependent on completion of data IO in the backing filesystem.
This can cause deadlocks when a flush daemon issues a log force with an inode locked because the IO completion of IO on the inode is blocked by the inode lock. This in turn prevents further data IO completion from occuring on all XFS filesystems on that CPU (due to the shared nature of the completion queues). This then prevents the log IO from completing because the log is waiting for data IO completion as well.
The fix for this new completion order dependency issue is to make the IO completion inode locking non-blocking. If the inode lock can't be grabbed, simply requeue the IO completion back to the work queue so that it can be processed later. This prevents the completion queue from being blocked and allows data IO completion on other inodes to proceed, hence avoiding completion order dependent deadlocks.
--- fs/xfs/linux-2.6/xfs_aops.c | 118 ++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 36 deletions(-)
fs/xfs/linux-2.6/xfs_aops.c +82 -36
@@ -204,14 +204,17 @@ xfs_ioend_new_eof( }/* -* Update on-disk file size now that data has been written to disk. -* The current in-memory file size is i_size. If a write is beyond -* eof i_new_size will be the intended file size until i_size is -* updated. If this write does not extend all the way to the valid -* file size then restrict this update to the end of the write. +* Update on-disk file size now that data has been written to disk. The +* current in-memory file size is i_size. If a write is beyond eof i_new_size +* will be the intended file size until i_size is updated. If this write does +* not extend all the way to the valid file size then restrict this update to +* the end of the write. +* +* This function does not block as blocking on the inode lock in IO completion +* can lead to IO completion order dependency deadlocks.. If it can't get the +* inode ilock it will return EAGAIN. Callers must handle this. */ - -STATIC void +STATIC intxfs_setfilesize (xfs_ioend_t *ioend) {
@@ -222,9 +225,11 @@ xfs_setfilesize(ASSERT (ioend->io_type !=IOMAP_READ );if (unlikely (ioend->io_error)) -return ; +return 0 ; + +if (!xfs_ilock_nowait (ip,XFS_ILOCK_EXCL )) +return EAGAIN ; -xfs_ilock (ip,XFS_ILOCK_EXCL ); isize =xfs_ioend_new_eof (ioend);if (isize) { ip->i_d.di_size = isize;
@@ -232,6 +237,28 @@ xfs_setfilesize( }xfs_iunlock (ip,XFS_ILOCK_EXCL ); +return 0 ; +} + +/* +* Schedule IO completion handling on a xfsdatad if this was +* the final hold on this ioend. If we are asked to wait, +* flush the workqueue. +*/ +STATIC void +xfs_finish_ioend ( +xfs_ioend_t *ioend, +int wait) +{ +if (atomic_dec_and_test (&ioend->io_remaining)) { +struct workqueue_struct *wq; + + wq = (ioend->io_type ==IOMAP_UNWRITTEN ) ? + xfsconvertd_workqueue : xfsdatad_workqueue; +queue_work (wq, &ioend->io_work); +if (wait) +flush_workqueue (wq); + } }/*
@@ -243,9 +270,23 @@ xfs_end_bio_delalloc( {xfs_ioend_t *ioend =container_of (work, xfs_ioend_t, io_work); +int error; -xfs_setfilesize (ioend); -xfs_destroy_ioend (ioend); +/* +* If we didn't complete processing of the ioend, requeue it to the +* tail of the workqueue for another attempt later. Otherwise destroy +* it. +*/ + error =xfs_setfilesize (ioend); +if (error ==EAGAIN ) { +atomic_inc (&ioend->io_remaining); +xfs_finish_ioend (ioend,0 ); +/* ensure we don't spin on blocked ioends */ +delay (1 ); + }else { +ASSERT (!error); +xfs_destroy_ioend (ioend); + } }/*
@@ -257,9 +298,23 @@ xfs_end_bio_written( {xfs_ioend_t *ioend =container_of (work, xfs_ioend_t, io_work); +int error; -xfs_setfilesize (ioend); -xfs_destroy_ioend (ioend); +/* +* If we didn't complete processing of the ioend, requeue it to the +* tail of the workqueue for another attempt later. Otherwise destroy +* it. +*/ + error =xfs_setfilesize (ioend); +if (error ==EAGAIN ) { +atomic_inc (&ioend->io_remaining); +xfs_finish_ioend (ioend,0 ); +/* ensure we don't spin on blocked ioends */ +delay (1 ); + }else { +ASSERT (!error); +xfs_destroy_ioend (ioend); + } }/*
@@ -279,13 +334,25 @@ xfs_end_bio_unwritten(size_t size = ioend->io_size;if (likely (!ioend->io_error)) { +int error;if (!XFS_FORCED_SHUTDOWN (ip->i_mount)) { -int error; error =xfs_iomap_write_unwritten (ip, offset, size);if (error) ioend->io_error = error; } -xfs_setfilesize (ioend); +/* +* If we didn't complete processing of the ioend, requeue it to the +* tail of the workqueue for another attempt later. Otherwise destroy +* it. +*/ + error =xfs_setfilesize (ioend); +if (error ==EAGAIN ) { +atomic_inc (&ioend->io_remaining); +xfs_finish_ioend (ioend,0 ); +/* ensure we don't spin on blocked ioends */ +delay (1 ); +return ; + } }xfs_destroy_ioend (ioend); }
@@ -304,27 +371,6 @@ xfs_end_bio_read( }/* -* Schedule IO completion handling on a xfsdatad if this was -* the final hold on this ioend. If we are asked to wait, -* flush the workqueue. -*/ -STATIC void -xfs_finish_ioend ( -xfs_ioend_t *ioend, -int wait) -{ -if (atomic_dec_and_test (&ioend->io_remaining)) { -struct workqueue_struct *wq = xfsdatad_workqueue; -if (ioend->io_work.func == xfs_end_bio_unwritten) - wq = xfsconvertd_workqueue; - -queue_work (wq, &ioend->io_work); -if (wait) -flush_workqueue (wq); - } -} - -/* * Allocate and initialise an IO completion structure. * We need to track unwritten extent write completion here initially. * We'll need to extend this for updating the ondisk inode size later
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 27/197 xfs: fix locking for inode cache radix tree tag updates
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Hellwig <[email protected]>
commit f1f724e4b523d444c5a598d74505aefa3d6844d2 upstream
The radix-tree code requires it's users to serialize tag updates against other updates to the tree. While XFS protects tag updates against each other it does not serialize them against updates of the tree contents, which can lead to tag corruption. Fix the inode cache to always take pag_ici_lock in exclusive mode when updating radix tree tags.
--- fs/xfs/linux-2.6/xfs_sync.c | 4 ++-- fs/xfs/xfs_iget.c | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-)
fs/xfs/linux-2.6/xfs_sync.c +2 -2
@@ -692,12 +692,12 @@ xfs_inode_set_reclaim_tag(xfs_mount_t *mp = ip->i_mount;xfs_perag_t *pag =xfs_get_perag (mp, ip->i_ino); -read_lock (&pag->pag_ici_lock); +write_lock (&pag->pag_ici_lock);spin_lock (&ip->i_flags_lock);__xfs_inode_set_reclaim_tag (pag, ip);__xfs_iflags_set (ip,XFS_IRECLAIMABLE );spin_unlock (&ip->i_flags_lock); -read_unlock (&pag->pag_ici_lock); +write_unlock (&pag->pag_ici_lock);xfs_put_perag (mp, pag); }
fs/xfs/xfs_iget.c +13 -6
@@ -228,13 +228,12 @@ xfs_iget_cache_hit(xfs_itrace_exit_tag (ip,"xfs_iget.alloc" );/* -* We need to set XFS_INEW atomically with clearing the -* reclaimable tag so that we do have an indicator of the -* inode still being initialized. +* We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode +* from stomping over us while we recycle the inode. We can't +* clear the radix tree reclaimable tag yet as it requires +* pag_ici_lock to be held exclusive. */ - ip->i_flags |=XFS_INEW ; - ip->i_flags &= ~XFS_IRECLAIMABLE ; -__xfs_inode_clear_reclaim_tag (mp, pag, ip); + ip->i_flags |=XFS_IRECLAIM ;spin_unlock (&ip->i_flags_lock);read_unlock (&pag->pag_ici_lock);
@@ -253,7 +252,15 @@ xfs_iget_cache_hit(__xfs_inode_set_reclaim_tag (pag, ip); goto out_error; } + +write_lock (&pag->pag_ici_lock); +spin_lock (&ip->i_flags_lock); + ip->i_flags &= ~(XFS_IRECLAIMABLE |XFS_IRECLAIM ); + ip->i_flags |=XFS_INEW ; +__xfs_inode_clear_reclaim_tag (mp, pag, ip); inode->i_state =I_LOCK |I_NEW ; +spin_unlock (&ip->i_flags_lock); +write_unlock (&pag->pag_ici_lock); }else {/* If the VFS inode is being torn down, pause and try again. */ if (!igrab (inode)) {
PATCH 28/197 sh: Enable the mmu in start_secondary()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Matt Fleming <[email protected]>
commit 4bea3418c737891894b9d3d3e9f8bbd67d66fa38 upstream.
For the boot, enable_mmu() is called from setup_arch() but we don't call setup_arch() for any of the other cpus. So turn on the non-boot cpu's mmu inside of start_secondary().
I noticed this bug on an SMP board when trying to map I/O memory (smsc911x registers) into the kernel address space. Since the Address Translation bit in MMUCR wasn't set, accessing the virtual address where the smsc911x registers were supposedly mapped actually performed a physical address access.
arch/sh/kernel/smp.c +1 -0
@@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void)unsigned int cpu;struct mm_struct *mm = &init_mm; +enable_mmu ();atomic_inc (&mm->mm_count);atomic_inc (&mm->mm_users); current->active_mm = mm;
PATCH 29/197 sh: Fix FDPIC binary loader
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Stubbs <[email protected]>
commit d5ab780305bb6d60a7b5a74f18cf84eb6ad153b1 upstream.
Ensure that the aux table is properly initialized, even when optional features are missing. Without this, the FDPIC loader did not work.
--- arch/sh/include/asm/elf.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/sh/include/asm/elf.h +4 -2
@@ -212,7 +212,9 @@ extern void __kernel_vsyscall;#define VSYSCALL_AUX_ENT \ if (vdso_enabled) \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ + else \ + NEW_AUX_ENT(AT_IGNORE, 0);#else #define VSYSCALL_AUX_ENT #endif /* CONFIG_VSYSCALL */
@@ -220,7 +222,7 @@ extern void __kernel_vsyscall;#ifdef CONFIG_SH_FPU #define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT)#else -#define FPU_AUX_ENT +#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0)#endif extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
PATCH 30/197 libiscsi: Fix recovery slowdown regression
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Christie <[email protected]>
commit 4ae0a6c15efcc37e94e3f30e3533bdec03c53126 upstream.
We could be failing/stopping a connection due to libiscsi starting recovery/cleanup, but the xmit path or scsi eh thread path could be dropping the connection at the same time.
As a result the session->state gets set to failed instead of in recovery. We end up not blocking the session
and so the replacement timeout never gets started and we only end up failing the IO when scsi_softirq_done sees that the
cmd has been running for (cmd->allowed + 1) * rq->timeout secs.
We used to fail the IO right away so users are seeing a long delay when using dm-multipath. This problem was added in 2.6.28.
--- drivers/scsi/libiscsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/libiscsi.c +3 -2
@@ -2823,14 +2823,15 @@ static void iscsi_start_session_recovery session->state =ISCSI_STATE_TERMINATE ; else if (conn->stop_stage != STOP_CONN_RECOVER) session->state = ISCSI_STATE_IN_RECOVERY; + + old_stop_stage = conn->stop_stage; + conn->stop_stage = flag;spin_unlock_bh (&session->lock);del_timer_sync (&conn->transport_timer);iscsi_suspend_tx (conn);spin_lock_bh (&session->lock); - old_stop_stage = conn->stop_stage; - conn->stop_stage = flag; conn->c_stage =ISCSI_CONN_STOPPED ;spin_unlock_bh (&session->lock);
PATCH 31/197 Freezer: Fix buggy resume test for tasks frozen with cgroup freezer
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Matt Helsley <[email protected]>
commit 5a7aadfe2fcb0f69e2acc1fbefe22a096e792fc9 upstream.
When the cgroup freezer is used to freeze tasks we do not want to thaw those tasks during resume. Currently we test the cgroup freezer state of the resuming tasks to see if the cgroup is FROZEN. If so then we don't thaw the task. However, the FREEZING state also indicates that the task should remain frozen.
This also avoids a problem pointed out by Oren Ladaan: the freezer state transition from FREEZING to FROZEN is updated lazily when userspace reads or writes the freezer.state file in the cgroup filesystem. This means that resume will thaw tasks in cgroups which should be in the FROZEN state if there is no read/write of the freezer.state file to trigger this transition before suspend.
NOTE: Another "simple" solution would be to always update the cgroup freezer state during resume. However it's a bad choice for several reasons:
Updating the cgroup freezer state is somewhat expensive because it requires walking all the tasks in the cgroup and checking if they are each frozen. Worse, this could easily make resume run in N^2 time where N is the number of tasks in the cgroup. Finally, updating the freezer state from this code path requires trickier locking because of the way locks must be ordered.
Instead of updating the freezer state we rely on the fact that lazy updates only manage the transition from FREEZING to FROZEN. We know that a cgroup with the FREEZING state may actually be FROZEN so test for that state too. This makes sense in the resume path even for partially-frozen cgroups -- those that really are FREEZING but not FROZEN.
--- include/linux/freezer.h | 7 +++++-- kernel/cgroup_freezer.c | 9 ++++++--- kernel/power/process.c | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-)
include/linux/freezer.h +5 -2
@@ -64,9 +64,12 @@ extern bool freeze_task(struct task_struextern void cancel_freezing (struct task_struct *p);#ifdef CONFIG_CGROUP_FREEZER -extern int cgroup_frozen (struct task_struct *task); +extern int cgroup_freezing_or_frozen (struct task_struct *task);#else /* !CONFIG_CGROUP_FREEZER */ -static inline int cgroup_frozen (struct task_struct *task) {return 0 ; } +static inline int cgroup_freezing_or_frozen (struct task_struct *task) +{ +return 0 ; +}#endif /* !CONFIG_CGROUP_FREEZER */ /*
kernel/cgroup_freezer.c +6 -3
@@ -47,17 +47,20 @@ static inline struct freezer *task_freez struct freezer, css); } -int cgroup_frozen (struct task_struct *task) +int cgroup_freezing_or_frozen (struct task_struct *task) {struct freezer *freezer;enum freezer_state state;task_lock (task); freezer =task_freezer (task); - state = freezer->state; +if (!freezer->css.cgroup->parent) + state =CGROUP_THAWED ;/* root cgroup can't be frozen */ +else + state = freezer->state;task_unlock (task); -return state ==CGROUP_FROZEN ; +return (state ==CGROUP_FREEZING ) || (state ==CGROUP_FROZEN ); }/*
kernel/power/process.c +1 -1
@@ -139,7 +139,7 @@ static void thaw_tasks(bool nosig_only)if (nosig_only &&should_send_signal (p))continue ; -if (cgroup_frozen (p)) +if (cgroup_freezing_or_frozen (p))continue ;thaw_process (p);
PATCH 32/197 iwlwifi: counting number of tfds can be free for 4965
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wey-Yi Guy <[email protected]>
commit be6b38bcb175613f239e0b302607db346472c6b6 upstream.
Forget one hunk in 4965 during "iwlwifi: error checking for number of tfds in queue" patch.
--- drivers/net/wireless/iwlwifi/iwl-4965.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965.c +2 -4
@@ -2161,16 +2161,14 @@ static void iwl4965_rx_reply_tx(struct i tx_resp->failure_frame); freed =iwl_tx_queue_reclaim (priv, txq_id, index); -if (qc &&likely (sta_id !=IWL_INVALID_STATION )) - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; +iwl_free_tfds_in_queue (priv, sta_id, tid, freed);if (priv->mac80211_registered && (iwl_queue_space (&txq->q) > txq->q.low_mark))iwl_wake_queue (priv, txq_id); } -if (qc &&likely (sta_id !=IWL_INVALID_STATION )) -iwl_txq_check_empty (priv, sta_id, tid, txq_id); +iwl_txq_check_empty (priv, sta_id, tid, txq_id);if (iwl_check_bits (status,TX_ABORT_REQUIRED_MSK ))IWL_ERR (priv,"TODO: Implement Tx ABORT REQUIRED!!!\n" );
PATCH 33/197 iwlwifi: fix nfreed--
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
During backporting of a120e912eb51e347f36c71b60a1d13af74d30e83 ("iwlwifi: sanity check before counting number of tfds can be free") we forget one hunk, what make lot of messages "free more than tfds_in_queue" show up in dmesg.
(picked from https://patchwork.kernel.org/patch/86722/)
--- drivers/net/wireless/iwlwifi/iwl-tx.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-tx.c +0 -1
@@ -1097,7 +1097,6 @@ int iwl_tx_queue_reclaim(struct iwl_priv priv->cfg->ops->lib->txq_inval_byte_cnt_tbl (priv, txq); priv->cfg->ops->lib->txq_free_tfd (priv, txq); - nfreed++; }return nfreed; }
PATCH 34/197 iwlwifi: range checking issue
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Carpenter <[email protected]>
commit 8e1a53c615e8efe0fac670f2973da64758748a8a upstream.
IWL_RATE_COUNT is 13 and IWL_RATE_COUNT_LEGACY is 12.
IWL_RATE_COUNT_LEGACY is the right one here because iwl3945_rates doesn't support 60M and also that's how "rates" is defined in iwlcore_init_geos() from drivers/net/wireless/iwlwifi/iwl-core.c.
rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
GFP_KERNEL);
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +1 -1
@@ -1904,7 +1904,7 @@ static void iwl3945_init_hw_rates(struct {int i; -for (i =0 ; i <IWL_RATE_COUNT ; i++) { +for (i =0 ; i <IWL_RATE_COUNT_LEGACY ; i++) { rates[i].bitrate = iwl3945_rates[i].ieee *5 ; rates[i].hw_value = i;/* Rate scaling will work on indexes */ rates[i].hw_value_short = i;
PATCH 35/197 setup correct int pipe type in ar9170_usb_exec_cmd
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Valentin Longchamp <[email protected]>
commit 2d20c72c021d96f8b9230396c8e3782f204214ec upstream.
An int urb is constructed but we fill it in with a bulk pipe type.
Commit f661c6f8c67bd55e93348f160d590ff9edf08904 implemented a pipe type check when CONFIG_USB_DEBUG is enabled. The check failed for all the ar9170 usb transfers and the driver could not configure the wifi dongle.
This went unnoticed until now because most people don't have CONFIG_USB_DEBUG enabled.
--- drivers/net/wireless/ath/ar9170/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ar9170/usb.c +1 -1
@@ -414,7 +414,7 @@ static int ar9170_usb_exec_cmd(struct arspin_unlock_irqrestore (&aru->common.cmdlock, flags);usb_fill_int_urb (urb, aru->udev, -usb_sndbulkpipe (aru->udev,AR9170_EP_CMD ), +usb_sndintpipe (aru->udev,AR9170_EP_CMD ), aru->common.cmdbuf, plen +4 , ar9170_usb_tx_urb_complete,NULL ,1 );
PATCH 36/197 mac80211: move netdev queue enabling to correct spot
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Johannes Berg <[email protected]>
commit 7236fe29fd72d17074574ba312e7f1bb9d10abaa upstream.
"mac80211: fix skb buffering issue" still left a race between enabling the hardware queues and the virtual interface queues. In hindsight it's totally obvious that enabling the netdev queues for a hardware queue when the hardware queue is enabled is wrong, because it could well possible that we can fill the hw queue with packets we already have pending. Thus, we must only enable the netdev queues once all the pending packets have been processed and sent off to the device.
In testing, I haven't been able to trigger this race condition, but it's clearly there, possibly only when aggregation is being enabled.
--- net/mac80211/tx.c | 6 ++++++ net/mac80211/util.c | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-)
net/mac80211/tx.c +6 -0
@@ -1881,6 +1881,7 @@ static bool ieee80211_tx_pending_skb(strvoid ieee80211_tx_pending (unsigned long data) {struct ieee80211_local *local = (struct ieee80211_local *)data; +struct ieee80211_sub_if_data *sdata;unsigned long flags;int i;bool txok;
@@ -1921,6 +1922,11 @@ void ieee80211_tx_pending(unsigned longif (!txok)break ; } + +if (skb_queue_empty (&local->pending[i])) +list_for_each_entry_rcu (sdata, &local->interfaces, list) +netif_tx_wake_queue ( +netdev_get_tx_queue (sdata->dev, i)); }spin_unlock_irqrestore (&local->queue_stop_reason_lock, flags);
net/mac80211/util.c +6 -6
@@ -280,13 +280,13 @@ static void __ieee80211_wake_queue(struc/* someone still has this queue stopped */ return ; -if (!skb_queue_empty (&local->pending[queue])) +if (skb_queue_empty (&local->pending[queue])) { +rcu_read_lock (); +list_for_each_entry_rcu (sdata, &local->interfaces, list) +netif_tx_wake_queue (netdev_get_tx_queue (sdata->dev, queue)); +rcu_read_unlock (); + }else tasklet_schedule (&local->tx_pending_tasklet); - -rcu_read_lock (); -list_for_each_entry_rcu (sdata, &local->interfaces, list) -netif_tx_wake_queue (netdev_get_tx_queue (sdata->dev, queue)); -rcu_read_unlock (); } void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
PATCH 37/197 mac80211: tear down all agg queues when restart/reconfig hw
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wey-Yi Guy <[email protected]>
commit 74e2bd1fa3ae9695af566ad5a7a288898787b909 upstream.
When there is a need to restart/reconfig hw, tear down all the aggregation queues and let the mac80211 and driver get in-sync to have the opportunity to re-establish the aggregation queues again.
Need to wait until driver re-establish all the station information before tear down the aggregation queues, driver(at least iwlwifi driver) will reject the stop aggregation queue request if station is not ready. But also need to make sure the aggregation queues are tear down before waking up the queues, so mac80211 will not sending frames with aggregation bit set.
--- net/mac80211/util.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/mac80211/util.c +8 -0
@@ -1137,6 +1137,14 @@ int ieee80211_reconfig(struct ieee80211_ } } +rcu_read_lock (); +if (hw->flags &IEEE80211_HW_AMPDU_AGGREGATION ) { +list_for_each_entry_rcu (sta, &local->sta_list, list) { +ieee80211_sta_tear_down_BA_sessions (sta); + } + } +rcu_read_unlock (); +/* add back keys */ list_for_each_entry (sdata, &local->interfaces, list)if (netif_running (sdata->dev))
PATCH 38/197 WATCHDOG: hpwdt - fix lower timeout limit
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Thomas Mingarelli <[email protected]>
commit 8ba42bd88c6982fe224b09c33151c797b0fdf1a5 upstream.
[Novell Bug 581103] HP Watchdog driver has arbitrary (wrong) timeout limits. Fix the lower timeout limit to a more appropriate value.
--- drivers/watchdog/hpwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/hpwdt.c +1 -1
@@ -443,7 +443,7 @@ static void hpwdt_ping(void)static int hpwdt_change_timer (int new_margin) {/* Arbitrary, can't find the card's limits */ -if (new_margin <30 || new_margin >600 ) { +if (new_margin <5 || new_margin >600 ) {printk (KERN_WARNING "hpwdt: New value passed in is invalid: %d seconds.\n" , new_margin);
PATCH 39/197 WATCHDOG: iTCO_wdt: TCO Watchdog patch for additional Intel Cougar Point DeviceIDs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Seth Heasley <[email protected]>
commit 4c7d849204341dea19be941a3c1eb4bdffac9cc4 upstream.
This patch adds the Intel Cougar Point PCH LPC Controller DeviceIDs for iTCO Watchdog.
--- drivers/watchdog/iTCO_wdt.c | 99 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 6 deletions(-)
drivers/watchdog/iTCO_wdt.c +93 -6
@@ -115,8 +115,37 @@ enum iTCO_chipsets {TCO_3420 ,/* 3420 */ TCO_3450 ,/* 3450 */ TCO_EP80579 ,/* EP80579 */ -TCO_CPTD ,/* CPT Desktop */ - TCO_CPTM, /* CPT Mobile */ +TCO_CPT1 ,/* Cougar Point */ +TCO_CPT2 ,/* Cougar Point Desktop */ +TCO_CPT3 ,/* Cougar Point Mobile */ +TCO_CPT4 ,/* Cougar Point */ +TCO_CPT5 ,/* Cougar Point */ +TCO_CPT6 ,/* Cougar Point */ +TCO_CPT7 ,/* Cougar Point */ +TCO_CPT8 ,/* Cougar Point */ +TCO_CPT9 ,/* Cougar Point */ +TCO_CPT10 ,/* Cougar Point */ +TCO_CPT11 ,/* Cougar Point */ +TCO_CPT12 ,/* Cougar Point */ +TCO_CPT13 ,/* Cougar Point */ +TCO_CPT14 ,/* Cougar Point */ +TCO_CPT15 ,/* Cougar Point */ +TCO_CPT16 ,/* Cougar Point */ +TCO_CPT17 ,/* Cougar Point */ +TCO_CPT18 ,/* Cougar Point */ +TCO_CPT19 ,/* Cougar Point */ +TCO_CPT20 ,/* Cougar Point */ +TCO_CPT21 ,/* Cougar Point */ +TCO_CPT22 ,/* Cougar Point */ +TCO_CPT23 ,/* Cougar Point */ +TCO_CPT24 ,/* Cougar Point */ +TCO_CPT25 ,/* Cougar Point */ +TCO_CPT26 ,/* Cougar Point */ +TCO_CPT27 ,/* Cougar Point */ +TCO_CPT28 ,/* Cougar Point */ +TCO_CPT29 ,/* Cougar Point */ +TCO_CPT30 ,/* Cougar Point */ + TCO_CPT31, /* Cougar Point */ }; static struct {
@@ -173,8 +202,37 @@ static struct { {"3420", 2}, {"3450", 2}, {"EP80579", 2}, - {"CPT Desktop", 2}, - {"CPT Mobile", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, + {"Cougar Point", 2}, {NULL, 0} };
@@ -259,8 +317,37 @@ static struct pci_device_id iTCO_wdt_pci { ITCO_PCI_DEVICE(0x3b14, TCO_3420)}, { ITCO_PCI_DEVICE(0x3b16, TCO_3450)}, { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, - { ITCO_PCI_DEVICE(0x1c42, TCO_CPTD)}, - { ITCO_PCI_DEVICE(0x1c43, TCO_CPTM)}, + { ITCO_PCI_DEVICE(0x1c41, TCO_CPT1)}, + { ITCO_PCI_DEVICE(0x1c42, TCO_CPT2)}, + { ITCO_PCI_DEVICE(0x1c43, TCO_CPT3)}, + { ITCO_PCI_DEVICE(0x1c44, TCO_CPT4)}, + { ITCO_PCI_DEVICE(0x1c45, TCO_CPT5)}, + { ITCO_PCI_DEVICE(0x1c46, TCO_CPT6)}, + { ITCO_PCI_DEVICE(0x1c47, TCO_CPT7)}, + { ITCO_PCI_DEVICE(0x1c48, TCO_CPT8)}, + { ITCO_PCI_DEVICE(0x1c49, TCO_CPT9)}, + { ITCO_PCI_DEVICE(0x1c4a, TCO_CPT10)}, + { ITCO_PCI_DEVICE(0x1c4b, TCO_CPT11)}, + { ITCO_PCI_DEVICE(0x1c4c, TCO_CPT12)}, + { ITCO_PCI_DEVICE(0x1c4d, TCO_CPT13)}, + { ITCO_PCI_DEVICE(0x1c4e, TCO_CPT14)}, + { ITCO_PCI_DEVICE(0x1c4f, TCO_CPT15)}, + { ITCO_PCI_DEVICE(0x1c50, TCO_CPT16)}, + { ITCO_PCI_DEVICE(0x1c51, TCO_CPT17)}, + { ITCO_PCI_DEVICE(0x1c52, TCO_CPT18)}, + { ITCO_PCI_DEVICE(0x1c53, TCO_CPT19)}, + { ITCO_PCI_DEVICE(0x1c54, TCO_CPT20)}, + { ITCO_PCI_DEVICE(0x1c55, TCO_CPT21)}, + { ITCO_PCI_DEVICE(0x1c56, TCO_CPT22)}, + { ITCO_PCI_DEVICE(0x1c57, TCO_CPT23)}, + { ITCO_PCI_DEVICE(0x1c58, TCO_CPT24)}, + { ITCO_PCI_DEVICE(0x1c59, TCO_CPT25)}, + { ITCO_PCI_DEVICE(0x1c5a, TCO_CPT26)}, + { ITCO_PCI_DEVICE(0x1c5b, TCO_CPT27)}, + { ITCO_PCI_DEVICE(0x1c5c, TCO_CPT28)}, + { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)}, + { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)}, + { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)}, { 0, }, /* End of list */ };MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
PATCH 40/197 genirq: Force MSI irq handlers to run with interrupts disabled
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Thomas Gleixner <[email protected]>
commit 753649dbc49345a73a2454c770a3f2d54d11aec6 upstream.
Network folks reported that directing all MSI-X vectors of their multi queue NICs to a single core can cause interrupt stack overflows when enough interrupts fire at the same time.
This is caused by the fact that we run interrupt handlers by default with interrupts enabled unless the driver reuqests the interrupt with the IRQF_DISABLED set. The NIC handlers do not set this flag, so simultaneous interrupts can nest unlimited and cause the stack overflow.
The only safe counter measure is to run the interrupt handlers with interrupts disabled. We can't switch to this mode in general right now, but it is safe to do so for MSI interrupts.
Force IRQF_DISABLED for MSI interrupt handlers.
--- kernel/irq/manage.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
kernel/irq/manage.c +10 -0
@@ -735,6 +735,16 @@ __setup_irq(unsigned int irq, struct irqif (new->flags &IRQF_ONESHOT ) desc->status |=IRQ_ONESHOT ; +/* +* Force MSI interrupts to run with interrupts +* disabled. The multi vector cards can cause stack +* overflows due to nested interrupts when enough of +* them are directed to a core and fire at the same +* time. +*/ +if (desc->msi_desc) + new->flags |=IRQF_DISABLED ; +if (!(desc->status &IRQ_NOAUTOEN )) { desc->depth =0 ; desc->status &= ~IRQ_DISABLED ;
PATCH 41/197 tty: release_one_tty() forgets to put pids
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Oleg Nesterov <[email protected]>
commit 6da8d866d0d39e9509ff826660f6a86a6757c966 upstream.
release_one_tty(tty) can be called when tty still has a reference to pgrp/session. In this case we leak the pid.
--- drivers/char/tty_io.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/char/tty_io.c +2 -0
@@ -1408,6 +1408,8 @@ static void release_one_tty(struct work_list_del_init (&tty->tty_files);file_list_unlock (); +put_pid (tty->pgrp); +put_pid (tty->session);free_tty_struct (tty); }
PATCH 42/197 lis3: fix show rate for 8 bits chips
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Éric Piel <[email protected]>
commit 4b5d95b3809bcd77599122494aa3f575cd6ab1b9 upstream.
Originally the driver was only targeted to 12bits sensors. When support for 8bits sensors was added, some slight difference in the registers were overlooked. This should fix it, both for initialization, and for displaying the rate.
--- drivers/hwmon/lis3lv02d.c | 24 ++++++++++++++++-------- drivers/hwmon/lis3lv02d.h | 1 + 2 files changed, 17 insertions(+), 8 deletions(-)
drivers/hwmon/lis3lv02d.c +16 -8
@@ -127,12 +127,14 @@ void lis3lv02d_poweron(struct lis3lv02d/* * Common configuration -* BDU: LSB and MSB values are not updated until both have been read. -* So the value read will always be correct. +* BDU: (12 bits sensors only) LSB and MSB values are not updated until +* both have been read. So the value read will always be correct. */ - lis3->read (lis3,CTRL_REG2 , ®); - reg |=CTRL2_BDU ; - lis3->write (lis3,CTRL_REG2 , reg); +if (lis3->whoami ==LIS_DOUBLE_ID ) { + lis3->read (lis3,CTRL_REG2 , ®); + reg |=CTRL2_BDU ; + lis3->write (lis3,CTRL_REG2 , reg); + } }EXPORT_SYMBOL_GPL (lis3lv02d_poweron);
@@ -361,7 +363,8 @@ static ssize_t lis3lv02d_calibrate_store }/* conversion btw sampling rate and the register values */ -static int lis3lv02dl_df_val[4 ] = {40 ,160 ,640 ,2560 }; +static int lis3_12_rates[4 ] = {40 ,160 ,640 ,2560 }; +static int lis3_8_rates[2 ] = {100 ,400 };static ssize_t lis3lv02d_rate_show (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -369,8 +372,13 @@ static ssize_t lis3lv02d_rate_show(strucint val; lis3_dev.read (&lis3_dev,CTRL_REG1 , &ctrl); - val = (ctrl & (CTRL1_DF0 |CTRL1_DF1 )) >>4 ; -return sprintf (buf,"%d\n" , lis3lv02dl_df_val[val]); + +if (lis3_dev.whoami ==LIS_DOUBLE_ID ) + val = lis3_12_rates[(ctrl & (CTRL1_DF0 |CTRL1_DF1 )) >>4 ]; +else + val = lis3_8_rates[(ctrl &CTRL1_DR ) >>7 ]; + +return sprintf (buf,"%d\n" , val); } static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
drivers/hwmon/lis3lv02d.h +1 -0
@@ -103,6 +103,7 @@ enum lis3lv02d_ctrl1 {CTRL1_DF1 =0x20 ,CTRL1_PD0 =0x40 ,CTRL1_PD1 =0x80 , + CTRL1_DR = 0x80, /* Data rate on 8 bits */ };enum lis3lv02d_ctrl2 { CTRL2_DAS = 0x01,
PATCH 43/197 pata_ali: Fix regression with old devices
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Cox <[email protected]>
commit d6250a03fa736c1bff4df4601f5af2dc21f2bf9e upstream.
Making the new stuff work broke some of the old chipsets. We need to go back to the old set up values for these it seems. Unfortunately even with documentation this is basically a mix of cargoculting and guesswork.
Chased down to the exact line by Gianluca.
--- drivers/ata/pata_ali.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ata/pata_ali.c +3 -1
@@ -453,7 +453,9 @@ static void ali_init_chipset(struct pci_/* Clear CD-ROM DMA write bit */ tmp &=0x7F ;/* Cable and UDMA */ -pci_write_config_byte (pdev,0x4B , tmp |0x09 ); +if (pdev->revision >=0xc2 ) + tmp |=0x01 ; +pci_write_config_byte (pdev,0x4B , tmp |0x08 );/* * CD_ROM DMA on (0x53 bit 0). Enable this even if we want * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
PATCH 44/197 HID: fix oops in gyration_event()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jiri Kosina <[email protected]>
commit d8e4ebf8b603bdcd091540e6b5bddf0dec10d516 upstream.
Fix oops caused by dereferencing field->hidinput in cases where the device hasn't been claimed by hid-input.
--- drivers/hid/hid-gyration.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/hid/hid-gyration.c +4 -1
@@ -53,10 +53,13 @@ static int gyration_input_mapping(structstatic int gyration_event (struct hid_device *hdev,struct hid_field *field,struct hid_usage *usage,__s32 value) { -struct input_dev *input = field->hidinput->input; + +if (!(hdev->claimed &HID_CLAIMED_INPUT ) || !field->hidinput) +return 0 ;if ((usage->hid &HID_USAGE_PAGE ) ==HID_UP_GENDESK && (usage->hid &0xff ) ==0x82 ) { +struct input_dev *input = field->hidinput->input;input_event (input, usage->type, usage->code,1 );input_sync (input);input_event (input, usage->type, usage->code,0 );
PATCH 45/197 raw: fsync method is now required
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Anton Blanchard <[email protected]>
commit 55ab3a1ff843e3f0e24d2da44e71bffa5d853010 upstream.
Commit 148f948ba877f4d3cdef036b1ff6d9f68986706a (vfs: Introduce new helpers for syncing after writing to O_SYNC file or IS_SYNC inode) broke the raw driver.
We now call through generic_file_aio_write -> generic_write_sync -> vfs_fsync_range. vfs_fsync_range has:
if (!fop || !fop->fsync) {
ret = -EINVAL;
goto out;
}But drivers/char/raw.c doesn't set an fsync method.
We have two options: fix it or remove the raw driver completely. I'm happy to do either, the fact this has been broken for so long suggests it is rarely used.
The patch below adds an fsync method to the raw driver. My knowledge of the block layer is pretty sketchy so this could do with a once over.
If we instead decide to remove the raw driver, this patch might still be useful as a backport to 2.6.33 and 2.6.32.
--- drivers/char/raw.c | 1 + fs/block_dev.c | 3 ++- include/linux/fs.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-)
drivers/char/raw.c +1 -0
@@ -247,6 +247,7 @@ static const struct file_operations raw_ .aio_read = generic_file_aio_read, .write = do_sync_write, .aio_write = blkdev_aio_write, + .fsync = block_fsync, .open = raw_open, .release= raw_release, .ioctl = raw_ioctl,
fs/block_dev.c +2 -1
@@ -404,7 +404,7 @@ static loff_t block_llseek(struct file ** NULL first argument is nfsd_sync_dir() and that's not a directory. */ -static int block_fsync (struct file *filp,struct dentry *dentry,int datasync) +int block_fsync (struct file *filp,struct dentry *dentry,int datasync) {return sync_blockdev (I_BDEV (filp->f_mapping->host)); }
@@ -423,6 +423,7 @@ static struct inode *bdev_alloc_inode(streturn NULL ;return &ei->vfs_inode; } +EXPORT_SYMBOL (block_fsync);static void bdev_destroy_inode (struct inode *inode) {
include/linux/fs.h +1 -0
@@ -2225,6 +2225,7 @@ extern int generic_segment_checks(const/* fs/block_dev.c */ extern ssize_t blkdev_aio_write (struct kiocb *iocb,const struct iovec *iov,unsigned long nr_segs,loff_t pos); +extern int block_fsync (struct file *filp,struct dentry *dentry,int datasync);/* fs/splice.c */ extern ssize_t generic_file_splice_read(struct file *, loff_t *,
PATCH 46/197 readahead: fix NULL filp dereference
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wu Fengguang <[email protected]>
commit 70655c06bd3f25111312d63985888112aed15ac5 upstream.
btrfs relocate_file_extent_cluster() calls us with NULL filp:
[ 4005.426805] BUG: unable to handle kernel NULL pointer dereference at 00000021 [ 4005.426818] IP: [<c109a130>] page_cache_sync_readahead+0x18/0x3e
--- mm/readahead.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/readahead.c +1 -1
@@ -502,7 +502,7 @@ void page_cache_sync_readahead(struct adreturn ;/* be dumb */ -if (filp->f_mode &FMODE_RANDOM ) { +if (filp && (filp->f_mode &FMODE_RANDOM )) {force_page_cache_readahead (mapping, filp, offset, req_size);return ; }
PATCH 47/197 ALSA: mixart: range checking proc file
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Carpenter <[email protected]>
commit b0cc58a25d04160d39a80e436847eaa2fbc5aa09 upstream.
The original code doesn't take into consideration that the value of MIXART_BA0_SIZE - pos can be less than zero which would lead to a large unsigned value for "count".
Also I moved the check that read size is a multiple of 4 bytes below the code that adjusts "count".
--- sound/pci/mixart/mixart.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
sound/pci/mixart/mixart.c +14 -10
@@ -1161,13 +1161,15 @@ static long snd_mixart_BA0_read(struct s unsigned long count, unsigned long pos) {struct mixart_mgr *mgr = entry->private_data; +unsigned long maxsize; - count = count & ~3 ;/* make sure the read size is a multiple of 4 bytes */ -if (count <=0 ) +if (pos >=MIXART_BA0_SIZE )return 0 ; -if (pos + count >MIXART_BA0_SIZE ) - count = (long )(MIXART_BA0_SIZE - pos); -if (copy_to_user_fromio (buf,MIXART_MEM ( mgr, pos ), count)) + maxsize =MIXART_BA0_SIZE - pos; +if (count > maxsize) + count = maxsize; + count = count & ~3 ;/* make sure the read size is a multiple of 4 bytes */ +if (copy_to_user_fromio (buf,MIXART_MEM (mgr, pos), count))return -EFAULT ;return count; }
@@ -1180,13 +1182,15 @@ static long snd_mixart_BA1_read(struct s unsigned long count, unsigned long pos) {struct mixart_mgr *mgr = entry->private_data; +unsigned long maxsize; - count = count & ~3 ;/* make sure the read size is a multiple of 4 bytes */ -if (count <=0 ) +if (pos >MIXART_BA1_SIZE )return 0 ; -if (pos + count >MIXART_BA1_SIZE ) - count = (long )(MIXART_BA1_SIZE - pos); -if (copy_to_user_fromio (buf,MIXART_REG ( mgr, pos ), count)) + maxsize =MIXART_BA1_SIZE - pos; +if (count > maxsize) + count = maxsize; + count = count & ~3 ;/* make sure the read size is a multiple of 4 bytes */ +if (copy_to_user_fromio (buf,MIXART_REG (mgr, pos), count))return -EFAULT ;return count; }
PATCH 48/197 ALSA: hda: Fix 0 dB offset for Lenovo Thinkpad models using AD1981
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel T Chen <[email protected]>
commit b8e80cf386419453678b01bef830f53445ebb15d upstream.
The OR's hardware distorts at PCM 100% because it does not correspond to 0 dB. Fix this in patch_ad1981() for all models using the Thinkpad quirk.
--- sound/pci/hda/patch_analog.c | 8 ++++++++ 1 file changed, 8 insertions(+)
sound/pci/hda/patch_analog.c +8 -0
@@ -1789,6 +1789,14 @@ static int patch_ad1981(struct hda_codeccase AD1981_THINKPAD : spec->mixers[0 ] = ad1981_thinkpad_mixers; spec->input_mux = &ad1981_thinkpad_capture_source; +/* set the upper-limit for mixer amp to 0dB for avoiding the +* possible damage by overloading +*/ +snd_hda_override_amp_caps (codec,0x11 ,HDA_INPUT , + (0x17 <<AC_AMPCAP_OFFSET_SHIFT ) | + (0x17 <<AC_AMPCAP_NUM_STEPS_SHIFT ) | + (0x05 <<AC_AMPCAP_STEP_SIZE_SHIFT ) | + (1 <<AC_AMPCAP_MUTE_SHIFT ));break ;case AD1981_TOSHIBA : spec->mixers[0 ] = ad1981_hp_mixers;
PATCH 49/197 x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andreas Herrmann <[email protected]>
commit 9d260ebc09a0ad6b5c73e17676df42c7bc75ff64 upstream.
Use NodeId MSR to get NodeId and number of nodes per processor.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/cpufeature.h | 1 arch/x86/include/asm/msr-index.h | 1 arch/x86/kernel/cpu/amd.c | 53 ++++++++++---------------------------- 3 files changed, 17 insertions(+), 38 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
@@ -153,6 +153,7 @@#define X86_FEATURE_SSE5 (6*32+11)/* SSE-5 */ #define X86_FEATURE_SKINIT (6*32+12)/* SKINIT/STGI instructions */ #define X86_FEATURE_WDT (6*32+13)/* Watchdog timer */ +#define X86_FEATURE_NODEID_MSR (6*32+19)/* NodeId MSR */ /* * Auxiliary flags: Linux defined - For features scattered in various
arch/x86/include/asm/msr-index.h +1 -0
@@ -125,6 +125,7 @@#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff#define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c/* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a
arch/x86/kernel/cpu/amd.c +15 -38
74 lines not on this page · raw message
Re: [049/197] x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space
Quoted 107 lines · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andreas Herrmann <[email protected]>
commit
9d260ebc09a0ad6b5c73e17676df42c7bc75ff64upstream.Use NodeId MSR to get NodeId and number of nodes per processor.
Signed-off-by Andreas Herrmann <[email protected]>LKML-Reference: <[email protected]>
Signed-off-by H. Peter Anvin <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- arch/x86/include/asm/cpufeature.h | 1 arch/x86/include/asm/msr-index.h | 1 arch/x86/kernel/cpu/amd.c | 53 ++++++++++---------------------------- 3 files changed, 17 insertions(+), 38 deletions(-)arch/x86/include/asm/cpufeature.h +1
-0@@ -153,6 +153,7 @@#define X86_FEATURE_SSE5 (6*32+11)/* SSE-5 */ #define X86_FEATURE_SKINIT (6*32+12)/* SKINIT/STGI instructions */ #define X86_FEATURE_WDT (6*32+13)/* Watchdog timer */ +#define X86_FEATURE_NODEID_MSR (6*32+19)/* NodeId MSR */ /* * Auxiliary flags: Linux defined - For features scattered in various arch/x86/include/asm/msr-index.h +1
-0@@ -125,6 +125,7 @@#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff#define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c/* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001aarch/x86/kernel/cpu/amd.c +13
-32@@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int api/* * Fixup core topology information for AMD multi-node processors. -* Assumption 1: Number of cores in each internal node is the same. -* Assumption 2: Mixed systems with both single-node and dual-node -* processors are not supported. +* Assumption: Number of cores in each internal node is the same. */ #ifdef CONFIG_X86_HT static void __cpuinit amd_fixup_dcm (struct cpuinfo_x86 *c) { -#ifdef CONFIG_PCI -u32 t, cpn; -u8 n, n_id; +unsigned long long value; +u32 nodes, cores_per_node;int cpu =smp_processor_id (); +if (!cpu_has (c,X86_FEATURE_NODEID_MSR )) +return ; +/* fixup topology information only once for a core */ if (cpu_has (c,X86_FEATURE_AMD_DCM ))return ; -/* check for multi-node processor on boot cpu */ - t =read_pci_config (0 ,24 ,3 ,0xe8 ); -if (!(t & (1 <<29 ))) +rdmsrl (MSR_FAM10H_NODE_ID , value); + + nodes = ((value >>3 ) &7 ) +1 ; +if (nodes ==1 )return ;set_cpu_cap (c,X86_FEATURE_AMD_DCM ); + cores_per_node = c->x86_max_cores / nodes; -/* cores per node: each internal node has half the number of cores */ - cpn = c->x86_max_cores >>1 ; - -/* even-numbered NB_id of this dual-node processor */ - n = c->phys_proc_id <<1 ; +/* store NodeID, use llc_shared_map to store sibling info */ +per_cpu (cpu_llc_id, cpu) = value &7 ; -/* -* determine internal node id and assign cores fifty-fifty to -* each node of the dual-node processor -*/ - t =read_pci_config (0 ,24 + n,3 ,0xe8 ); - n = (t>>30 ) &0x3 ; -if (n ==0 ) { -if (c->cpu_core_id < cpn) - n_id =0 ; -else - n_id =1 ; - }else { -if (c->cpu_core_id < cpn) - n_id =1 ; -else - n_id =0 ; - } -
arch/x86/kernel/cpu/amd.c static int __cpuinit nearby_node(int api · line 288
Quoted 10 lines
arch/x86/kernel/cpu/amd.c +2
-6-/* compute entire NodeID, use llc_shared_map to store sibling info */ -per_cpu (cpu_llc_id, cpu) = (c->phys_proc_id <<1 ) + n_id; - -/* fixup core id to be in range from 0 to cpn */ - c->cpu_core_id = c->cpu_core_id % cpn; -#endif +/* fixup core id to be in range from 0 to (cores_per_node - 1) */ + c->cpu_core_id = c->cpu_core_id % cores_per_node; }#endif
This patch is causing kernel panic on boot on Magny Cours CPU here (cpu family 16, model 9, stepping 1).
Please see screenshot from the paniced kernel on
http://www.jikos.cz/jikos/junk/screenshot.jpg
(sorry for bad quality of this screenshot, it was captured only from the IPMI/HTTP console so far, I will try to grab something better tomorrow)
Also this screenshot probably doesn't show the complete picture -- see the "end trace" marker on the very first line. I will try to have something better tomorrow, but maybe this rings bell for someone right away.
Signature · 2 lines
Jiri Kosina SUSE Labs, Novell Inc.
Re: [049/197] x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space
Quoted 3 lines · Jiri Kosina
Quoted 1 line · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
[...]
Quoted 6 lines
This patch is causing kernel panic on boot on Magny Cours CPU here (cpu family 16, model 9, stepping 1).
Please see screenshot from the paniced kernel on
Quoted 8 lines
http://www.jikos.cz/jikos/junk/screenshot.jpg
(sorry for bad quality of this screenshot, it was captured only from the IPMI/HTTP console so far, I will try to grab something better tomorrow)
Also this screenshot probably doesn't show the complete picture -- see the "end trace" marker on the very first line. I will try to have something better tomorrow, but maybe this rings bell for someone right away.
This looks like a BIOS issue to me. Obviously this is a pre-production test system where an old BIOS is installed. A BIOS update should fix this issue for you.
Regards,
Andreas
Signature · 5 lines
Operating | Advanced Micro Devices GmbH System | Karl-Hammerschmidt-Str. 34, 85609 Dornach b. München, Germany Research | Geschäftsführer: Andrew Bowd, Thomas M. McCoy, Giuliano Meroni Center | Sitz: Dornach, Gemeinde Aschheim, Landkreis München (OSRC) | Registergericht München, HRB Nr. 43632
Re: [049/197] x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space
Quoted 12 lines · Andreas Herrmann
Quoted 12 lines
Quoted 1 line
2.6.32-stable review patch. If anyone has any objections, please let us know.
This patch is causing kernel panic on boot on Magny Cours CPU here (cpu family 16, model 9, stepping 1).
Please see screenshot from the paniced kernel on
http://www.jikos.cz/jikos/junk/screenshot.jpg
(sorry for bad quality of this screenshot, it was captured only from the IPMI/HTTP console so far, I will try to grab something better tomorrow)
Quoted 7 lines
Quoted 3 lines
Also this screenshot probably doesn't show the complete picture -- see the "end trace" marker on the very first line. I will try to have something better tomorrow, but maybe this rings bell for someone right away.
This looks like a BIOS issue to me. Obviously this is a pre-production test system where an old BIOS is installed. A BIOS update should fix this issue for you.
I can confirm that on different Magny Cours system (16/9/1) with a newer BIOS, the NodeID is provided correctly via MSR, and the issue doesn't trigger.
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs, Novell Inc.
PATCH 50/197 resource: move kernel function inside __KERNEL__
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 96d07d211739fd2450ac54e81d00fa40fcd4b1bd upstream
From: Jiri Slaby <[email protected]>
resource: move kernel function inside __KERNEL__
It is an internal function. Move it inside __KERNEL__ ifdef, along with task_struct declaration.
Then we get:
#--- /usr/include/linux/resource.h 2009-09-14 15:09:29.000000000 +0200
#+++ usr/include/linux/resource.h 2010-01-04 11:30:54.000000000 +0100
#@@ -3,8 +3,6 @@
#
##include <linux/time.h>
#
#-struct task_struct;
#-
#/*
#* Resource control/accounting header file for linux
#*/
#@@ -70,6 +68,5 @@
#*/
##include <asm/resource.h>
#
#-int getrusage(struct task_struct *p, int who, struct rusage *ru); #
##endif
#
#***********
include/linux/Kbuild is untouched, since unifdef is run even on headers-y nowadays.
backport to 2.6.32 by maximilian attems <[email protected]> Patch commented out by gregkh due to quilt complaining.
--- include/linux/resource.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
include/linux/resource.h +6 -2
@@ -3,8 +3,6 @@#include <linux/time.h> -struct task_struct ; -/* * Resource control/accounting header file for linux */
@@ -70,6 +68,12 @@ struct rlimit {*/ #include <asm/resource.h> +#ifdef __KERNEL__ + +struct task_struct ; +int getrusage (struct task_struct *p,int who,struct rusage __user *ru); +#endif /* __KERNEL__ */ +#endif
PATCH 51/197 backlight: mbp_nvidia_bl - add five more MacBook variants
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Evan McClain <[email protected]>
commit 36bc5ee6a8d13333980fa54e97d3469d3d4cda98 upstream.
This adds the MacBook 1,1 2,1 3,1 4,1 and 4,2 to the DMI tables.
--- drivers/video/backlight/mbp_nvidia_bl.c | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
drivers/video/backlight/mbp_nvidia_bl.c +45 -0
@@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dmstatic const struct dmi_system_id __initdata mbp_device_table[] = { { .callback = mbp_dmi_match, + .ident ="MacBook 1,1" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"MacBook1,1" ), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident ="MacBook 2,1" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"MacBook2,1" ), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident ="MacBook 3,1" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"MacBook3,1" ), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident ="MacBook 4,1" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"MacBook4,1" ), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident ="MacBook 4,2" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"MacBook4,2" ), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, .ident ="MacBookPro 3,1" , .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"Apple Inc." ),
Re: [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 1 line · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
Apparently the MacBook1,1 reports the manufacturer as Apple Computer, Inc.
A patch was submitted here: http://lkml.org/lkml/2010/3/23/412
Steffen Röcker wasn't sure about the MacBook2,1 but according to sample dmidecode outputs:
http://www.mail-archive.com/[email protected]/msg07914.html
and
http://www.mail-archive.com/[email protected]/msg09304.html
for MacBook1,1 and MacBook2,1 systems respectively, MacBook2,1 reports as Apple Inc. as in my original patch.
Sorry for not catching this earlier.
Signature · 4 lines
Evan McClain Aerospace Engineering Graduate Student Senator . [email protected] ..:
Re: [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 15 lines · Evan McClain
Quoted 1 line · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
Apparently the MacBook1,1 reports the manufacturer as Apple Computer, Inc.
A patch was submitted here: http://lkml.org/lkml/2010/3/23/412
Steffen Röcker wasn't sure about the MacBook2,1 but according to sample dmidecode outputs:
http://www.mail-archive.com/[email protected]/msg07914.html
and
http://www.mail-archive.com/[email protected]/msg09304.html
for MacBook1,1 and MacBook2,1 systems respectively, MacBook2,1 reports as Apple Inc. as in my original patch.
Quoted 1 line
Sorry for not catching this earlier.
I don't understand, is this patch not correct? Should I drop it from the stable release?
thanks,
greg k-h
Re: [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 2 lines · Greg KH
I don't understand, is this patch not correct? Should I drop it from the stable release?
It is correct, but it will not match MacBook1,1s as intended due to apple changing vendor names.
Signature · 4 lines
Evan McClain Aerospace Engineering Graduate Student Senator . [email protected] ..:
Re: [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 6 lines · Evan McClain
Quoted 2 lines · Greg KH
I don't understand, is this patch not correct? Should I drop it from the stable release?
It is correct, but it will not match MacBook1,1s as intended due to apple changing vendor names.
And by correct, I mean it would be correct if it only claimed to add four MacBook variants instead of five.
Signature · 4 lines
Evan McClain Aerospace Engineering Graduate Student Senator . [email protected] ..:
Re: [Stable-review] [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 10 lines · Evan McClain
Quoted 6 lines · Evan McClain
Quoted 2 lines · Greg KH
I don't understand, is this patch not correct? Should I drop it from the stable release?
It is correct, but it will not match MacBook1,1s as intended due to apple changing vendor names.
And by correct, I mean it would be correct if it only claimed to add four MacBook variants instead of five.
I'm not sure I understand the implications either. The real question in my opinion is : is it better to keep this patch, to delay it or to drop it ?
Willy
Re: [Stable-review] [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 3 lines · Willy Tarreau
I'm not sure I understand the implications either. The real question in my opinion is : is it better to keep this patch, to delay it or to drop it ?
I'm afraid I'm not familiar with this whole process, but if the intention of the stable review is to only include perfectly correct code, I would suggest delaying until Steffen Röcker's patch could be included too.
As my patch currently stands, it will add support for only four of the claimed five MacBook models. Unless some other machine reports a product name of MacBook1,1 and a vendor of Apple Inc. and doesn't use an intel graphics card there should be no real issues with the patch as it stands other than claiming to support MacBook1,1.
Signature · 4 lines
Evan McClain Aerospace Engineering Graduate Student Senator . [email protected] ..:
Re: [stable] [Stable-review] [051/197] backlight: mbp_nvidia_bl - add five more MacBook variants
Quoted 10 lines · Evan McClain
Quoted 3 lines · Willy Tarreau
I'm not sure I understand the implications either. The real question in my opinion is : is it better to keep this patch, to delay it or to drop it ?
I'm afraid I'm not familiar with this whole process, but if the intention of the stable review is to only include perfectly correct code, I would suggest delaying until Steffen Röcker's patch could be included too.
Quoted 5 lines
As my patch currently stands, it will add support for only four of the claimed five MacBook models. Unless some other machine reports a product name of MacBook1,1 and a vendor of Apple Inc. and doesn't use an intel graphics card there should be no real issues with the patch as it stands other than claiming to support MacBook1,1.
It's ok, we'll leave the patch as-is.
thanks,
greg k-h
PATCH 52/197 KVM: x86 emulator: Add Virtual-8086 mode of emulation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gleb Natapov <[email protected]>
commit a0044755679f3e761b8b95995e5f2db2b7efd0f6 upstream
For some instructions CPU behaves differently for real-mode and virtual 8086. Let emulator know which mode cpu is in, so it will not poke into vcpu state directly.
--- arch/x86/include/asm/kvm_emulate.h | 1 + arch/x86/kvm/emulate.c | 14 +++++++------- arch/x86/kvm/x86.c | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-)
arch/x86/include/asm/kvm_emulate.h +1 -0
@@ -168,6 +168,7 @@ struct x86_emulate_ctxt {/* Execution mode, passed to the emulator. */ #define X86EMUL_MODE_REAL 0/* Real mode. */ +#define X86EMUL_MODE_VM86 1/* Virtual 8086 mode. */ #define X86EMUL_MODE_PROT16 2/* 16-bit protected mode. */ #define X86EMUL_MODE_PROT32 4/* 32-bit protected mode. */ #define X86EMUL_MODE_PROT64 8/* 64-bit (long) mode. */
arch/x86/kvm/emulate.c +7 -7
@@ -895,6 +895,7 @@ x86_decode_insn(struct x86_emulate_ctxtswitch (mode) {case X86EMUL_MODE_REAL : +case X86EMUL_MODE_VM86 :case X86EMUL_MODE_PROT16 : def_op_bytes = def_ad_bytes =2 ;break ;
@@ -1453,7 +1454,7 @@ emulate_syscall(struct x86_emulate_ctxt/* syscall is not available in real mode */ if (c->lock_prefix || ctxt->mode ==X86EMUL_MODE_REAL - || !(ctxt->vcpu->arch.cr0 &X86_CR0_PE )) + || ctxt->mode ==X86EMUL_MODE_VM86 )return -1 ;setup_syscalls_segments (ctxt, &cs, &ss);
@@ -1505,9 +1506,8 @@ emulate_sysenter(struct x86_emulate_ctxtif (c->lock_prefix)return -1 ; -/* inject #GP if in real mode or paging is disabled */ -if (ctxt->mode ==X86EMUL_MODE_REAL || - !(ctxt->vcpu->arch.cr0 &X86_CR0_PE )) { +/* inject #GP if in real mode */ +if (ctxt->mode ==X86EMUL_MODE_REAL ) {kvm_inject_gp (ctxt->vcpu,0 );return -1 ; }
@@ -1571,9 +1571,9 @@ emulate_sysexit(struct x86_emulate_ctxtif (c->lock_prefix)return -1 ; -/* inject #GP if in real mode or paging is disabled */ -if (ctxt->mode ==X86EMUL_MODE_REAL - || !(ctxt->vcpu->arch.cr0 &X86_CR0_PE )) { +/* inject #GP if in real mode or Virtual 8086 mode */ +if (ctxt->mode ==X86EMUL_MODE_REAL || + ctxt->mode ==X86EMUL_MODE_VM86 ) {kvm_inject_gp (ctxt->vcpu,0 );return -1 ; }
arch/x86/kvm/x86.c +2 -1
@@ -2828,8 +2828,9 @@ int emulate_instruction(struct kvm_vcpu vcpu->arch.emulate_ctxt.vcpu = vcpu; vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags (vcpu); vcpu->arch.emulate_ctxt.mode = + (!(vcpu->arch.cr0 &X86_CR0_PE )) ?X86EMUL_MODE_REAL : (vcpu->arch.emulate_ctxt.eflags &X86_EFLAGS_VM ) - ?X86EMUL_MODE_REAL : cs_l + ?X86EMUL_MODE_VM86 : cs_l ?X86EMUL_MODE_PROT64 : cs_db ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ;
PATCH 53/197 KVM: x86 emulator: fix memory access during x86 emulation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gleb Natapov <[email protected]>
commit 1871c6020d7308afb99127bba51f04548e7ca84e upstream
Currently when x86 emulator needs to access memory, page walk is done with broadest permission possible, so if emulated instruction was executed by userspace process it can still access kernel memory. Fix that by providing correct memory access to page walker during emulation.
--- arch/x86/include/asm/kvm_emulate.h | 14 +++ arch/x86/include/asm/kvm_host.h | 7 + arch/x86/kvm/emulate.c | 6 - arch/x86/kvm/mmu.c | 17 +--- arch/x86/kvm/mmu.h | 6 + arch/x86/kvm/paging_tmpl.h | 11 ++- arch/x86/kvm/x86.c | 131 ++++++++++++++++++++++++++++--------- 7 files changed, 142 insertions(+), 50 deletions(-)
arch/x86/include/asm/kvm_emulate.h +12 -2
@@ -54,13 +54,23 @@ struct x86_emulate_ctxt;struct x86_emulate_ops {/* * read_std: Read bytes of standard (non-emulated/special) memory. -* Used for instruction fetch, stack operations, and others. +* Used for descriptor reading. * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_std)(unsigned long addr,void *val, -unsigned int bytes,struct kvm_vcpu *vcpu); +unsigned int bytes,struct kvm_vcpu *vcpu,u32 *error); + +/* +* fetch: Read bytes of standard (non-emulated/special) memory. +* Used for instruction fetch. +* @addr: [IN ] Linear address from which to read. +* @val: [OUT] Value read from memory, zero-extended to 'u_long'. +* @bytes: [IN ] Number of bytes to read from memory. +*/ +int (*fetch)(unsigned long addr,void *val, +unsigned int bytes,struct kvm_vcpu *vcpu,u32 *error);/* * read_emulated: Read bytes from emulated/special memory area.
arch/x86/include/asm/kvm_host.h +6 -1
@@ -256,7 +256,8 @@ struct kvm_mmu {void (*new_cr3)(struct kvm_vcpu *vcpu);int (*page_fault)(struct kvm_vcpu *vcpu,gva_t gva,u32 err);void (*free)(struct kvm_vcpu *vcpu); -gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu,gva_t gva); +gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu,gva_t gva,u32 access, +u32 *error);void (*prefetch_page)(struct kvm_vcpu *vcpu,struct kvm_mmu_page *page); int (*sync_page)(struct kvm_vcpu *vcpu,
@@ -645,6 +646,10 @@ void __kvm_mmu_free_some_pages(struct kvint kvm_mmu_load (struct kvm_vcpu *vcpu);void kvm_mmu_unload (struct kvm_vcpu *vcpu);void kvm_mmu_sync_roots (struct kvm_vcpu *vcpu); +gpa_t kvm_mmu_gva_to_gpa_read (struct kvm_vcpu *vcpu,gva_t gva,u32 *error); +gpa_t kvm_mmu_gva_to_gpa_fetch (struct kvm_vcpu *vcpu,gva_t gva,u32 *error); +gpa_t kvm_mmu_gva_to_gpa_write (struct kvm_vcpu *vcpu,gva_t gva,u32 *error); +gpa_t kvm_mmu_gva_to_gpa_system (struct kvm_vcpu *vcpu,gva_t gva,u32 *error);int kvm_emulate_hypercall (struct kvm_vcpu *vcpu);
arch/x86/kvm/emulate.c +3 -3
@@ -612,7 +612,7 @@ static int do_fetch_insn_byte(struct x86if (linear < fc->start || linear >= fc->end) { size =min (15UL ,PAGE_SIZE -offset_in_page (linear)); - rc = ops->read_std (linear, fc->data, size, ctxt->vcpu); + rc = ops->fetch (linear, fc->data, size, ctxt->vcpu,NULL );if (rc)return rc; fc->start = linear;
@@ -667,11 +667,11 @@ static int read_descriptor(struct x86_em op_bytes =3 ; *address =0 ; rc = ops->read_std ((unsigned long )ptr, (unsigned long *)size,2 , - ctxt->vcpu); + ctxt->vcpu,NULL );if (rc)return rc; rc = ops->read_std ((unsigned long )ptr +2 , address, op_bytes, - ctxt->vcpu); + ctxt->vcpu,NULL );return rc; }
arch/x86/kvm/mmu.c +7 -10
@@ -136,12 +136,6 @@ module_param(oos_shadow, bool, 0644);#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ | PT64_NX_MASK) -#define PFERR_PRESENT_MASK (1U << 0) -#define PFERR_WRITE_MASK (1U << 1) -#define PFERR_USER_MASK (1U << 2) -#define PFERR_RSVD_MASK (1U << 3) -#define PFERR_FETCH_MASK (1U << 4) -#define PT_PDPE_LEVEL 3#define PT_DIRECTORY_LEVEL 2#define PT_PAGE_TABLE_LEVEL 1
@@ -1639,7 +1633,7 @@ struct page *gva_to_page(struct kvm_vcpu {struct page *page; -gpa_t gpa = vcpu->arch.mmu.gva_to_gpa (vcpu, gva); +gpa_t gpa =kvm_mmu_gva_to_gpa_read (vcpu, gva,NULL );if (gpa ==UNMAPPED_GVA )return NULL ;
@@ -2162,8 +2156,11 @@ void kvm_mmu_sync_roots(struct kvm_vcpuspin_unlock (&vcpu->kvm->mmu_lock); } -static gpa_t nonpaging_gva_to_gpa (struct kvm_vcpu *vcpu,gva_t vaddr) +static gpa_t nonpaging_gva_to_gpa (struct kvm_vcpu *vcpu,gva_t vaddr, +u32 access,u32 *error) { +if (error) + *error =0 ;return vaddr; }
@@ -2747,7 +2744,7 @@ int kvm_mmu_unprotect_page_virt(struct kif (tdp_enabled)return 0 ; - gpa = vcpu->arch.mmu.gva_to_gpa (vcpu, gva); + gpa =kvm_mmu_gva_to_gpa_read (vcpu, gva,NULL );spin_lock (&vcpu->kvm->mmu_lock); r =kvm_mmu_unprotect_page (vcpu->kvm, gpa >>PAGE_SHIFT );
@@ -3245,7 +3242,7 @@ static void audit_mappings_page(struct kif (is_shadow_present_pte (ent) && !is_last_spte (ent, level))audit_mappings_page (vcpu, ent, va, level -1 );else { -gpa_t gpa = vcpu->arch.mmu.gva_to_gpa (vcpu, va); +gpa_t gpa =kvm_mmu_gva_to_gpa_read (vcpu, va,NULL );gfn_t gfn = gpa >>PAGE_SHIFT ;pfn_t pfn =gfn_to_pfn (vcpu->kvm, gfn);hpa_t hpa = (hpa_t )pfn <<PAGE_SHIFT ;
arch/x86/kvm/mmu.h +6 -0
@@ -37,6 +37,12 @@#define PT32_ROOT_LEVEL 2#define PT32E_ROOT_LEVEL 3 +#define PFERR_PRESENT_MASK (1U << 0) +#define PFERR_WRITE_MASK (1U << 1) +#define PFERR_USER_MASK (1U << 2) +#define PFERR_RSVD_MASK (1U << 3) +#define PFERR_FETCH_MASK (1U << 4) +int kvm_mmu_get_spte_hierarchy (struct kvm_vcpu *vcpu,u64 addr,u64 sptes[4 ]);static inline void kvm_mmu_free_some_pages (struct kvm_vcpu *vcpu)
arch/x86/kvm/paging_tmpl.h +8 -3
@@ -491,18 +491,23 @@ static void FNAME(invlpg)(struct kvm_vcpspin_unlock (&vcpu->kvm->mmu_lock); } -static gpa_t FNAME (gva_to_gpa )(struct kvm_vcpu *vcpu,gva_t vaddr) +static gpa_t FNAME (gva_to_gpa )(struct kvm_vcpu *vcpu,gva_t vaddr,u32 access, +u32 *error) {struct guest_walker walker;gpa_t gpa =UNMAPPED_GVA ;int r; - r =FNAME (walk_addr)(&walker, vcpu, vaddr,0 ,0 ,0 ); + r =FNAME (walk_addr)(&walker, vcpu, vaddr, + !!(access &PFERR_WRITE_MASK ), + !!(access &PFERR_USER_MASK ), + !!(access &PFERR_FETCH_MASK ));if (r) { gpa =gfn_to_gpa (walker.gfn); gpa |= vaddr & ~PAGE_MASK ; - } + }else if (error) + *error = walker.error_code;return gpa; }
arch/x86/kvm/x86.c +100 -31
283 lines not on this page · raw message
PATCH 54/197 KVM: x86 emulator: Check IOPL level during io instruction emulation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gleb Natapov <[email protected]>
commit f850e2e603bf5a05b0aee7901857cf85715aa694 upstream
Make emulator check that vcpu is allowed to execute IN, INS, OUT, OUTS, CLI, STI.
--- arch/x86/include/asm/kvm_host.h | 1 arch/x86/kvm/emulate.c | 89 ++++++++++++++++++++++++++++++++++++---- arch/x86/kvm/x86.c | 10 +--- 3 files changed, 87 insertions(+), 13 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -663,6 +663,7 @@ void kvm_disable_tdp(void);int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3);int complete_pio (struct kvm_vcpu *vcpu); +bool kvm_check_iopl (struct kvm_vcpu *vcpu);struct kvm_memory_slot *gfn_to_memslot_unaliased (struct kvm *kvm,gfn_t gfn);
arch/x86/kvm/emulate.c +82 -7
121 lines not on this page · raw message
arch/x86/kvm/x86.c +4 -6
@@ -3079,6 +3079,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp {unsigned long val; +trace_kvm_pio (!in, port, size,1 ); + vcpu->run->exit_reason =KVM_EXIT_IO ; vcpu->run->io.direction = in ?KVM_EXIT_IO_IN :KVM_EXIT_IO_OUT ; vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3090,9 +3092,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp vcpu->arch.pio.down =0 ; vcpu->arch.pio.rep =0 ; -trace_kvm_pio (vcpu->run->io.direction ==KVM_EXIT_IO_OUT , port, - size,1 ); - val =kvm_register_read (vcpu,VCPU_REGS_RAX );memcpy (vcpu->arch.pio_data, &val,4 );
@@ -3111,6 +3110,8 @@ int kvm_emulate_pio_string(struct kvm_vcunsigned now, in_page;int ret =0 ; +trace_kvm_pio (!in, port, size, count); + vcpu->run->exit_reason =KVM_EXIT_IO ; vcpu->run->io.direction = in ?KVM_EXIT_IO_IN :KVM_EXIT_IO_OUT ; vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3122,9 +3123,6 @@ int kvm_emulate_pio_string(struct kvm_vc vcpu->arch.pio.down = down; vcpu->arch.pio.rep = rep; -trace_kvm_pio (vcpu->run->io.direction ==KVM_EXIT_IO_OUT , port, - size, count); -if (!count) { kvm_x86_ops->skip_emulated_instruction (vcpu);return 1 ;
PATCH 55/197 KVM: x86 emulator: Fix popf emulation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gleb Natapov <[email protected]>
commit d4c6a1549c056f1d817e8f6f2f97d8b44933472f upstream
POPF behaves differently depending on current CPU mode. Emulate correct logic to prevent guest from changing flags that it can't change otherwise.
--- arch/x86/kvm/emulate.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)
arch/x86/kvm/emulate.c +54 -1
@@ -339,11 +339,18 @@ static u32 group2_table[] = { };/* EFLAGS bit definitions. */ +#define EFLG_ID (1<<21) +#define EFLG_VIP (1<<20) +#define EFLG_VIF (1<<19) +#define EFLG_AC (1<<18)#define EFLG_VM (1<<17)#define EFLG_RF (1<<16) +#define EFLG_IOPL (3<<12) +#define EFLG_NT (1<<14)#define EFLG_OF (1<<11)#define EFLG_DF (1<<10)#define EFLG_IF (1<<9) +#define EFLG_TF (1<<8)#define EFLG_SF (1<<7)#define EFLG_ZF (1<<6)#define EFLG_AF (1<<4)
@@ -1205,6 +1212,49 @@ static int emulate_pop(struct x86_emulatreturn rc; } +static int emulate_popf (struct x86_emulate_ctxt *ctxt, +struct x86_emulate_ops *ops, +void *dest,int len) +{ +int rc; +unsigned long val, change_mask; +int iopl = (ctxt->eflags &X86_EFLAGS_IOPL ) >>IOPL_SHIFT ; +int cpl = kvm_x86_ops->get_cpl (ctxt->vcpu); + + rc =emulate_pop (ctxt, ops, &val, len); +if (rc !=X86EMUL_CONTINUE ) +return rc; + + change_mask =EFLG_CF |EFLG_PF |EFLG_AF |EFLG_ZF |EFLG_SF |EFLG_OF + |EFLG_TF |EFLG_DF |EFLG_NT |EFLG_RF |EFLG_AC |EFLG_ID ; + +switch (ctxt->mode) { +case X86EMUL_MODE_PROT64 : +case X86EMUL_MODE_PROT32 : +case X86EMUL_MODE_PROT16 : +if (cpl ==0 ) + change_mask |=EFLG_IOPL ; +if (cpl <= iopl) + change_mask |=EFLG_IF ; +break ; +case X86EMUL_MODE_VM86 : +if (iopl <3 ) { +kvm_inject_gp (ctxt->vcpu,0 ); +return X86EMUL_PROPAGATE_FAULT ; + } + change_mask |=EFLG_IF ; +break ; +default :/* real mode */ + change_mask |= (EFLG_IOPL |EFLG_IF ); +break ; + } + + *(unsigned long *)dest = + (ctxt->eflags & ~change_mask) | (val & change_mask); + +return rc; +} +static inline int emulate_grp1a (struct x86_emulate_ctxt *ctxt,struct x86_emulate_ops *ops) {
@@ -1995,7 +2045,10 @@ special_insn: c->dst.type =OP_REG ; c->dst.ptr = (unsigned long *) &ctxt->eflags; c->dst.bytes = c->op_bytes; - goto pop_instruction; + rc =emulate_popf (ctxt, ops, &c->dst.val, c->op_bytes); +if (rc !=X86EMUL_CONTINUE ) + goto done; +break ; case 0xa0 ... 0xa1: /* mov */ c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX ]; c->dst.val = c->src.val;
PATCH 56/197 KVM: Fix segment descriptor loading
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gleb Natapov <[email protected]>
commit c697518a861e6c43b92b848895f9926580ee63c3 upstream
Add proper error and permission checking. This patch also change task switching code to load segment selectors before segment descriptors, like SDM requires, otherwise permission checking during segment descriptor loading will be incorrect.
--- arch/x86/include/asm/kvm_host.h | 3 arch/x86/kvm/emulate.c | 28 +----- arch/x86/kvm/x86.c | 173 ++++++++++++++++++++++++++++++++++------ 3 files changed, 158 insertions(+), 46 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -2
@@ -602,8 +602,7 @@ int emulator_set_dr(struct x86_emulate_c unsigned long value);void kvm_get_segment (struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg); -int kvm_load_segment_descriptor (struct kvm_vcpu *vcpu,u16 selector, -int type_bits,int seg); +int kvm_load_segment_descriptor (struct kvm_vcpu *vcpu,u16 selector,int seg);int kvm_task_switch (struct kvm_vcpu *vcpu,u16 tss_selector,int reason);
arch/x86/kvm/emulate.c +7 -21
@@ -1396,7 +1396,7 @@ static int emulate_ret_far(struct x86_em rc =emulate_pop (ctxt, ops, &cs, c->op_bytes);if (rc)return rc; - rc =kvm_load_segment_descriptor (ctxt->vcpu, (u16 )cs,1 ,VCPU_SREG_CS ); + rc =kvm_load_segment_descriptor (ctxt->vcpu, (u16 )cs,VCPU_SREG_CS );return rc; }
@@ -1992,12 +1992,11 @@ special_insn:break ;case 0x8e : {/* mov seg, r/m16 */ uint16_t sel; -int type_bits; -int err; sel = c->src.val; -if (c->modrm_reg ==VCPU_SREG_CS ) { +if (c->modrm_reg ==VCPU_SREG_CS || + c->modrm_reg >VCPU_SREG_GS ) {kvm_queue_exception (ctxt->vcpu,UD_VECTOR ); goto done; }
@@ -2005,18 +2004,7 @@ special_insn:if (c->modrm_reg ==VCPU_SREG_SS )toggle_interruptibility (ctxt,X86_SHADOW_INT_MOV_SS ); -if (c->modrm_reg <=5 ) { - type_bits = (c->modrm_reg ==1 ) ?9 :1 ; - err =kvm_load_segment_descriptor (ctxt->vcpu, sel, - type_bits, c->modrm_reg); - }else { -printk (KERN_INFO "Invalid segreg in modrm byte 0x%02x\n" , - c->modrm); - goto cannot_emulate; - } - -if (err <0 ) - goto cannot_emulate; + rc =kvm_load_segment_descriptor (ctxt->vcpu, sel, c->modrm_reg); c->dst.type =OP_NONE ;/* Disable writeback. */ break ;
@@ -2186,11 +2174,9 @@ special_insn:case 0xe9 :/* jmp rel */ goto jmp;case 0xea :/* jmp far */ -if (kvm_load_segment_descriptor (ctxt->vcpu, c->src2.val,9 , -VCPU_SREG_CS ) <0 ) { -DPRINTF ("jmp far: Failed to load CS descriptor\n" ); - goto cannot_emulate; - } +if (kvm_load_segment_descriptor (ctxt->vcpu, c->src2.val, +VCPU_SREG_CS )) + goto done; c->eip = c->src.val;break ;
arch/x86/kvm/x86.c +150 -23
231 lines not on this page · raw message
PATCH 57/197 KVM: VMX: Update instruction length on intercepted BP
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jan Kiszka <[email protected]>
commit c573cd22939e54fc1b8e672054a505048987a7cb upstream
We intercept #BP while in guest debugging mode. As VM exits due to intercepted exceptions do not necessarily come with valid idt_vectoring, we have to update event_exit_inst_len explicitly in such cases. At least in the absence of migration, this ensures that re-injections of #BP will find and use the correct instruction length.
--- arch/x86/kvm/vmx.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/x86/kvm/vmx.c +13 -0
@@ -2674,6 +2674,12 @@ static int handle_rmode_exception(structkvm_queue_exception (vcpu, vec);return 1 ;case BP_VECTOR : +/* +* Update instruction length as we may reinject the exception +* from user space while in guest debugging mode. +*/ +to_vmx (vcpu)->vcpu.arch.event_exit_inst_len = +vmcs_read32 (VM_EXIT_INSTRUCTION_LEN );if (vcpu->guest_debug &KVM_GUESTDBG_USE_SW_BP )return 0 ;/* fall through */
@@ -2790,6 +2796,13 @@ static int handle_exception(struct kvm_v kvm_run->debug.arch.dr7 =vmcs_readl (GUEST_DR7 );/* fall through */ case BP_VECTOR : +/* +* Update instruction length as we may reinject #BP from +* user space while in guest debugging mode. Reading it for +* #DB as well causes no harm, it is not used in that case. +*/ + vmx->vcpu.arch.event_exit_inst_len = +vmcs_read32 (VM_EXIT_INSTRUCTION_LEN ); kvm_run->exit_reason =KVM_EXIT_DEBUG ; kvm_run->debug.arch.pc =vmcs_readl (GUEST_CS_BASE ) + rip; kvm_run->debug.arch.exception = ex_no;
PATCH 58/197 KVM: VMX: Use macros instead of hex value on cr0 initialization
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eduardo Habkost <[email protected]>
commit fa40052ca04bdbbeb20b839cc8ffe9fa7beefbe9 upstream
This should have no effect, it is just to make the code clearer.
--- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/vmx.c +1 -1
@@ -2510,7 +2510,7 @@ static int vmx_vcpu_reset(struct kvm_vcpif (vmx->vpid !=0 )vmcs_write16 (VIRTUAL_PROCESSOR_ID , vmx->vpid); - vmx->vcpu.arch.cr0 =0x60000010 ; + vmx->vcpu.arch.cr0 =X86_CR0_NW |X86_CR0_CD |X86_CR0_ET ;vmx_set_cr0 (&vmx->vcpu, vmx->vcpu.arch.cr0);/* enter rmode */ vmx_set_cr4 (&vmx->vcpu,0 );vmx_set_efer (&vmx->vcpu,0 );
PATCH 59/197 KVM: SVM: Reset cr0 properly on vcpu reset
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eduardo Habkost <[email protected]>
commit 18fa000ae453767b59ab97477925895a3f0c46ea upstream
svm_vcpu_reset() was not properly resetting the contents of the guest-visible cr0 register, causing the following issue:
https://bugzilla.redhat.com/show_bug.cgi?id=525699
Without resetting cr0 properly, the vcpu was running the SIPI bootstrap routine with paging enabled, making the vcpu get a pagefault exception while trying to run it.
Instead of setting vmcb->save.cr0 directly, the new code just resets kvm->arch.cr0 and calls kvm_set_cr0(). The bits that were set/cleared on vmcb->save.cr0 (PG, WP, !CD, !NW) will be set properly by svm_set_cr0().
kvm_set_cr0() is used instead of calling svm_set_cr0() directly to make sure kvm_mmu_reset_context() is called to reset the mmu to nonpaging mode.
--- arch/x86/kvm/svm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/x86/kvm/svm.c +5 -4
@@ -625,11 +625,12 @@ static void init_vmcb(struct vcpu_svm *s save->rip =0x0000fff0 ; svm->vcpu.arch.regs[VCPU_REGS_RIP ] = save->rip; -/* -* cr0 val on cpu init should be 0x60000010, we enable cpu -* cache by default. the orderly way is to enable cache in bios. +/* This is the guest-visible cr0 value. +* svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. */ - save->cr0 =0x00000010 |X86_CR0_PG |X86_CR0_WP ; + svm->vcpu.arch.cr0 =X86_CR0_NW |X86_CR0_CD |X86_CR0_ET ; +kvm_set_cr0 (&svm->vcpu, svm->vcpu.arch.cr0); + save->cr4 =X86_CR4_PAE ;/* rdx = ?? */
PATCH 60/197 KVM: VMX: Disable unrestricted guest when EPT disabled
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sheng Yang <[email protected]>
commit 046d87103addc117f0d397196e85189722d4d7de upstream
Otherwise would cause VMEntry failure when using ept=0 on unrestricted guest supported processors.
--- arch/x86/kvm/vmx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx.c +3 -1
@@ -2302,8 +2302,10 @@ static int vmx_vcpu_setup(struct vcpu_vm ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES ;if (vmx->vpid ==0 ) exec_control &= ~SECONDARY_EXEC_ENABLE_VPID ; -if (!enable_ept) +if (!enable_ept) { exec_control &= ~SECONDARY_EXEC_ENABLE_EPT ; + enable_unrestricted_guest =0 ; + }if (!enable_unrestricted_guest) exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST ;vmcs_write32 (SECONDARY_VM_EXEC_CONTROL , exec_control);
PATCH 61/197 KVM: x86: disable paravirt mmu reporting
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Marcelo Tosatti <[email protected]>
commit a68a6a7282373bedba8a2ed751b6384edb983a64 upstream
Disable paravirt MMU capability reporting, so that new (or rebooted) guests switch to native operation.
Paravirt MMU is a burden to maintain and does not bring significant advantages compared to shadow anymore.
--- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +2 -2
@@ -1242,8 +1242,8 @@ int kvm_dev_ioctl_check_extension(long ecase KVM_CAP_NR_MEMSLOTS : r =KVM_MEMORY_SLOTS ;break ; -case KVM_CAP_PV_MMU : - r = !tdp_enabled; +case KVM_CAP_PV_MMU :/* obsolete */ + r =0 ;break ;case KVM_CAP_IOMMU : r =iommu_found ();
PATCH 62/197 pata_via: Add VIA VX900 support
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: [email protected] <[email protected]>
commit 4f1deba435ef75380c1d06fda860c7a15ea16fdf upstream.
--- drivers/ata/pata_via.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/pata_via.c +1 -0
@@ -661,6 +661,7 @@ static const struct pci_device_id via[] { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE }, + { PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE }, { }, };
PATCH 63/197 ext3: Dont update the superblock in ext3_statfs()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Sandeen <[email protected]>
commit b918397542388de75bd86c32fbfa820e5d629fa9 upstream.
commit a71ce8c6c9bf269b192f352ea555217815cf027e updated ext3_statfs() to update the on-disk superblock counters, but modified this buffer directly without any journaling of the change. This is one of the accesses that was causing the crc errors in journal replay as seen in kernel.org bugzilla #14354.
The modifications were originally to keep the sb "more" in sync, so that a readonly fsck of the device didn't flag this as an error (as often), but apparently e2fsprogs deals with this differently now, anyway.
Based on Ted's patch for ext4, which was in turn based on my work on that bug and another preliminary patch...
--- fs/ext3/super.c | 2 -- 1 file changed, 2 deletions(-)
fs/ext3/super.c +0 -2
@@ -2686,13 +2686,11 @@ static int ext3_statfs (struct dentry * buf->f_bsize = sb->s_blocksize; buf->f_blocks =le32_to_cpu (es->s_blocks_count) - sbi->s_overhead_last; buf->f_bfree =percpu_counter_sum_positive (&sbi->s_freeblocks_counter); - es->s_free_blocks_count =cpu_to_le32 (buf->f_bfree); buf->f_bavail = buf->f_bfree -le32_to_cpu (es->s_r_blocks_count);if (buf->f_bfree <le32_to_cpu (es->s_r_blocks_count)) buf->f_bavail =0 ; buf->f_files =le32_to_cpu (es->s_inodes_count); buf->f_ffree =percpu_counter_sum_positive (&sbi->s_freeinodes_counter); - es->s_free_inodes_count =cpu_to_le32 (buf->f_ffree); buf->f_namelen =EXT3_NAME_LEN ; fsid =le64_to_cpup ((void *)es->s_uuid) ^le64_to_cpup ((void *)es->s_uuid +sizeof (u64));
PATCH 64/197 ext3: journal all modifications in ext3_xattr_set_handle
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Sandeen <[email protected]>
commit d965736b8cb42ae51ba9c3f13488035a98d025c6 upstream.
ext3_xattr_set_handle() was zeroing out an inode outside of journaling constraints; this is one of the accesses that was causing the crc errors in journal replay as seen in kernel.org bugzilla #14354.
Although ext3 doesn't have the crc issue, modifications out of journal control are a Bad Thing.
--- fs/ext3/xattr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/ext3/xattr.c +4 -3
@@ -960,6 +960,10 @@ ext3_xattr_set_handle(handle_t *handle,if (error) goto cleanup; + error =ext3_journal_get_write_access (handle, is.iloc.bh); +if (error) + goto cleanup; +if (EXT3_I (inode)->i_state &EXT3_STATE_NEW ) {struct ext3_inode *raw_inode =ext3_raw_inode (&is.iloc);memset (raw_inode,0 ,EXT3_SB (inode->i_sb)->s_inode_size);
@@ -985,9 +989,6 @@ ext3_xattr_set_handle(handle_t *handle,if (flags &XATTR_CREATE ) goto cleanup; } - error =ext3_journal_get_write_access (handle, is.iloc.bh); -if (error) - goto cleanup;if (!value) {if (!is.s.not_found) error =ext3_xattr_ibody_set (handle, inode, &i, &is);
PATCH 65/197 thinkpad-acpi: fix some version quirks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 90765c6aee568137521ba19347c744b5abde8161 upstream.
Update some of the BIOS/EC version quirks.
--- drivers/platform/x86/thinkpad_acpi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +3 -3
@@ -1779,7 +1779,7 @@ static const struct tpacpi_quirk tpacpi_TPV_QL1 ('7' ,'9' ,'E' ,'3' ,'5' ,'0' ),/* T60/p */ TPV_QL1 ('7' ,'C' ,'D' ,'2' ,'2' ,'2' ),/* R60, R60i */ -TPV_QL0 ('7' ,'E' ,'D' ,'0' ),/* R60e, R60i */ +TPV_QL1 ('7' ,'E' ,'D' ,'0' ,'1' ,'5' ),/* R60e, R60i */ /* BIOS FW BIOS VERS EC FW EC VERS */ TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */
@@ -1795,8 +1795,8 @@ static const struct tpacpi_quirk tpacpi_TPV_QI1 ('7' ,'4' ,'6' ,'4' ,'2' ,'7' ),/* X41 (0) */ TPV_QI1 ('7' ,'5' ,'6' ,'0' ,'2' ,'0' ),/* X41t (0) */ -TPV_QL0 ('7' ,'B' ,'D' ,'7' ),/* X60/s */ -TPV_QL0 ('7' ,'J' ,'3' ,'0' ),/* X60t */ +TPV_QL1 ('7' ,'B' ,'D' ,'7' ,'4' ,'0' ),/* X60/s */ +TPV_QL1 ('7' ,'J' ,'3' ,'0' ,'1' ,'3' ),/* X60t */ /* (0) - older versions lack DMI EC fw string and functionality */ /* (1) - older versions known to lack functionality */
PATCH 66/197 thinkpad-acpi: issue backlight class events
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 347a26860e2293b1347996876d3550499c7bb31f upstream.
Take advantage of the new events capabilities of the backlight class to notify userspace of backlight changes.
This depends on "backlight: Allow drivers to update the core, and generate events on changes", by Matthew Garrett.
--- Documentation/laptops/thinkpad-acpi.txt | 51 +++++++------------------------- drivers/platform/x86/thinkpad_acpi.c | 24 ++++++++++++++- 2 files changed, 35 insertions(+), 40 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +12 -39
@@ -460,6 +460,8 @@ event code Key Notes For Lenovo ThinkPads with a new BIOS, it has to be handled either by the ACPI OSI, or by userspace. + The driver does the right thing, + never mess with this. 0x1011 0x10 FN+END Brightness down. See brightness up for details.
@@ -582,46 +584,15 @@ with hotkey_report_mode. Brightness hotkey notes: -These are the current sane choices for brightness key mapping in -thinkpad-acpi: +Don't mess with the brightness hotkeys in a Thinkpad. If you want +notifications for OSD, use the sysfs backlight class event support. -For IBM and Lenovo models *without* ACPI backlight control (the ones on -which thinkpad-acpi will autoload its backlight interface by default, -and on which ACPI video does not export a backlight interface): - -1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as - these older firmware versions unfortunately won't respect the hotkey - mask for brightness keys anyway, and always reacts to them. This - usually work fine, unless X.org drivers are doing something to block - the BIOS. In that case, use (3) below. This is the default mode of - operation. - -2. Enable the hotkeys, but map them to something else that is NOT - KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause - userspace to try to change the backlight level, and use that as an - on-screen-display hint. - -3. IF AND ONLY IF X.org drivers find a way to block the firmware from - automatically changing the brightness, enable the hotkeys and map - them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to - something that calls xbacklight. thinkpad-acpi will not be able to - change brightness in that case either, so you should disable its - backlight interface. - -For Lenovo models *with* ACPI backlight control: - -1. Load up ACPI video and use that. ACPI video will report ACPI - events for brightness change keys. Do not mess with thinkpad-acpi - defaults in this case. thinkpad-acpi should not have anything to do - with backlight events in a scenario where ACPI video is loaded: - brightness hotkeys must be disabled, and the backlight interface is - to be kept disabled as well. This is the default mode of operation. - -2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, - and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process - these keys on userspace somehow (e.g. by calling xbacklight). - The driver will do this automatically if it detects that ACPI video - has been disabled. +The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events +automatically for the cases were userspace has to do something to +implement brightness changes. When you override these events, you will +either fail to handle properly the ThinkPads that require explicit +action to change backlight brightness, or the ThinkPads that require +that no action be taken to work properly. Bluetooth
@@ -1465,3 +1436,5 @@ Sysfs interface changelog: and it is always able to disable hot keys. Very old thinkpads are properly supported. hotkey_bios_mask is deprecated and marked for removal. + +0x020600: Marker for backlight change event support.
drivers/platform/x86/thinkpad_acpi.c +23 -1
@@ -22,7 +22,7 @@*/ #define TPACPI_VERSION "0.23" -#define TPACPI_SYSFS_VERSION 0x020500 +#define TPACPI_SYSFS_VERSION 0x020600/* * Changelog:
@@ -6083,6 +6083,12 @@ static int brightness_get(struct backligreturn status &TP_EC_BACKLIGHT_LVLMSK ; } +static void tpacpi_brightness_notify_change (void ) +{ +backlight_force_update (ibm_backlight_device, +BACKLIGHT_UPDATE_HOTKEY ); +} +static struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status,
@@ -6237,6 +6243,12 @@ static int __init brightness_init(struct ibm_backlight_device->props.brightness = b &TP_EC_BACKLIGHT_LVLMSK ;backlight_update_status (ibm_backlight_device); +vdbg_printk (TPACPI_DBG_INIT |TPACPI_DBG_BRGHT , +"brightness: registering brightness hotkeys " +"as change notification\n" ); +tpacpi_hotkey_driver_mask_set (hotkey_driver_mask + |TP_ACPI_HKEY_BRGHTUP_MASK + |TP_ACPI_HKEY_BRGHTDWN_MASK );;return 0 ; }
@@ -6313,6 +6325,9 @@ static int brightness_write(char *buf)* Doing it this way makes the syscall restartable in case of EINTR */ rc =brightness_set (level); +if (!rc && ibm_backlight_device) +backlight_force_update (ibm_backlight_device, +BACKLIGHT_UPDATE_SYSFS );return (rc == -EINTR )? -ERESTARTSYS : rc; }
@@ -7712,6 +7727,13 @@ static struct ibm_struct fan_driver_data*/ static void tpacpi_driver_event (const unsigned int hkey_event) { +if (ibm_backlight_device) { +switch (hkey_event) { +case TP_HKEY_EV_BRGHT_UP : +case TP_HKEY_EV_BRGHT_DOWN : +tpacpi_brightness_notify_change (); + } + } }
PATCH 67/197 thinkpad-acpi: silence bogus complain during rmmod
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 6b30eb7d211840ba1a03f855d9e7b80a921368f2 upstream.
Fix this bogus warning during module shutdown, when backlight event reporting is enabled:
"thinkpad_acpi: required events 0x00018000 not enabled!"
--- drivers/platform/x86/thinkpad_acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/platform/x86/thinkpad_acpi.c +2 -1
@@ -2190,7 +2190,8 @@ static int hotkey_mask_set(u32 mask) fwmask, hotkey_acpi_mask); } -hotkey_mask_warn_incomplete_mask (); +if (tpacpi_lifecycle !=TPACPI_LIFE_EXITING ) +hotkey_mask_warn_incomplete_mask ();return rc; }
PATCH 68/197 thinkpad-acpi: adopt input device
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit d112ef95d4ec1ee7fe7123e3f21e4aac0d57570c upstream.
Properly init the parent field of the input device. Thanks to Alan Jenkins, who noted this problem in a different driver.
--- drivers/platform/x86/thinkpad_acpi.c | 1 + 1 file changed, 1 insertion(+)
drivers/platform/x86/thinkpad_acpi.c +1 -0
@@ -8385,6 +8385,7 @@ static int __init thinkpad_acpi_module_iPCI_VENDOR_ID_IBM ; tpacpi_inputdev->id.product =TPACPI_HKEY_INPUT_PRODUCT ; tpacpi_inputdev->id.version =TPACPI_HKEY_INPUT_VERSION ; + tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; }for (i =0 ; i <ARRAY_SIZE (ibms_init); i++) { ret =ibm_init (&ibms_init[i]);
PATCH 69/197 thinkpad-acpi: expose module parameters
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit b09c72259e88cec3d602aef987a3209297f3a9c2 upstream.
Export the normal (non-command) module paramenters as mode 0444, so that they will show up in sysfs.
These parameters must not be changed at runtime as a rule, with very few exceptions.
--- drivers/platform/x86/thinkpad_acpi.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +10 -10
@@ -8126,32 +8126,32 @@ static int __init set_ibm_param(const chreturn -EINVAL ; } -module_param (experimental, int,0 ); +module_param (experimental, int,0444 );MODULE_PARM_DESC (experimental,"Enables experimental features when non-zero" );module_param_named (debug, dbg_level, uint,0 );MODULE_PARM_DESC (debug,"Sets debug level bit-mask" ); -module_param (force_load, bool,0 ); +module_param (force_load, bool,0444 );MODULE_PARM_DESC (force_load,"Attempts to load the driver even on a " "mis-identified ThinkPad when true" ); -module_param_named (fan_control, fan_control_allowed, bool,0 ); +module_param_named (fan_control, fan_control_allowed, bool,0444 );MODULE_PARM_DESC (fan_control,"Enables setting fan parameters features when true" ); -module_param_named (brightness_mode, brightness_mode, uint,0 ); +module_param_named (brightness_mode, brightness_mode, uint,0444 );MODULE_PARM_DESC (brightness_mode,"Selects brightness control strategy: " "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM" ); -module_param (brightness_enable, uint,0 ); +module_param (brightness_enable, uint,0444 );MODULE_PARM_DESC (brightness_enable,"Enables backlight control when 1, disables when 0" ); -module_param (hotkey_report_mode, uint,0 ); +module_param (hotkey_report_mode, uint,0444 );MODULE_PARM_DESC (hotkey_report_mode,"used for backwards compatibility with userspace, " "see documentation" );
@@ -8174,25 +8174,25 @@ TPACPI_PARAM(volume);TPACPI_PARAM (fan);#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES -module_param (dbg_wlswemul, uint,0 ); +module_param (dbg_wlswemul, uint,0444 );MODULE_PARM_DESC (dbg_wlswemul,"Enables WLSW emulation" );module_param_named (wlsw_state, tpacpi_wlsw_emulstate, bool,0 );MODULE_PARM_DESC (wlsw_state,"Initial state of the emulated WLSW switch" ); -module_param (dbg_bluetoothemul, uint,0 ); +module_param (dbg_bluetoothemul, uint,0444 );MODULE_PARM_DESC (dbg_bluetoothemul,"Enables bluetooth switch emulation" );module_param_named (bluetooth_state, tpacpi_bluetooth_emulstate, bool,0 );MODULE_PARM_DESC (bluetooth_state,"Initial state of the emulated bluetooth switch" ); -module_param (dbg_wwanemul, uint,0 ); +module_param (dbg_wwanemul, uint,0444 );MODULE_PARM_DESC (dbg_wwanemul,"Enables WWAN switch emulation" );module_param_named (wwan_state, tpacpi_wwan_emulstate, bool,0 );MODULE_PARM_DESC (wwan_state,"Initial state of the emulated WWAN switch" ); -module_param (dbg_uwbemul, uint,0 ); +module_param (dbg_uwbemul, uint,0444 );MODULE_PARM_DESC (dbg_uwbemul,"Enables UWB switch emulation" );module_param_named (uwb_state, tpacpi_uwb_emulstate, bool,0 ); MODULE_PARM_DESC(uwb_state,
PATCH 70/197 thinkpad-acpi: log temperatures on termal alarm (v2)
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 9ebd9e833648745fa5ac6998b9e0153ccd3ba839 upstream.
Log temperatures on any of the EC thermal alarms. It could be useful to help tracking down what is happening...
--- drivers/platform/x86/thinkpad_acpi.c | 57 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +45 -12
@@ -3548,49 +3548,57 @@ static bool hotkey_notify_usrevent(const } } +static void thermal_dump_all_sensors (void ); +static bool hotkey_notify_thermal (const u32 hkey,bool *send_acpi_ev,bool *ignore_acpi_ev) { +bool known = true; +/* 0x6000-0x6FFF: thermal alarms */ *send_acpi_ev = true; *ignore_acpi_ev = false;switch (hkey) { +case TP_HKEY_EV_THM_TABLE_CHANGED : +printk (TPACPI_INFO +"EC reports that Thermal Table has changed\n" ); +/* recommended action: do nothing, we don't have +* Lenovo ATM information */ +return true;case TP_HKEY_EV_ALARM_BAT_HOT :printk (TPACPI_CRIT "THERMAL ALARM: battery is too hot!\n" );/* recommended action: warn user through gui */ -return true; +break ;case TP_HKEY_EV_ALARM_BAT_XHOT :printk (TPACPI_ALERT "THERMAL EMERGENCY: battery is extremely hot!\n" );/* recommended action: immediate sleep/hibernate */ -return true; +break ;case TP_HKEY_EV_ALARM_SENSOR_HOT :printk (TPACPI_CRIT "THERMAL ALARM: " "a sensor reports something is too hot!\n" );/* recommended action: warn user through gui, that */ /* some internal component is too hot */ -return true; +break ;case TP_HKEY_EV_ALARM_SENSOR_XHOT :printk (TPACPI_ALERT "THERMAL EMERGENCY: " "a sensor reports something is extremely hot!\n" );/* recommended action: immediate sleep/hibernate */ -return true; -case TP_HKEY_EV_THM_TABLE_CHANGED : -printk (TPACPI_INFO -"EC reports that Thermal Table has changed\n" ); -/* recommended action: do nothing, we don't have -* Lenovo ATM information */ -return true; +break ;default :printk (TPACPI_ALERT "THERMAL ALERT: unknown thermal alarm received\n" ); -return false; + known = false; } + +thermal_dump_all_sensors (); + +return known; }static void hotkey_notify (struct ibm_struct *ibm,u32 event)
@@ -5472,8 +5480,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */TP_EC_THERMAL_TMP0 =0x78 ,/* ACPI EC regs TMP 0..7 */ TP_EC_THERMAL_TMP8 =0xC0 ,/* ACPI EC regs TMP 8..15 */ TP_EC_THERMAL_TMP_NA =-128 ,/* ACPI EC sensor not available */ + + TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */ }; +#define TPACPI_MAX_THERMAL_SENSORS 16/* Max thermal sensors supported */ struct ibm_thermal_sensors_struct { s32 temp[TPACPI_MAX_THERMAL_SENSORS];
@@ -5563,6 +5574,28 @@ static int thermal_get_sensors(struct ibreturn n; } +static void thermal_dump_all_sensors (void ) +{ +int n, i; +struct ibm_thermal_sensors_struct t; + + n =thermal_get_sensors (&t); +if (n <=0 ) +return ; + +printk (TPACPI_NOTICE +"temperatures (Celsius):" ); + +for (i =0 ; i < n; i++) { +if (t.temp[i] !=TPACPI_THERMAL_SENSOR_NA ) +printk (KERN_CONT " %d" , (int )(t.temp[i] /1000 )); +else +printk (KERN_CONT " N/A" ); + } + +printk (KERN_CONT "\n" ); +} +/* sysfs temp##_input -------------------------------------------------- */ static ssize_t thermal_temp_input_show(struct device *dev,
@@ -5578,7 +5611,7 @@ static ssize_t thermal_temp_input_show(s res =thermal_get_sensor (idx, &value);if (res)return res; -if (value ==TP_EC_THERMAL_TMP_NA *1000 ) +if (value ==TPACPI_THERMAL_SENSOR_NA )return -ENXIO ;return snprintf (buf,PAGE_SIZE ,"%d\n" , value);
PATCH 71/197 thinkpad-acpi: use input_set_capability
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 792979c8032b8f5adb77ea986db7082fff04c8e7 upstream.
Use input_set_capability() instead of set_bit.
--- drivers/platform/x86/thinkpad_acpi.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +5 -9
@@ -3350,16 +3350,14 @@ static int __init hotkey_init(struct ibm TPACPI_HOTKEY_MAP_SIZE); } -set_bit (EV_KEY , tpacpi_inputdev->evbit); -set_bit (EV_MSC , tpacpi_inputdev->evbit); -set_bit (MSC_SCAN , tpacpi_inputdev->mscbit); +input_set_capability (tpacpi_inputdev,EV_MSC ,MSC_SCAN ); tpacpi_inputdev->keycodesize =TPACPI_HOTKEY_MAP_TYPESIZE ; tpacpi_inputdev->keycodemax =TPACPI_HOTKEY_MAP_LEN ; tpacpi_inputdev->keycode = hotkey_keycode_map;for (i =0 ; i <TPACPI_HOTKEY_MAP_LEN ; i++) {if (hotkey_keycode_map[i] !=KEY_RESERVED ) { -set_bit (hotkey_keycode_map[i], - tpacpi_inputdev->keybit); +input_set_capability (tpacpi_inputdev,EV_KEY , + hotkey_keycode_map[i]); }else {if (i <sizeof (hotkey_reserved_mask)*8 ) hotkey_reserved_mask |=1 << i;
@@ -3367,12 +3365,10 @@ static int __init hotkey_init(struct ibm }if (tp_features.hotkey_wlsw) { -set_bit (EV_SW , tpacpi_inputdev->evbit); -set_bit (SW_RFKILL_ALL , tpacpi_inputdev->swbit); +input_set_capability (tpacpi_inputdev,EV_SW ,SW_RFKILL_ALL ); }if (tp_features.hotkey_tablet) { -set_bit (EV_SW , tpacpi_inputdev->evbit); -set_bit (SW_TABLET_MODE , tpacpi_inputdev->swbit); +input_set_capability (tpacpi_inputdev,EV_SW ,SW_TABLET_MODE ); }/* Do not issue duplicate brightness change events to
PATCH 72/197 thinkpad-acpi: sync input device EV_SW initial state
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit d89a727aff649f6768f7a34ee57f031ebf8bab4c upstream.
Before we register the input device, sync the input layer EV_SW state through a call to input_report_switch(), to avoid issuing a gratuitous event for the initial state of these switches.
This fixes some annoyances caused by the interaction with rfkill and EV_SW SW_RFKILL_ALL events.
--- drivers/platform/x86/thinkpad_acpi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +10 -4
@@ -3188,6 +3188,8 @@ static int __init hotkey_init(struct ibmint res, i;int status;int hkeyv; +bool radiosw_state = false; +bool tabletsw_state = false;unsigned long quirks;
@@ -3293,6 +3295,7 @@ static int __init hotkey_init(struct ibm#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_wlswemul) { tp_features.hotkey_wlsw =1 ; + radiosw_state = !!tpacpi_wlsw_emulstate;printk (TPACPI_INFO "radio switch emulation enabled\n" ); }else
@@ -3300,6 +3303,7 @@ static int __init hotkey_init(struct ibm/* Not all thinkpads have a hardware radio switch */ if (acpi_evalf (hkey_handle, &status,"WLSW" ,"qd" )) { tp_features.hotkey_wlsw =1 ; + radiosw_state = !!status;printk (TPACPI_INFO "radio switch found; radios are %s\n" ,enabled (status,0 ));
@@ -3311,11 +3315,11 @@ static int __init hotkey_init(struct ibm/* For X41t, X60t, X61t Tablets... */ if (!res &&acpi_evalf (hkey_handle, &status,"MHKG" ,"qd" )) { tp_features.hotkey_tablet =1 ; + tabletsw_state = !!(status &TP_HOTKEY_TABLET_MASK );printk (TPACPI_INFO "possible tablet mode switch found; " "ThinkPad in %s mode\n" , - (status &TP_HOTKEY_TABLET_MASK )? -"tablet" :"laptop" ); + (tabletsw_state) ?"tablet" :"laptop" ); res =add_to_attr_set (hotkey_dev_attributes, &dev_attr_hotkey_tablet_mode.attr); }
@@ -3366,9 +3370,13 @@ static int __init hotkey_init(struct ibmif (tp_features.hotkey_wlsw) {input_set_capability (tpacpi_inputdev,EV_SW ,SW_RFKILL_ALL ); +input_report_switch (tpacpi_inputdev, +SW_RFKILL_ALL , radiosw_state); }if (tp_features.hotkey_tablet) {input_set_capability (tpacpi_inputdev,EV_SW ,SW_TABLET_MODE ); +input_report_switch (tpacpi_inputdev, +SW_TABLET_MODE , tabletsw_state); }/* Do not issue duplicate brightness change events to
@@ -3435,8 +3443,6 @@ static int __init hotkey_init(struct ibm tpacpi_inputdev->close = &hotkey_inputdev_close;hotkey_poll_setup_safe (true); -tpacpi_send_radiosw_update (); -tpacpi_input_send_tabletsw ();return 0 ;
PATCH 73/197 thinkpad-acpi: log initial state of rfkill switches
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit 5451a923bbdcff6ae665947e120af7238b21a9d2 upstream.
We already log the initial state of the hardware rfkill switch (WLSW), might as well log the state of the softswitches as well.
--- drivers/platform/x86/thinkpad_acpi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/platform/x86/thinkpad_acpi.c +6 -1
@@ -1264,6 +1264,7 @@ static int __init tpacpi_new_rfkill(consstruct tpacpi_rfk *atp_rfk;int res;bool sw_state = false; +bool hw_state;int sw_status;BUG_ON (id >=TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
@@ -1298,7 +1299,8 @@ static int __init tpacpi_new_rfkill(consrfkill_init_sw_state (atp_rfk->rfkill, sw_state); } } -rfkill_set_hw_state (atp_rfk->rfkill,tpacpi_rfk_check_hwblock_state ()); + hw_state =tpacpi_rfk_check_hwblock_state (); +rfkill_set_hw_state (atp_rfk->rfkill, hw_state); res =rfkill_register (atp_rfk->rfkill);if (res <0 ) {
@@ -1311,6 +1313,9 @@ static int __init tpacpi_new_rfkill(cons } tpacpi_rfkill_switches[id] = atp_rfk; + +printk (TPACPI_INFO "rfkill switch %s: radio is %sblocked\n" , + name, (sw_state || hw_state) ?"" :"un" );return 0 ; }
PATCH 74/197 thinkpad-acpi: convert to seq_file
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alexey Dobriyan <[email protected]>
commit 887965e6576a78f71b9b98dec43fd1c73becd2e8 upstream.
([email protected]: Updated to apply to 2.6.32.y)
--- drivers/platform/x86/thinkpad_acpi.c | 282 ++++++++++++++++------------------- 1 file changed, 131 insertions(+), 151 deletions(-)
drivers/platform/x86/thinkpad_acpi.c +131 -151
@@ -61,6 +61,7 @@#include <linux/nvram.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/sysfs.h> #include <linux/backlight.h> #include <linux/fb.h>
@@ -256,7 +257,7 @@ struct tp_acpi_drv_struct {struct ibm_struct {char *name; -int (*read) (char *); +int (*read) (struct seq_file *);int (*write) (char *);void (*exit) (void );void (*resume) (void );
@@ -776,36 +777,25 @@ static int __init register_tpacpi_subdri**************************************************************************** ****************************************************************************/ -static int dispatch_procfs_read (char *page,char **start,off_t off, -int count,int *eof,void *data) +static int dispatch_proc_show (struct seq_file *m,void *v) { -struct ibm_struct *ibm = data; -int len; +struct ibm_struct *ibm = m->private;if (!ibm || !ibm->read)return -EINVAL ; +return ibm->read (m); +} - len = ibm->read (page); -if (len <0 ) -return len; - -if (len <= off + count) - *eof =1 ; - *start = page + off; - len -= off; -if (len > count) - len = count; -if (len <0 ) - len =0 ; - -return len; +static int dispatch_proc_open (struct inode *inode,struct file *file) +{ +return single_open (file, dispatch_proc_show,PDE (inode)->data); } -static int dispatch_procfs_write (struct file *file, +static ssize_t dispatch_proc_write (struct file *file,const char __user *userbuf, -unsigned long count,void *data) +size_t count,loff_t *pos) { -struct ibm_struct *ibm = data; +struct ibm_struct *ibm =PDE (file->f_path.dentry->d_inode)->data;char *kernbuf;int ret;
@@ -834,6 +824,15 @@ static int dispatch_procfs_write(structreturn ret; } +static const struct file_operations dispatch_proc_fops = { + .owner =THIS_MODULE , + .open = dispatch_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = dispatch_proc_write, +}; +static char *next_cmd (char **cmds) {char *start = *cmds;
@@ -1388,12 +1387,11 @@ static ssize_t tpacpi_rfk_sysfs_enable_s }/* procfs -------------------------------------------------------------- */ -static int tpacpi_rfk_procfs_read (const enum tpacpi_rfk_id id,char *p) +static int tpacpi_rfk_procfs_read (const enum tpacpi_rfk_id id, +struct seq_file *m) { -int len =0 ; -if (id >=TPACPI_RFK_SW_MAX ) - len +=sprintf (p + len,"status:\t\tnot supported\n" ); +seq_printf (m,"status:\t\tnot supported\n" );else {int status;
@@ -1407,13 +1405,13 @@ static int tpacpi_rfk_procfs_read(constreturn status; } - len +=sprintf (p + len,"status:\t\t%s\n" , +seq_printf (m,"status:\t\t%s\n" , (status ==TPACPI_RFK_RADIO_ON ) ?"enabled" :"disabled" ); - len +=sprintf (p + len,"commands:\tenable, disable\n" ); +seq_printf (m,"commands:\tenable, disable\n" ); } -return len; +return 0 ; }static int tpacpi_rfk_procfs_write (const enum tpacpi_rfk_id id,char *buf)
@@ -1891,14 +1889,11 @@ static int __init thinkpad_acpi_driver_ireturn 0 ; } -static int thinkpad_acpi_driver_read (char *p) +static int thinkpad_acpi_driver_read (struct seq_file *m) { -int len =0 ; - - len +=sprintf (p + len,"driver:\t\t%s\n" ,TPACPI_DESC ); - len +=sprintf (p + len,"version:\t%s\n" ,TPACPI_VERSION ); - -return len; +seq_printf (m,"driver:\t\t%s\n" ,TPACPI_DESC ); +seq_printf (m,"version:\t%s\n" ,TPACPI_VERSION ); +return 0 ; }static struct ibm_struct thinkpad_acpi_driver_data = {
@@ -3754,14 +3749,13 @@ static void hotkey_resume(void) }/* procfs -------------------------------------------------------------- */ -static int hotkey_read (char *p) +static int hotkey_read (struct seq_file *m) {int res, status; -int len =0 ;if (!tp_features.hotkey) { - len +=sprintf (p + len,"status:\t\tnot supported\n" ); -return len; +seq_printf (m,"status:\t\tnot supported\n" ); +return 0 ; }if (mutex_lock_killable (&hotkey_mutex))
@@ -3773,17 +3767,16 @@ static int hotkey_read(char *p)if (res)return res; - len +=sprintf (p + len,"status:\t\t%s\n" ,enabled (status,0 )); +seq_printf (m,"status:\t\t%s\n" ,enabled (status,0 ));if (hotkey_all_mask) { - len +=sprintf (p + len,"mask:\t\t0x%08x\n" , hotkey_user_mask); - len +=sprintf (p + len, -"commands:\tenable, disable, reset, <mask>\n" ); +seq_printf (m,"mask:\t\t0x%08x\n" , hotkey_user_mask); +seq_printf (m,"commands:\tenable, disable, reset, <mask>\n" ); }else { - len +=sprintf (p + len,"mask:\t\tnot supported\n" ); - len +=sprintf (p + len,"commands:\tenable, disable, reset\n" ); +seq_printf (m,"mask:\t\tnot supported\n" ); +seq_printf (m,"commands:\tenable, disable, reset\n" ); } -return len; +return 0 ; }static void hotkey_enabledisable_warn (bool enable)
@@ -4050,9 +4043,9 @@ static int __init bluetooth_init(struct }/* procfs -------------------------------------------------------------- */ -static int bluetooth_read (char *p) +static int bluetooth_read (struct seq_file *m) { -return tpacpi_rfk_procfs_read (TPACPI_RFK_BLUETOOTH_SW_ID , p); +return tpacpi_rfk_procfs_read (TPACPI_RFK_BLUETOOTH_SW_ID , m); }static int bluetooth_write (char *buf)
@@ -4241,9 +4234,9 @@ static int __init wan_init(struct ibm_in }/* procfs -------------------------------------------------------------- */ -static int wan_read (char *p) +static int wan_read (struct seq_file *m) { -return tpacpi_rfk_procfs_read (TPACPI_RFK_WWAN_SW_ID , p); +return tpacpi_rfk_procfs_read (TPACPI_RFK_WWAN_SW_ID , m); }static int wan_write (char *buf)
@@ -4618,14 +4611,13 @@ static int video_expand_toggle(void)/* not reached */ } -static int video_read (char *p) +static int video_read (struct seq_file *m) {int status, autosw; -int len =0 ;if (video_supported ==TPACPI_VIDEO_NONE ) { - len +=sprintf (p + len,"status:\t\tnot supported\n" ); -return len; +seq_printf (m,"status:\t\tnot supported\n" ); +return 0 ; } status =video_outputsw_get ();
@@ -4636,20 +4628,20 @@ static int video_read(char *p)if (autosw <0 )return autosw; - len +=sprintf (p + len,"status:\t\tsupported\n" ); - len +=sprintf (p + len,"lcd:\t\t%s\n" ,enabled (status,0 )); - len +=sprintf (p + len,"crt:\t\t%s\n" ,enabled (status,1 )); +seq_printf (m,"status:\t\tsupported\n" ); +seq_printf (m,"lcd:\t\t%s\n" ,enabled (status,0 )); +seq_printf (m,"crt:\t\t%s\n" ,enabled (status,1 ));if (video_supported ==TPACPI_VIDEO_NEW ) - len +=sprintf (p + len,"dvi:\t\t%s\n" ,enabled (status,3 )); - len +=sprintf (p + len,"auto:\t\t%s\n" ,enabled (autosw,0 )); - len +=sprintf (p + len,"commands:\tlcd_enable, lcd_disable\n" ); - len +=sprintf (p + len,"commands:\tcrt_enable, crt_disable\n" ); +seq_printf (m,"dvi:\t\t%s\n" ,enabled (status,3 )); +seq_printf (m,"auto:\t\t%s\n" ,enabled (autosw,0 )); +seq_printf (m,"commands:\tlcd_enable, lcd_disable\n" ); +seq_printf (m,"commands:\tcrt_enable, crt_disable\n" );if (video_supported ==TPACPI_VIDEO_NEW ) - len +=sprintf (p + len,"commands:\tdvi_enable, dvi_disable\n" ); - len +=sprintf (p + len,"commands:\tauto_enable, auto_disable\n" ); - len +=sprintf (p + len,"commands:\tvideo_switch, expand_toggle\n" ); +seq_printf (m,"commands:\tdvi_enable, dvi_disable\n" ); +seq_printf (m,"commands:\tauto_enable, auto_disable\n" ); +seq_printf (m,"commands:\tvideo_switch, expand_toggle\n" ); -return len; +return 0 ; }static int video_write (char *buf)
@@ -4841,25 +4833,24 @@ static void light_exit(void)flush_workqueue (tpacpi_wq); } -static int light_read (char *p) +static int light_read (struct seq_file *m) { -int len =0 ;int status;if (!tp_features.light) { - len +=sprintf (p + len,"status:\t\tnot supported\n" ); +seq_printf (m,"status:\t\tnot supported\n" ); }else if (!tp_features.light_status) { - len +=sprintf (p + len,"status:\t\tunknown\n" ); - len +=sprintf (p + len,"commands:\ton, off\n" ); +seq_printf (m,"status:\t\tunknown\n" ); +seq_printf (m,"commands:\ton, off\n" ); }else { status =light_get_status ();if (status <0 )return status; - len +=sprintf (p + len,"status:\t\t%s\n" ,onoff (status,0 )); - len +=sprintf (p + len,"commands:\ton, off\n" ); +seq_printf (m,"status:\t\t%s\n" ,onoff (status,0 )); +seq_printf (m,"commands:\ton, off\n" ); } -return len; +return 0 ; }static int light_write (char *buf)
@@ -4937,20 +4928,18 @@ static void cmos_exit(void)device_remove_file (&tpacpi_pdev->dev, &dev_attr_cmos_command); } -static int cmos_read (char *p) +static int cmos_read (struct seq_file *m) { -int len =0 ; -/* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, R30, R31, T20-22, X20-21 */ if (!cmos_handle) - len +=sprintf (p + len,"status:\t\tnot supported\n" ); +seq_printf (m,"status:\t\tnot supported\n" );else { - len +=sprintf (p + len,"status:\t\tsupported\n" ); - len +=sprintf (p + len,"commands:\t<cmd> (<cmd> is 0-21)\n" ); +seq_printf (m,"status:\t\tsupported\n" ); +seq_printf (m,"commands:\t<cmd> (<cmd> is 0-21)\n" ); } -return len; +return 0 ; }static int cmos_write (char *buf)
@@ -5325,15 +5314,13 @@ static int __init led_init(struct ibm_in ((s) ==TPACPI_LED_OFF ?"off" : \ ((s) == TPACPI_LED_ON ? "on" : "blinking")) -static int led_read (char *p) +static int led_read (struct seq_file *m) { -int len =0 ; -if (!led_supported) { - len +=sprintf (p + len,"status:\t\tnot supported\n" ); -return len; +seq_printf (m,"status:\t\tnot supported\n" ); +return 0 ; } - len +=sprintf (p + len,"status:\t\tsupported\n" ); +seq_printf (m,"status:\t\tsupported\n" );if (led_supported ==TPACPI_LED_570 ) {/* 570 */
@@ -5342,15 +5329,15 @@ static int led_read(char *p) status =led_get_status (i);if (status <0 )return -EIO ; - len +=sprintf (p + len,"%d:\t\t%s\n" , +seq_printf (m,"%d:\t\t%s\n" , i,str_led_status (status)); } } - len +=sprintf (p + len,"commands:\t" +seq_printf (m,"commands:\t" "<led> on, <led> off, <led> blink (<led> is 0-15)\n" ); -return len; +return 0 ; }static int led_write (char *buf)
@@ -5423,18 +5410,16 @@ static int __init beep_init(struct ibm_ireturn (beep_handle)?0 :1 ; } -static int beep_read (char *p) +static int beep_read (struct seq_file *m) { -int len =0 ; -if (!beep_handle) - len +=sprintf (p + len,"status:\t\tnot supported\n" ); +seq_printf (m,"status:\t\tnot supported\n" );else { - len +=sprintf (p + len,"status:\t\tsupported\n" ); - len +=sprintf (p + len,"commands:\t<cmd> (<cmd> is 0-17)\n" ); +seq_printf (m,"status:\t\tsupported\n" ); +seq_printf (m,"commands:\t<cmd> (<cmd> is 0-17)\n" ); } -return len; +return 0 ; }static int beep_write (char *buf)
@@ -5795,9 +5780,8 @@ static void thermal_exit(void) } } -static int thermal_read (char *p) +static int thermal_read (struct seq_file *m) { -int len =0 ;int n, i;struct ibm_thermal_sensors_struct t;
@@ -5805,16 +5789,16 @@ static int thermal_read(char *p)if (unlikely (n <0 ))return n; - len +=sprintf (p + len,"temperatures:\t" ); +seq_printf (m,"temperatures:\t" );if (n >0 ) {for (i =0 ; i < (n -1 ); i++) - len +=sprintf (p + len,"%d " , t.temp[i] /1000 ); - len +=sprintf (p + len,"%d\n" , t.temp[i] /1000 ); +seq_printf (m,"%d " , t.temp[i] /1000 ); +seq_printf (m,"%d\n" , t.temp[i] /1000 ); }else - len +=sprintf (p + len,"not supported\n" ); +seq_printf (m,"not supported\n" ); -return len; +return 0 ; }static struct ibm_struct thermal_driver_data = {
@@ -5829,39 +5813,38 @@ static struct ibm_struct thermal_driver_static u8 ecdump_regs[256 ]; -static int ecdump_read (char *p) +static int ecdump_read (struct seq_file *m) { -int len =0 ;int i, j;u8 v; - len +=sprintf (p + len,"EC " +seq_printf (m,"EC " " +00 +01 +02 +03 +04 +05 +06 +07" " +08 +09 +0a +0b +0c +0d +0e +0f\n" );for (i =0 ; i <256 ; i +=16 ) { - len +=sprintf (p + len,"EC 0x%02x:" , i); +seq_printf (m,"EC 0x%02x:" , i);for (j =0 ; j <16 ; j++) {if (!acpi_ec_read (i + j, &v))break ;if (v != ecdump_regs[i + j]) - len +=sprintf (p + len," *%02x" , v); +seq_printf (m," *%02x" , v);else - len +=sprintf (p + len," %02x" , v); +seq_printf (m," %02x" , v); ecdump_regs[i + j] = v; } - len +=sprintf (p + len,"\n" ); +seq_putc (m,'\n' );if (j !=16 )break ; }/* These are way too dangerous to advertise openly... */ #if 0 - len +=sprintf (p + len,"commands:\t0x<offset> 0x<value>" +seq_printf (m,"commands:\t0x<offset> 0x<value>" " (<offset> is 00-ff, <value> is 00-ff)\n" ); - len +=sprintf (p + len,"commands:\t0x<offset> <value> " +seq_printf (m,"commands:\t0x<offset> <value> " " (<offset> is 00-ff, <value> is 0-255)\n" );#endif -return len; +return 0 ; }static int ecdump_write (char *buf)
@@ -6314,23 +6297,22 @@ static void brightness_exit(void)tpacpi_brightness_checkpoint_nvram (); } -static int brightness_read (char *p) +static int brightness_read (struct seq_file *m) { -int len =0 ;int level; level =brightness_get (NULL );if (level <0 ) { - len +=sprintf (p + len,"level:\t\tunreadable\n" ); +seq_printf (m,"level:\t\tunreadable\n" ); }else { - len +=sprintf (p + len,"level:\t\t%d\n" , level); - len +=sprintf (p + len,"commands:\tup, down\n" ); - len +=sprintf (p + len,"commands:\tlevel <level>" +seq_printf (m,"level:\t\t%d\n" , level); +seq_printf (m,"commands:\tup, down\n" ); +seq_printf (m,"commands:\tlevel <level>" " (<level> is 0-%d)\n" , (tp_features.bright_16levels) ?15 :7 ); } -return len; +return 0 ; }static int brightness_write (char *buf)
@@ -6387,22 +6369,21 @@ static struct ibm_struct brightness_drivstatic int volume_offset =0x30 ; -static int volume_read (char *p) +static int volume_read (struct seq_file *m) { -int len =0 ;u8 level;if (!acpi_ec_read (volume_offset, &level)) { - len +=sprintf (p + len,"level:\t\tunreadable\n" ); +seq_printf (m,"level:\t\tunreadable\n" ); }else { - len +=sprintf (p + len,"level:\t\t%d\n" , level &0xf ); - len +=sprintf (p + len,"mute:\t\t%s\n" ,onoff (level,6 )); - len +=sprintf (p + len,"commands:\tup, down, mute\n" ); - len +=sprintf (p + len,"commands:\tlevel <level>" +seq_printf (m,"level:\t\t%d\n" , level &0xf ); +seq_printf (m,"mute:\t\t%s\n" ,onoff (level,6 )); +seq_printf (m,"commands:\tup, down, mute\n" ); +seq_printf (m,"commands:\tlevel <level>" " (<level> is 0-15)\n" ); } -return len; +return 0 ; }static int volume_write (char *buf)
@@ -7554,9 +7535,8 @@ static void fan_resume(void) } } -static int fan_read (char *p) +static int fan_read (struct seq_file *m) { -int len =0 ;int rc;u8 status;unsigned int speed =0 ;
@@ -7568,7 +7548,7 @@ static int fan_read(char *p)if (rc <0 )return rc; - len +=sprintf (p + len,"status:\t\t%s\n" +seq_printf (m,"status:\t\t%s\n" "level:\t\t%d\n" , (status !=0 ) ?"enabled" :"disabled" , status);break ;
@@ -7579,54 +7559,54 @@ static int fan_read(char *p)if (rc <0 )return rc; - len +=sprintf (p + len,"status:\t\t%s\n" , +seq_printf (m,"status:\t\t%s\n" , (status !=0 ) ?"enabled" :"disabled" ); rc =fan_get_speed (&speed);if (rc <0 )return rc; - len +=sprintf (p + len,"speed:\t\t%d\n" , speed); +seq_printf (m,"speed:\t\t%d\n" , speed);if (status &TP_EC_FAN_FULLSPEED )/* Disengaged mode takes precedence */ - len +=sprintf (p + len,"level:\t\tdisengaged\n" ); +seq_printf (m,"level:\t\tdisengaged\n" );else if (status &TP_EC_FAN_AUTO ) - len +=sprintf (p + len,"level:\t\tauto\n" ); +seq_printf (m,"level:\t\tauto\n" );else - len +=sprintf (p + len,"level:\t\t%d\n" , status); +seq_printf (m,"level:\t\t%d\n" , status);break ;case TPACPI_FAN_NONE :default : - len +=sprintf (p + len,"status:\t\tnot supported\n" ); +seq_printf (m,"status:\t\tnot supported\n" ); }if (fan_control_commands &TPACPI_FAN_CMD_LEVEL ) { - len +=sprintf (p + len,"commands:\tlevel <level>" ); +seq_printf (m,"commands:\tlevel <level>" );switch (fan_control_access_mode) {case TPACPI_FAN_WR_ACPI_SFAN : - len +=sprintf (p + len," (<level> is 0-7)\n" ); +seq_printf (m," (<level> is 0-7)\n" );break ;default : - len +=sprintf (p + len," (<level> is 0-7, " +seq_printf (m," (<level> is 0-7, " "auto, disengaged, full-speed)\n" );break ; } }if (fan_control_commands &TPACPI_FAN_CMD_ENABLE ) - len +=sprintf (p + len,"commands:\tenable, disable\n" +seq_printf (m,"commands:\tenable, disable\n" "commands:\twatchdog <timeout> (<timeout> " "is 0 (off), 1-120 (seconds))\n" );if (fan_control_commands &TPACPI_FAN_CMD_SPEED ) - len +=sprintf (p + len,"commands:\tspeed <speed>" +seq_printf (m,"commands:\tspeed <speed>" " (<speed> is 0-65535)\n" ); -return len; +return 0 ; }static int fan_write_cmd_level (const char *cmd,int *rc)
@@ -7907,19 +7887,19 @@ static int __init ibm_init(struct ibm_in "%s installed\n", ibm->name);if (ibm->read) { - entry =create_proc_entry (ibm->name, -S_IFREG |S_IRUGO |S_IWUSR , - proc_dir); +mode_t mode; + + mode =S_IRUGO ; +if (ibm->write) + mode |=S_IWUSR ; + entry =proc_create_data (ibm->name, mode, proc_dir, + &dispatch_proc_fops, ibm);if (!entry) {printk (TPACPI_ERR "unable to create proc entry %s\n" , ibm->name); ret = -ENODEV ; goto err_out; } - entry->data = ibm; - entry->read_proc = &dispatch_procfs_read; -if (ibm->write) - entry->write_proc = &dispatch_procfs_write; ibm->flags.proc_created =1 ; }
PATCH 75/197 thinkpad-acpi: lock down video output state access
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Henrique de Moraes Holschuh <[email protected]>
commit b525c06cdbd8a3963f0173ccd23f9147d4c384b5 upstream.
Given the right combination of ThinkPad and X.org, just reading the video output control state is enough to hard-crash X.org.
Until the day I somehow find out a model or BIOS cut date to not provide this feature to ThinkPads that can do video switching through X RandR, change permissions so that only processes with CAP_SYS_ADMIN can access any sort of video output control state.
This bug could be considered a local DoS I suppose, as it allows any non-privledged local user to cause some versions of X.org to hard-crash some ThinkPads.
--- Documentation/laptops/thinkpad-acpi.txt | 4 ++++ drivers/platform/x86/Kconfig | 10 ++++++++-- drivers/platform/x86/thinkpad_acpi.c | 15 +++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +4 -0
@@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The foll echo expand_toggle > /proc/acpi/ibm/video echo video_switch > /proc/acpi/ibm/video +NOTE: Access to this feature is restricted to processes owning the +CAP_SYS_ADMIN capability for safety reasons, as it can interact badly +enough with some versions of X.org to crash it. + Each video output device can be enabled or disabled individually. Reading /proc/acpi/ibm/video shows the status of each device.
drivers/platform/x86/Kconfig +8 -2
@@ -291,9 +291,15 @@ config THINKPAD_ACPI_VIDEO server running, phase of the moon, and the current mood of Schroedinger's cat. If you can use X.org's RandR to control your ThinkPad's video output ports instead of this feature, - don't think twice: do it and say N here to save some memory. + don't think twice: do it and say N here to save memory and avoid + bad interactions with X.org. - If you are not sure, say Y here. + NOTE: access to this feature is limited to processes with the + CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms + where it interacts badly with X.org. + + If you are not sure, say Y here but do try to check if you could + be using X.org RandR instead. config THINKPAD_ACPI_HOTKEY_POLL bool "Support NVRAM polling for hot keys"
drivers/platform/x86/thinkpad_acpi.c +13 -2
@@ -281,6 +281,7 @@ struct ibm_init_struct {char param[32 ];int (*init) (struct ibm_init_struct *); +mode_t base_procfs_mode;struct ibm_struct *data; };
@@ -4620,6 +4621,10 @@ static int video_read(struct seq_file *mreturn 0 ; } +/* Even reads can crash X.org, so... */ +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + status =video_outputsw_get ();if (status <0 )return status;
@@ -4653,6 +4658,10 @@ static int video_write(char *buf)if (video_supported ==TPACPI_VIDEO_NONE )return -ENODEV ; +/* Even reads can crash X.org, let alone writes... */ +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + enable =0 ; disable =0 ;
@@ -7887,9 +7896,10 @@ static int __init ibm_init(struct ibm_in "%s installed\n", ibm->name);if (ibm->read) { -mode_t mode; +mode_t mode = iibm->base_procfs_mode; - mode =S_IRUGO ; +if (!mode) + mode =S_IRUGO ;if (ibm->write) mode |=S_IWUSR ; entry = proc_create_data(ibm->name, mode, proc_dir,
@@ -8080,6 +8090,7 @@ static struct ibm_init_struct ibms_init[#ifdef CONFIG_THINKPAD_ACPI_VIDEO { .init = video_init, + .base_procfs_mode = S_IRUSR, .data = &video_driver_data, },#endif
PATCH 76/197 eeepc-laptop: disable cpu speed control on EeePC 701
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit da8ba01deb98f3dc0558b1f5a37e64f40bba7904 upstream.
The EeePC 4G ("701") implements CFVS, but it is not supported by the pre-installed OS, and the original option to change it in the BIOS setup screen was removed in later versions. Judging by the lack of "Super Hybrid Engine" on Asus product pages, this applies to all "701" models (4G/4G Surf/2G Surf).
So Asus made a deliberate decision not to support it on this model. We have several reports that using it can cause the system to hang [1]. That said, it does not happen all the time. Some users do not experience it at all (and apparently wish to continue "right-clocking").
Check for the EeePC 701 using DMI. If met, then disable writes to the "cpufv" sysfs attribute and log an explanatory message.
Add a "cpufv_disabled" attribute which allow users to override this policy. Writing to this attribute will log a second message.
The sysfs attribute is more useful than a module option, because it makes it easier for userspace scripts to provide consistent behaviour (according to user configuration), regardless of whether the kernel includes this change.
[1] <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=559578>
[bwh: Backported to 2.6.32]
--- drivers/platform/x86/eeepc-laptop.c | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
drivers/platform/x86/eeepc-laptop.c +84 -0
@@ -34,6 +34,7 @@#include <linux/rfkill.h> #include <linux/pci.h> #include <linux/pci_hotplug.h> +#include <linux/dmi.h> #define EEEPC_LAPTOP_VERSION "0.1"
@@ -135,6 +136,7 @@ struct eeepc_hotk {acpi_handle handle;/* the handle of the hotk device */ u32 cm_supported;/* the control methods supported by this BIOS */ +bool cpufv_disabled;uint init_flag;/* Init flags */ u16 event_count[128 ];/* count for each event */ struct input_dev *inputdev;
@@ -467,6 +469,8 @@ static ssize_t store_cpufv(struct devicestruct eeepc_cpufv c;int rv, value; +if (ehotk->cpufv_disabled) +return -EPERM ;if (get_cpufv (&c))return -ENODEV ; rv =parse_arg (buf, count, &value);
@@ -478,6 +482,38 @@ static ssize_t store_cpufv(struct devicereturn rv; } +static ssize_t show_cpufv_disabled (struct device *dev, +struct device_attribute *attr, +char *buf) +{ +return sprintf (buf,"%d\n" , ehotk->cpufv_disabled); +} + +static ssize_t store_cpufv_disabled (struct device *dev, +struct device_attribute *attr, +const char *buf,size_t count) +{ +int rv, value; + + rv =parse_arg (buf, count, &value); +if (rv <0 ) +return rv; + +switch (value) { +case 0 : +if (ehotk->cpufv_disabled) +pr_warning ("cpufv enabled (not officially supported " +"on this model)\n" ); + ehotk->cpufv_disabled = false; +return rv; +case 1 : +return -EPERM ; +default : +return -EINVAL ; + } +} + +static struct device_attribute dev_attr_cpufv = { .attr = { .name ="cpufv" ,
@@ -493,12 +529,22 @@ static struct device_attribute dev_attr_ .show = show_available_cpufv }; +static struct device_attribute dev_attr_cpufv_disabled = { + .attr = { + .name ="cpufv_disabled" , + .mode =0644 }, + .show = show_cpufv_disabled, + .store = store_cpufv_disabled +}; + +static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, &dev_attr_cpufv.attr, &dev_attr_available_cpufv.attr, + &dev_attr_cpufv_disabled.attr,NULL };
@@ -564,6 +610,42 @@ static int eeepc_setkeycode(struct inputreturn -EINVAL ; } +static void eeepc_dmi_check (void ) +{ +const char *model; + +/* +* Blacklist for setting cpufv (cpu speed). +* +* EeePC 4G ("701") implements CFVS, but it is not supported +* by the pre-installed OS, and the original option to change it +* in the BIOS setup screen was removed in later versions. +* +* Judging by the lack of "Super Hybrid Engine" on Asus product pages, +* this applies to all "701" models (4G/4G Surf/2G Surf). +* +* So Asus made a deliberate decision not to support it on this model. +* We have several reports that using it can cause the system to hang +* +* The hang has also been reported on a "702" (Model name "8G"?). +* +* We avoid dmi_check_system() / dmi_match(), because they use +* substring matching. We don't want to affect the "701SD" +* and "701SDX" models, because they do support S.H.E. +*/ + + model =dmi_get_system_info (DMI_PRODUCT_NAME ); +if (!model) +return ; + +if (strcmp (model,"701" ) ==0 ||strcmp (model,"702" ) ==0 ) { + ehotk->cpufv_disabled = true; +pr_info ("model %s does not officially support setting cpu " +"speed\n" , model); +pr_info ("cpufv disabled to avoid instability\n" ); + } +} +static void cmsg_quirk (int cm,const char *name) {int dummy;
@@ -1208,6 +1290,8 @@ static int __devinit eeepc_hotk_add(stru device->driver_data = ehotk; ehotk->device = device; +eeepc_dmi_check (); + result =eeepc_hotk_check ();if (result) goto fail_platform_driver;
PATCH 77/197 eeepc-laptop: dmi blacklist to disable pci hotplug code
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 10ae4b5663ff3092553bfbd867e7bd474ce6c553 upstream.
This is a short term workaround for Eeepc 1005HA.
refs: <http://bugzilla.kernel.org/show_bug.cgi?id=14570>
[bwh: Backported to 2.6.32]
--- drivers/platform/x86/eeepc-laptop.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/platform/x86/eeepc-laptop.c +20 -5
@@ -137,6 +137,7 @@ struct eeepc_hotk {u32 cm_supported;/* the control methods supported by this BIOS */ bool cpufv_disabled; +bool hotplug_disabled;uint init_flag;/* Init flags */ u16 event_count[128 ];/* count for each event */ struct input_dev *inputdev;
@@ -614,6 +615,10 @@ static void eeepc_dmi_check(void) {const char *model; + model =dmi_get_system_info (DMI_PRODUCT_NAME ); +if (!model) +return ; +/* * Blacklist for setting cpufv (cpu speed). *
@@ -633,17 +638,24 @@ static void eeepc_dmi_check(void)* substring matching. We don't want to affect the "701SD" * and "701SDX" models, because they do support S.H.E. */ - - model =dmi_get_system_info (DMI_PRODUCT_NAME ); -if (!model) -return ; -if (strcmp (model,"701" ) ==0 ||strcmp (model,"702" ) ==0 ) { ehotk->cpufv_disabled = true;pr_info ("model %s does not officially support setting cpu " "speed\n" , model);pr_info ("cpufv disabled to avoid instability\n" ); } + +/* +* Blacklist for wlan hotplug +* +* Eeepc 1005HA doesn't work like others models and don't need the +* hotplug code. In fact, current hotplug code seems to unplug another +* device... +*/ +if (strcmp (model,"1005HA" ) ==0 ) { + ehotk->hotplug_disabled = true; +pr_info ("wlan hotplug disabled\n" ); + } }static void cmsg_quirk (int cm,const char *name)
@@ -1177,6 +1189,9 @@ static int eeepc_rfkill_init(struct deviif (result && result != -ENODEV ) goto exit; +if (ehotk->hotplug_disabled) +return 0 ; + result =eeepc_setup_pci_hotplug ();/* * If we get -EBUSY then something else is handling the PCI hotplug -
PATCH 78/197 eeepc-laptop: add hotplug_disable parameter
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 322a1356be96bcc4b97e8e370f6468c821330077 upstream.
Some new models need to disable wireless hotplug. For the moment, we don't know excactly what models need that, except 1005HA.
Users will be able to use that param as a workaround.
[bwh: Backported to 2.6.32]
--- drivers/platform/x86/eeepc-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/platform/x86/eeepc-laptop.c +10 -0
@@ -254,6 +254,14 @@ MODULE_AUTHOR("Corentin Chary, Eric CoopMODULE_DESCRIPTION (EEEPC_HOTK_NAME );MODULE_LICENSE ("GPL" ); +static bool hotplug_disabled; + +module_param (hotplug_disabled, bool,0644 ); +MODULE_PARM_DESC (hotplug_disabled, +"Disable hotplug for wireless device. " +"If your laptop need that, please report to " +"[email protected]." ); +/* * ACPI Helpers */
@@ -1305,6 +1313,8 @@ static int __devinit eeepc_hotk_add(stru device->driver_data = ehotk; ehotk->device = device; + ehotk->hotplug_disabled = hotplug_disabled; +eeepc_dmi_check (); result =eeepc_hotk_check ();
PATCH 79/197 eeepc-laptop: disable wireless hotplug for 1201N
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 4194e2f551a6308e6ab34ac88210bf54858aa7df upstream.
[bwh: Backported to 2.6.32]
--- drivers/platform/x86/eeepc-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/eeepc-laptop.c +1 -1
@@ -660,7 +660,7 @@ static void eeepc_dmi_check(void)* hotplug code. In fact, current hotplug code seems to unplug another * device... */ -if (strcmp (model,"1005HA" ) ==0 ) { +if (strcmp (model,"1005HA" ) ==0 ||strcmp (model,"1201N" ) ==0 ) { ehotk->hotplug_disabled = true;pr_info ("wlan hotplug disabled\n" ); }
PATCH 80/197 eeepc-laptop: disable wireless hotplug for 1005PE
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit ced69c59811f05b2f8378467cbb82ac6ed3c6a5a upstream.
The wireless hotplug code is not needed on this model, and it disables the wired ethernet card. (Like on the 1005HA and 1201N).
[bwh: Backported to 2.6.32]
--- drivers/platform/x86/eeepc-laptop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/platform/x86/eeepc-laptop.c +2 -1
@@ -660,7 +660,8 @@ static void eeepc_dmi_check(void)* hotplug code. In fact, current hotplug code seems to unplug another * device... */ -if (strcmp (model,"1005HA" ) ==0 ||strcmp (model,"1201N" ) ==0 ) { +if (strcmp (model,"1005HA" ) ==0 ||strcmp (model,"1201N" ) ==0 || +strcmp (model,"1005PE" ) ==0 ) { ehotk->hotplug_disabled = true;pr_info ("wlan hotplug disabled\n" ); }
PATCH 81/197 libata: disable NCQ on Crucial C300 SSD
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tejun Heo <[email protected]>
commit 68b0ddb289220b6d4d865be128939663be34959d upstream.
Crucial said,
Thank you for contacting us. We know that with our M225 line of SSDs you sometimes need to disable NCQ (native command queuing) to avoid just the type of errors you're seeing. Our recommendation for the M225 is to add libata.force=noncq to your Linux kernel boot options, under the kernel ATA library option.
I have sent your feedback to the engineers working on the C300, and asked them to please pass it on to the firmware team. I have been notified that they are in the process of testing and finalizing a new firmware version, that you can expect to see released around the end of April. We’ll keep you posted as to when it will be available for download.
So, turn off NCQ on the drive w/ the current firmware revision.
Reported in the following bug.
https://bugzilla.kernel.org/show_bug.cgi?id=15573
--- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/ata/libata-core.c +3 -0
@@ -4348,6 +4348,9 @@ static const struct ata_blacklist_entry { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ + { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, + /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
PATCH 82/197 cifs: Fix a kernel BUG with remote OS/2 server (try #3)
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Suresh Jayaraman <[email protected]>
commit 6513a81e9325d712f1bfb9a1d7b750134e49ff18 upstream.
While chasing a bug report involving a OS/2 server, I noticed the server sets pSMBr->CountHigh to a incorrect value even in case of normal writes. This results in 'nbytes' being computed wrongly and triggers a kernel BUG at mm/filemap.c.
void iov_iter_advance(struct iov_iter *i, size_t bytes)
{
BUG_ON(i->count < bytes); <--- BUG hereWhy the server is setting 'CountHigh' is not clear but only does so after writing 64k bytes. Though this looks like the server bug, the client side crash may not be acceptable.
The workaround is to mask off high 16 bits if the number of bytes written as returned by the server is greater than the bytes requested by the client as suggested by Jeff Layton.
--- fs/cifs/cifssmb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/cifs/cifssmb.c +16 -0
@@ -1517,6 +1517,14 @@ CIFSSMBWrite(const int xid, struct cifsT *nbytes =le16_to_cpu (pSMBr->CountHigh); *nbytes = (*nbytes) <<16 ; *nbytes +=le16_to_cpu (pSMBr->Count); + +/* +* Mask off high 16 bits when bytes written as returned by the +* server is greater than bytes requested by the client. Some +* OS/2 servers are known to set incorrect CountHigh values. +*/ +if (*nbytes > count) + *nbytes &=0xFFFF ; }cifs_buf_release (pSMB);
@@ -1605,6 +1613,14 @@ CIFSSMBWrite2(const int xid, struct cifs *nbytes =le16_to_cpu (pSMBr->CountHigh); *nbytes = (*nbytes) <<16 ; *nbytes +=le16_to_cpu (pSMBr->Count); + +/* +* Mask off high 16 bits when bytes written as returned by the +* server is greater than bytes requested by the client. OS/2 +* servers are known to set incorrect CountHigh values. +*/ +if (*nbytes > count) + *nbytes &=0xFFFF ; }/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
PATCH 83/197 CIFS: initialize nbytes at the beginning of CIFSSMBWrite()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Steve French <[email protected]>
commit a24e2d7d8f512340991ef0a59cb5d08d491b8e98 upstream.
By doing this we always overwrite nbytes value that is being passed on to CIFSSMBWrite() and need not rely on the callers to initialize. CIFSSMBWrite2 is doing this already.
--- fs/cifs/cifssmb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/cifs/cifssmb.c +2 -1
@@ -1430,6 +1430,8 @@ CIFSSMBWrite(const int xid, struct cifsT__u32 bytes_sent;__u16 byte_count; + *nbytes =0 ; +/* cFYI(1, ("write at %lld %d bytes", offset, count));*/ if (tcon->ses ==NULL )return -ECONNABORTED ;
@@ -1512,7 +1514,6 @@ CIFSSMBWrite(const int xid, struct cifsTcifs_stats_inc (&tcon->num_writes);if (rc) {cFYI (1 , ("Send error in write = %d" , rc)); - *nbytes =0 ; }else { *nbytes =le16_to_cpu (pSMBr->CountHigh); *nbytes = (*nbytes) <<16 ;
PATCH 84/197 iwlwifi: need check for valid qos packet before free
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wey-Yi Guy <[email protected]>
commit ece6444c2fe80dab679beb5f0d58b091f1933b00 upstream.
For 4965, need to check it is valid qos frame before free, only valid QoS frame has the tid used to free the packets.
--- drivers/net/wireless/iwlwifi/iwl-4965.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965.c +9 -4
@@ -2134,7 +2134,9 @@ static void iwl4965_rx_reply_tx(struct iIWL_DEBUG_TX_REPLY (priv,"Retry scheduler reclaim scd_ssn " "%d index %d\n" , scd_ssn , index); freed =iwl_tx_queue_reclaim (priv, txq_id, index); -iwl_free_tfds_in_queue (priv, sta_id, tid, freed); +if (qc) +iwl_free_tfds_in_queue (priv, sta_id, + tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2161,14 +2163,17 @@ static void iwl4965_rx_reply_tx(struct i tx_resp->failure_frame); freed =iwl_tx_queue_reclaim (priv, txq_id, index); -iwl_free_tfds_in_queue (priv, sta_id, tid, freed); +if (qc &&likely (sta_id !=IWL_INVALID_STATION )) +iwl_free_tfds_in_queue (priv, sta_id, tid, freed); +else if (sta_id ==IWL_INVALID_STATION ) +IWL_DEBUG_TX_REPLY (priv,"Station not known\n" );if (priv->mac80211_registered && (iwl_queue_space (&txq->q) > txq->q.low_mark))iwl_wake_queue (priv, txq_id); } - -iwl_txq_check_empty (priv, sta_id, tid, txq_id); +if (qc &&likely (sta_id !=IWL_INVALID_STATION )) +iwl_txq_check_empty (priv, sta_id, tid, txq_id);if (iwl_check_bits (status,TX_ABORT_REQUIRED_MSK ))IWL_ERR (priv,"TODO: Implement Tx ABORT REQUIRED!!!\n" );
PATCH 85/197 ARM: 6031/1: fix Thumb-2 decompressor
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Rabin Vincent <[email protected]>
commit d4d9959c099751158c5cf14813fe378e206339c6 upstream.
98e12b5a6e05413 ("ARM: Fix decompressor's kernel size estimation for ROM=y") broke the Thumb-2 decompressor because it added an entry in the LC0 table but didn't adjust the offset the Thumb-2 code uses to load the SP from that table. Fix it.
--- arch/arm/boot/compressed/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/compressed/head.S +1 -1
@@ -164,7 +164,7 @@ not_angel: adr r0, LC0 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) - THUMB( ldr sp, [r0, #28] ) + THUMB( ldr sp, [r0, #32] ) subs r0, r0, r1 @ calculate the delta offset @ if delta is zero, we are
PATCH 86/197 drm/edid/quirks: Envision EN2028
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Adam Jackson <[email protected]>
commit ba1163de2f74d624e7b0e530c4104c98ede0045a upstream.
Claims 1280x1024 preferred, physically 1600x1200
cf. http://bugzilla.redhat.com/530399
--- drivers/gpu/drm/drm_edid.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/drm_edid.c +2 -0
@@ -85,6 +85,8 @@ static struct edid_quirk {/* Envision Peripherals, Inc. EN-7100e */ { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, +/* Envision EN2028 */ + { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },/* Funai Electronics PM36B */ { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
PATCH 87/197 drm/radeon: R300 AD only has one quad pipe.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <[email protected]>
commit 57b54ea6b7863ccfeb41851b5f58f9fd1b83c79e upstream.
Gleaned from the Mesa code.
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=27355 .
--- drivers/gpu/drm/radeon/r300.c | 5 +++-- drivers/gpu/drm/radeon/radeon_cp.c | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-)
drivers/gpu/drm/radeon/r300.c +3 -2
@@ -346,11 +346,12 @@ void r300_gpu_init(struct radeon_devicer100_hdp_reset (rdev);/* FIXME: rv380 one pipes ? */ -if ((rdev->family ==CHIP_R300 ) || (rdev->family ==CHIP_R350 )) { +if ((rdev->family ==CHIP_R300 && rdev->pdev->device !=0x4144 ) || + (rdev->family ==CHIP_R350 )) {/* r300,r350 */ rdev->num_gb_pipes =2 ; }else { -/* rv350,rv370,rv380 */ +/* rv350,rv370,rv380,r300 AD */ rdev->num_gb_pipes =1 ; } rdev->num_z_pipes =1 ;
drivers/gpu/drm/radeon/radeon_cp.c +6 -4
@@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_rreturn -EBUSY ; } -static void radeon_init_pipes (drm_radeon_private_t *dev_priv) +static void radeon_init_pipes (struct drm_device *dev) { +drm_radeon_private_t *dev_priv = dev->dev_private;uint32_t gb_tile_config, gb_pipe_sel =0 ;if ((dev_priv->flags &RADEON_FAMILY_MASK ) ==CHIP_RV530 ) {
@@ -436,11 +437,12 @@ static void radeon_init_pipes(drm_radeon dev_priv->num_gb_pipes = ((gb_pipe_sel >>12 ) &0x3 ) +1 ; }else {/* R3xx */ -if (((dev_priv->flags &RADEON_FAMILY_MASK ) ==CHIP_R300 ) || +if (((dev_priv->flags &RADEON_FAMILY_MASK ) ==CHIP_R300 && + dev->pdev->device !=0x4144 ) || ((dev_priv->flags &RADEON_FAMILY_MASK ) ==CHIP_R350 )) { dev_priv->num_gb_pipes =2 ; }else { -/* R3Vxx */ +/* RV3xx/R300 AD */ dev_priv->num_gb_pipes =1 ; } }
@@ -736,7 +738,7 @@ static int radeon_do_engine_reset(struct/* setup the raster pipes */ if ((dev_priv->flags &RADEON_FAMILY_MASK ) >=CHIP_R300 ) -radeon_init_pipes (dev_priv); +radeon_init_pipes (dev);/* Reset the CP ring */ radeon_do_cp_reset (dev_priv);
PATCH 88/197 drm/radeon/kms: fix washed out image on legacy tv dac
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 643acacf02679befd0f98ac3c5fecb805f1c9548 upstream.
bad cast was overwriting the tvdac adj values Fixes fdo bug 27478
--- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_connectors.c +1 -1
@@ -281,7 +281,7 @@ int radeon_connector_set_property(struct radeon_encoder =to_radeon_encoder (encoder);if (!radeon_encoder->enc_priv)return 0 ; -if (rdev->is_atom_bios) { +if (ASIC_IS_AVIVO (rdev) || radeon_r4xx_atom) {struct radeon_encoder_atom_dac *dac_int; dac_int = radeon_encoder->enc_priv; dac_int->tv_std = val;
PATCH 89/197 x86-32, resume: do a global tlb flush in S4 resume
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Shaohua Li <[email protected]>
commit 8ae06d223f8203c72104e5c0c4ee49a000aedb42 upstream.
Colin King reported a strange oops in S4 resume code path (see below). The test system has i5/i7 CPU. The kernel doesn't open PAE, so 4M page table is used. The oops always happen a virtual address 0xc03ff000, which is mapped to the last 4k of first 4M memory. Doing a global tlb flush fixes the issue.
EIP: 0060:[<c0493a01>] EFLAGS: 00010086 CPU: 0 EIP is at copy_loop+0xe/0x15
EAX: 36aeb000 EBX: 00000000 ECX: 00000400 EDX: f55ad46c
ESI: 0f800000 EDI: c03ff000 EBP: f67fbec4 ESP: f67fbea8
DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
...
...
CR2: 00000000c03ff000
LKML-Reference: <[email protected]>
--- arch/x86/power/hibernate_asm_32.S | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
arch/x86/power/hibernate_asm_32.S +7 -8
@@ -27,10 +27,17 @@ ENTRY(swsusp_arch_suspend) ret ENTRY(restore_image) + movl mmu_cr4_features, %ecx movl resume_pg_dir, %eax subl $__PAGE_OFFSET, %eax movl %eax, %cr3 + jecxz 1f # cr4 Pentium and higher, skip if zero + andl $~(X86_CR4_PGE), %ecx + movl %ecx, %cr4; # turn off PGE + movl %cr3, %eax; # flush TLB + movl %eax, %cr3 +1: movl restore_pblist, %edx .p2align 4,,7
@@ -54,16 +61,8 @@ done: movl $swapper_pg_dir, %eax subl $__PAGE_OFFSET, %eax movl %eax, %cr3 - /* Flush TLB, including "global" things (vmalloc) */ movl mmu_cr4_features, %ecx jecxz 1f # cr4 Pentium and higher, skip if zero - movl %ecx, %edx - andl $~(X86_CR4_PGE), %edx - movl %edx, %cr4; # turn off PGE -1: - movl %cr3, %eax; # flush TLB - movl %eax, %cr3 - jecxz 1f # cr4 Pentium and higher, skip if zero movl %ecx, %cr4; # turn PGE back on 1:
PATCH 90/197 x86: hpet: Make WARN_ON understandable
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Thomas Gleixner <[email protected]>
commit 18ed61da985c57eea3fe8038b13fa2837c9b3c3f upstream.
Andrew complained rightly that the WARN_ON in hpet_next_event() is confusing and the code comment not really helpful.
Change it to WARN_ONCE and print the reason in clear text. Change the comment to explain what kind of hardware wreckage we deal with.
--- arch/x86/kernel/hpet.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
arch/x86/kernel/hpet.c +15 -4
@@ -385,11 +385,22 @@ static int hpet_next_event(unsigned longhpet_writel (cnt,HPET_Tn_CMP (timer));/* -* We need to read back the CMP register to make sure that -* what we wrote hit the chip before we compare it to the -* counter. +* We need to read back the CMP register on certain HPET +* implementations (ATI chipsets) which seem to delay the +* transfer of the compare register into the internal compare +* logic. With small deltas this might actually be too late as +* the counter could already be higher than the compare value +* at that point and we would wait for the next hpet interrupt +* forever. We found out that reading the CMP register back +* forces the transfer so we can rely on the comparison with +* the counter register below. If the read back from the +* compare register does not match the value we programmed +* then we might have a real hardware problem. We can not do +* much about it here, but at least alert the user/admin with +* a prominent warning. */ -WARN_ON_ONCE ((u32 )hpet_readl (HPET_Tn_CMP (timer)) != cnt); +WARN_ONCE ((u32 )hpet_readl (HPET_Tn_CMP (timer)) != cnt, +KERN_WARNING "hpet: compare register read back failed.\n" );return (s32)((u32 )hpet_readl (HPET_COUNTER ) - cnt) >=0 ? -ETIME :0 ; }
PATCH 91/197 x86, hpet: Erratum workaround for read after write of HPET comparator
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Pallipadi, Venkatesh <[email protected]>
commit 8da854cb02156c90028233ae1e85ce46a1d3f82c upstream.
Quoted 31 lines · Justin Piszcz
Hello,
Again, on the Intel DP55KG board:
# uname -a Linux host 2.6.33 #1 SMP Wed Feb 24 18:31:00 EST 2010 x86_64 GNU/Linux[ 1.237600] ------------[ cut here ]------------ [ 1.237890] WARNING: at arch/x86/kernel/hpet.c:404 hpet_next_event+0x70/0x80() [ 1.238221] Hardware name: [ 1.238504] hpet: compare register read back failed. [ 1.238793] Modules linked in: [ 1.239315] Pid: 0, comm: swapper Not tainted 2.6.33 #1 [ 1.239605] Call Trace: [ 1.239886] <IRQ> [<ffffffff81056c13>] ? warn_slowpath_common+0x73/0xb0 [ 1.240409] [<ffffffff81079608>] ? tick_dev_program_event+0x38/0xc0 [ 1.240699] [<ffffffff81056cb0>] ? warn_slowpath_fmt+0x40/0x50 [ 1.240992] [<ffffffff81079608>] ? tick_dev_program_event+0x38/0xc0 [ 1.241281] [<ffffffff81041ad0>] ? hpet_next_event+0x70/0x80 [ 1.241573] [<ffffffff81079608>] ? tick_dev_program_event+0x38/0xc0 [ 1.241859] [<ffffffff81078e32>] ? tick_handle_oneshot_broadcast+0xe2/0x100 [ 1.246533] [<ffffffff8102a67a>] ? timer_interrupt+0x1a/0x30 [ 1.246826] [<ffffffff81085499>] ? handle_IRQ_event+0x39/0xd0 [ 1.247118] [<ffffffff81087368>] ? handle_edge_irq+0xb8/0x160 [ 1.247407] [<ffffffff81029f55>] ? handle_irq+0x15/0x20 [ 1.247689] [<ffffffff810294a2>] ? do_IRQ+0x62/0xe0 [ 1.247976] [<ffffffff8146be53>] ? ret_from_intr+0x0/0xa [ 1.248262] <EOI> [<ffffffff8102f277>] ? mwait_idle+0x57/0x80 [ 1.248796] [<ffffffff8102645c>] ? cpu_idle+0x5c/0xb0 [ 1.249080] ---[ end trace db7f668fb6fef4e1 ]---
Quoted 1 line
Is this something Intel has to fix or is it a bug in the kernel?
This is a chipset erratum.
Thomas: You mentioned we can retain this check only for known-buggy and hpet debug kind of options. But here is the simple workaround patch for this particular erratum.
Some chipsets have a erratum due to which read immediately following a write of HPET comparator returns old comparator value instead of most recently written value.
Erratum 15 in
"Intel I/O Controller Hub 9 (ICH9) Family Specification Update"
(http://www.intel.com/assets/pdf/specupdate/316973.pdf)
Workaround for the errata is to read the comparator twice if the first one fails.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/hpet.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/kernel/hpet.c +7 -1
@@ -398,9 +398,15 @@ static int hpet_next_event(unsigned long* then we might have a real hardware problem. We can not do * much about it here, but at least alert the user/admin with * a prominent warning. +* An erratum on some chipsets (ICH9,..), results in comparator read +* immediately following a write returning old value. Workaround +* for this is to read this value second time, when first +* read returns old value. */ -WARN_ONCE ((u32 )hpet_readl (HPET_Tn_CMP (timer)) != cnt, +if (unlikely ((u32 )hpet_readl (HPET_Tn_CMP (timer)) != cnt)) { +WARN_ONCE ((u32 )hpet_readl (HPET_Tn_CMP (timer)) != cnt,KERN_WARNING "hpet: compare register read back failed.\n" ); + }return (s32)((u32 )hpet_readl (HPET_COUNTER ) - cnt) >=0 ? -ETIME :0 ; }
PATCH 92/197 x86: Fix double enable_IR_x2apic() call on SMP kernel on !SMP boards
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Suresh Siddha <[email protected]>
commit 472a474c6630efd195d3738339fd1bdc8aa3b1aa upstream.
Jan Grossmann reported kernel boot panic while booting SMP kernel on his system with a single core cpu. SMP kernels call enable_IR_x2apic() from native_smp_prepare_cpus() and on platforms where the kernel doesn't find SMP configuration we ended up again calling enable_IR_x2apic() from the APIC_init_uniprocessor() call in the smp_sanity_check(). Thus leading to kernel panic.
Don't call enable_IR_x2apic() and default_setup_apic_routing() from APIC_init_uniprocessor() in CONFIG_SMP case.
NOTE: this kind of non-idempotent and assymetric initialization sequence is rather fragile and unclean, we'll clean that up in v2.6.35. This is the minimal fix for v2.6.34.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/apic/apic.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kernel/apic/apic.c +2 -0
@@ -1664,8 +1664,10 @@ int __init APIC_init_uniprocessor(void) }#endif +#ifndef CONFIG_SMP enable_IR_x2apic ();default_setup_apic_routing (); +#endif verify_local_APIC ();connect_bsp_APIC ();
PATCH 93/197 sched: sched_getaffinity(): Allow less than NR_CPUS length
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: KOSAKI Motohiro <[email protected]>
commit cd3d8031eb4311e516329aee03c79a08333141f1 upstream.
[ Note, this commit changes the syscall ABI for > 1024 CPUs systems. ]
Recently, some distro decided to use NR_CPUS=4096 for mysterious reasons. Unfortunately, glibc sched interface has the following definition:
# define __CPU_SETSIZE 1024
# define __NCPUBITS (8 * sizeof (__cpu_mask))
typedef unsigned long int __cpu_mask;
typedef struct
{
__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;It mean, if NR_CPUS is bigger than 1024, cpu_set_t makes an ABI issue ...
More recently, Sharyathi Nagesh reported following test program makes misterious syscall failure:
-----------------------------------------------------------------------
#define _GNU_SOURCE
#include<stdio.h>
#include<errno.h>
#include<sched.h>
int main()
{
cpu_set_t set;
if (sched_getaffinity(0, sizeof(cpu_set_t), &set) < 0)
printf("\n Call is failing with:%d", errno); }
-----------------------------------------------------------------------
Because the kernel assumes len argument of sched_getaffinity() is bigger than NR_CPUS. But now it is not correct.
Now we are faced with the following annoying dilemma, due to the limitations of the glibc interface built in years ago:
(1) if we change glibc's __CPU_SETSIZE definition, we lost binary compatibility of _all_ application.
(2) if we don't change it, we also lost binary compatibility of Sharyathi's use case.
Then, I would propse to change the rule of the len argument of sched_getaffinity().
Old:
len should be bigger than NR_CPUS
New:
len should be bigger than maximum possible cpu id
This creates the following behavior:
(A) In the real 4096 cpus machine, the above test program still return -EINVAL.
(B) NR_CPUS=4096 but the machine have less than 1024 cpus (almost all machines in the world), the above can run successfully.
Fortunatelly, BIG SGI machine is mainly used for HPC use case. It means they can rebuild their programs.
IOW we hope they are not annoyed by this issue ...
LKML-Reference: <[email protected]>
--- kernel/sched.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
kernel/sched.c +7 -3
@@ -6669,7 +6669,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_tint ret;cpumask_var_t mask; -if (len <cpumask_size ()) +if (len < nr_cpu_ids) +return -EINVAL ; +if (len & (sizeof (unsigned long )-1 ))return -EINVAL ;if (!alloc_cpumask_var (&mask,GFP_KERNEL ))
@@ -6677,10 +6679,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t ret =sched_getaffinity (pid, mask);if (ret ==0 ) { -if (copy_to_user (user_mask_ptr, mask,cpumask_size ())) +int retlen =min (len,cpumask_size ()); + +if (copy_to_user (user_mask_ptr, mask, retlen)) ret = -EFAULT ;else - ret =cpumask_size (); + ret = retlen; }free_cpumask_var (mask);
PATCH 94/197 sched: Fix sched_getaffinity()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Anton Blanchard <[email protected]>
commit 84fba5ec91f11c0efb27d0ed6098f7447491f0df upstream.
taskset on 2.6.34-rc3 fails on one of my ppc64 test boxes with the following error:
sched_getaffinity(0, 16, 0x10029650030) = -1 EINVAL (Invalid argument)
This box has 128 threads and 16 bytes is enough to cover it.
Commit cd3d8031eb4311e516329aee03c79a08333141f1 (sched:sched_getaffinity(): Allow less than NR_CPUS length) is comparing this 16 bytes agains nr_cpu_ids.
Fix it by comparing nr_cpu_ids to the number of bits in the cpumask we pass in.
LKML-Reference: <20100406070218.GM5594@kryten>
--- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched.c +1 -1
@@ -6669,7 +6669,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_tint ret;cpumask_var_t mask; -if (len < nr_cpu_ids) +if ((len *BITS_PER_BYTE ) < nr_cpu_ids)return -EINVAL ;if (len & (sizeof (unsigned long )-1 ))return -EINVAL ;
PATCH 95/197 NFSv4: Fall back to ordinary lookup if nfs4_atomic_open() returns EISDIR
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit 80e60639f1b7c121a7fea53920c5a4b94009361a upstream.
--- fs/nfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/dir.c +1 -1
@@ -1025,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup( res =NULL ; goto out;/* This turned out not to be a regular file */ +case -EISDIR :case -ENOTDIR : goto no_open;case -ELOOP :if (!(nd->intent.open.flags &O_NOFOLLOW )) goto no_open; -/* case -EISDIR: */ /* case -EINVAL: */ default : goto out;
PATCH 96/197 NFSv4: fix delegated locking
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit 0df5dd4aae211edeeeb84f7f84f6d093406d7c22 upstream.
Arnaud Giersch reports that NFSv4 locking is broken when we hold a delegation since commit 8e469ebd6dc32cbaf620e134d79f740bf0ebab79 (NFSv4:
Don't allow posix locking against servers that don't support it).
According to Arnaud, the lock succeeds the first time he opens the file (since we cannot do a delegated open) but then fails after we start using delegated opens.
The following patch fixes it by ensuring that locking behaviour is governed by a per-filesystem capability flag that is initially set, but gets cleared if the server ever returns an OPEN without the NFS4_OPEN_RESULT_LOCKTYPE_POSIX flag being set.
--- fs/nfs/client.c | 3 ++- fs/nfs/nfs4proc.c | 4 +++- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-)
fs/nfs/client.c +2 -1
@@ -1283,7 +1283,8 @@ static int nfs4_init_server(struct nfs_s/* Initialise the client representation from the mount data */ server->flags = data->flags; - server->caps |=NFS_CAP_ATOMIC_OPEN |NFS_CAP_CHANGE_ATTR ; + server->caps |=NFS_CAP_ATOMIC_OPEN |NFS_CAP_CHANGE_ATTR | +NFS_CAP_POSIX_LOCK ; server->options = data->options;/* Get a client record */
fs/nfs/nfs4proc.c +3 -1
@@ -1439,6 +1439,8 @@ static int _nfs4_proc_open(struct nfs4_onfs_post_op_update_inode (dir, o_res->dir_attr); }else nfs_refresh_inode (dir, o_res->dir_attr); +if ((o_res->rflags &NFS4_OPEN_RESULT_LOCKTYPE_POSIX ) ==0 ) + server->caps &= ~NFS_CAP_POSIX_LOCK ;if (o_res->rflags &NFS4_OPEN_RESULT_CONFIRM ) { status =_nfs4_proc_open_confirm (data);if (status !=0 )
@@ -1573,7 +1575,7 @@ static int _nfs4_do_open(struct inode *d status =PTR_ERR (state);if (IS_ERR (state)) goto err_opendata_put; -if ((opendata->o_res.rflags &NFS4_OPEN_RESULT_LOCKTYPE_POSIX ) !=0 ) +if (server->caps &NFS_CAP_POSIX_LOCK )set_bit (NFS_STATE_POSIX_LOCKS , &state->flags);nfs4_opendata_put (opendata);nfs4_put_state_owner (sp);
include/linux/nfs_fs_sb.h +1 -0
@@ -176,6 +176,7 @@ struct nfs_server {#define NFS_CAP_ATIME (1U << 11)#define NFS_CAP_CTIME (1U << 12)#define NFS_CAP_MTIME (1U << 13) +#define NFS_CAP_POSIX_LOCK (1U << 14)/* maximum number of slots to use */
PATCH 97/197 ALSA: hda - add a quirk for Clevo M570U laptop
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joerg Schirottke <[email protected]>
commit d1501ea844eefdf925f6b711875b4b2b928fddf8 upstream.
Added the matching model for Clevo laptop M570U.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -8895,6 +8895,7 @@ static struct snd_pci_quirk alc882_cfg_tSND_PCI_QUIRK (0x1462 ,0xaa08 ,"MSI" , ALC883_TARGA_2ch_DIG),SND_PCI_QUIRK (0x147b ,0x1083 ,"Abit IP35-PRO" ,ALC883_6ST_DIG ), +SND_PCI_QUIRK (0x1558 ,0x0571 ,"Clevo laptop M570U" , ALC883_3ST_6ch_DIG),SND_PCI_QUIRK (0x1558 ,0x0721 ,"Clevo laptop M720R" ,ALC883_CLEVO_M720 ),SND_PCI_QUIRK (0x1558 ,0x0722 ,"Clevo laptop M720SR" ,ALC883_CLEVO_M720 ), SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
PATCH 98/197 ALSA: usb - Fix Oops after usb-midi disconnection
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Takashi Iwai <[email protected]>
commit 29aac005ff4dc8a5f50b80f4e5c4f59b21c0fb50 upstream.
usb-midi causes sometimes Oops at snd_usbmidi_output_drain() after disconnection. This is due to the access to the endpoints which have been already released at disconnection while the files are still alive.
This patch fixes the problem by checking disconnection state at snd_usbmidi_output_drain() and by releasing urbs but keeping the endpoint instances until really all freed.
--- sound/usb/usbmidi.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
sound/usb/usbmidi.c +18 -6
@@ -931,6 +931,8 @@ static void snd_usbmidi_output_drain(strDEFINE_WAIT (wait);long timeout =msecs_to_jiffies (50 ); +if (ep->umidi->disconnected) +return ;/* * The substream buffer is empty, but some data might still be in the * currently active URBs, so we have to wait for those to complete.
@@ -1075,14 +1077,21 @@ static unsigned int snd_usbmidi_count_bi* Frees an output endpoint. * May be called when ep hasn't been initialized completely. */ -static void snd_usbmidi_out_endpoint_delete (struct snd_usb_midi_out_endpoint * ep) +static void snd_usbmidi_out_endpoint_clear (struct snd_usb_midi_out_endpoint *ep) {unsigned int i;for (i =0 ; i <OUTPUT_URBS ; ++i) -if (ep->urbs[i].urb) +if (ep->urbs[i].urb) {free_urb_and_buffer (ep->umidi, ep->urbs[i].urb, ep->max_transfer); + ep->urbs[i].urb =NULL ; + } +} + +static void snd_usbmidi_out_endpoint_delete (struct snd_usb_midi_out_endpoint *ep) +{ +snd_usbmidi_out_endpoint_clear (ep);kfree (ep); }
@@ -1201,15 +1210,18 @@ void snd_usbmidi_disconnect(struct list_usb_kill_urb (ep->out->urbs[j].urb);if (umidi->usb_protocol_ops->finish_out_endpoint) umidi->usb_protocol_ops->finish_out_endpoint (ep->out); + ep->out->active_urbs =0 ; +if (ep->out->drain_urbs) { + ep->out->drain_urbs =0 ; +wake_up (&ep->out->drain_wait); + } }if (ep->in)for (j =0 ; j <INPUT_URBS ; ++j)usb_kill_urb (ep->in->urbs[j]);/* free endpoints here; later call can result in Oops */ -if (ep->out) { -snd_usbmidi_out_endpoint_delete (ep->out); - ep->out =NULL ; - } +if (ep->out) +snd_usbmidi_out_endpoint_clear (ep->out);if (ep->in) {snd_usbmidi_in_endpoint_delete (ep->in); ep->in =NULL ;
PATCH 99/197 hwmon: (sht15) Fix sht15_calc_temp interpolation function
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jerome Oufella <[email protected]>
commit 328a2c22abd08911e37fa66f1358f829cecd72e9 upstream.
I discovered two issues.
First the previous sht15_calc_temp() loop did not iterate through the temppoints array since the (data->supply_uV > temppoints[i - 1].vdd) test is always true in this direction.
Also the two-points linear interpolation function was returning biased values due to a stray division by 1000 which shouldn't be there.
[JD: Also change the default value for d1 from 0 to something saner.]
--- drivers/hwmon/sht15.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/hwmon/sht15.c +3 -3
@@ -302,13 +302,13 @@ error_ret:**/ static inline int sht15_calc_temp (struct sht15_data *data) { -int d1 =0 ; +int d1 = temppoints[0 ].d1;int i; -for (i =1 ; i <ARRAY_SIZE (temppoints); i++) +for (i =ARRAY_SIZE (temppoints) -1 ; i >0 ; i--)/* Find pointer to interpolate */ if (data->supply_uV > temppoints[i -1 ].vdd) { - d1 = (data->supply_uV/1000 - temppoints[i -1 ].vdd) + d1 = (data->supply_uV - temppoints[i -1 ].vdd) * (temppoints[i].d1 - temppoints[i -1 ].d1) / (temppoints[i].vdd - temppoints[i -1 ].vdd) + temppoints[i -1 ].d1;
PATCH 100/197 hwmon: (sht15) Properly handle the case CONFIG_REGULATOR=n
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit c7a78d2c2e2537fd24903e966f34aae50319d587 upstream.
When CONFIG_REGULATOR isn't set, regulator_get_voltage() returns 0. Properly handle this case by not trusting the value.
--- drivers/hwmon/sht15.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/hwmon/sht15.c +6 -1
@@ -541,7 +541,12 @@ static int __devinit sht15_probe(struct/* If a regulator is available, query what the supply voltage actually is!*/ data->reg =regulator_get (data->dev,"vcc" );if (!IS_ERR (data->reg)) { - data->supply_uV =regulator_get_voltage (data->reg); +int voltage; + + voltage =regulator_get_voltage (data->reg); +if (voltage) + data->supply_uV = voltage; +regulator_enable (data->reg);/* setup a notifier block to update this if another device * causes the voltage to change */
PATCH 101/197 drm/i915: Add no_lvds entry for the Clientron U800
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Bader <[email protected]>
commit 9875557ee8247c3f7390d378c027b45c7535a224 upstream.
This system claims to have a LVDS but has not.
--- drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/i915/intel_lvds.c +8 -0
@@ -885,6 +885,14 @@ static const struct dmi_system_id intel_ DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Clientron U800", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), + DMI_MATCH(DMI_PRODUCT_NAME, "U800"), + }, + }, { }/* terminating entry */ };
PATCH 102/197 drm/radeon/kms: disable the tv encoder when tv/cv is not in use
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit d3a67a43b0460bae3e2ac14092497833344ac10d upstream.
Switching between TV and VGA caused VGA to break on some systems since the TV encoder was left enabled when VGA was used.
fixes fdo bug 25520.
--- drivers/gpu/drm/radeon/radeon_encoders.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_encoders.c +6 -2
@@ -1155,8 +1155,12 @@ radeon_atom_encoder_mode_set(struct drm_case ENCODER_OBJECT_ID_INTERNAL_DAC2 :case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 :atombios_dac_setup (encoder,ATOM_ENABLE ); -if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT |ATOM_DEVICE_CV_SUPPORT )) -atombios_tv_setup (encoder,ATOM_ENABLE ); +if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |ATOM_DEVICE_CV_SUPPORT )) { +if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT |ATOM_DEVICE_CV_SUPPORT )) +atombios_tv_setup (encoder,ATOM_ENABLE ); +else +atombios_tv_setup (encoder,ATOM_DISABLE ); + }break ; }atombios_apply_encoder_quirks (encoder, adjusted_mode);
PATCH 103/197 drm/radeon/kms: fix tv dac conflict resolver
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 08d075116db3592db218bfe0f554cd93c9e12505 upstream.
On systems with the tv dac shared between DVI and TV, we can only use the dac for one of the connectors. However, when using a digital monitor on the DVI port, you can use the dac for the TV connector just fine. Check the use_digital status when resolving the conflict.
Fixes fdo bug 27649, possibly others.
--- drivers/gpu/drm/radeon/radeon_connectors.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/radeon/radeon_connectors.c +5 -0
@@ -140,12 +140,14 @@ radeon_connector_analog_encoder_conflict {struct drm_device *dev = connector->dev;struct drm_connector *conflict; +struct radeon_connector *radeon_conflict;int i;list_for_each_entry (conflict, &dev->mode_config.connector_list, head) {if (conflict == connector)continue ; + radeon_conflict =to_radeon_connector (conflict);for (i =0 ; i <DRM_CONNECTOR_MAX_ENCODER ; i++) {if (conflict->encoder_ids[i] ==0 )break ;
@@ -155,6 +157,9 @@ radeon_connector_analog_encoder_conflictif (conflict->status != connector_status_connected)continue ; +if (radeon_conflict->use_digital) +continue ; +if (priority == true) {DRM_INFO ("1: conflicting encoders switching off %s\n" ,drm_get_connector_name (conflict));DRM_INFO ("in favor of %s\n" ,drm_get_connector_name (connector));
PATCH 104/197 drm/radeon/kms: fix rs600 tlb flush
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jerome Glisse <[email protected]>
commit 30f69f3fb20bd719b5e1bf879339914063d38f47 upstream.
Typo in in flush leaded to no flush of the RS600 tlb which ultimately leaded to massive system ram corruption, with this patch everythings seems to work properly.
--- drivers/gpu/drm/radeon/rs600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/rs600.c +1 -1
@@ -57,7 +57,7 @@ void rs600_gart_tlb_flush(struct radeon_WREG32_MC (R_000100_MC_PT0_CNTL , tmp); tmp =RREG32_MC (R_000100_MC_PT0_CNTL ); - tmp |=S_000100_INVALIDATE_ALL_L1_TLBS (1 ) &S_000100_INVALIDATE_L2_CACHE (1 ); + tmp |=S_000100_INVALIDATE_ALL_L1_TLBS (1 ) |S_000100_INVALIDATE_L2_CACHE (1 );WREG32_MC (R_000100_MC_PT0_CNTL , tmp); tmp =RREG32_MC (R_000100_MC_PT0_CNTL );
PATCH 105/197 drm/radeon/kms: add FireMV 2400 PCI ID.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Airlie <[email protected]>
commit 79b9517a33a283c5d9db875c263670ed1e055f7e upstream.
This is an M24/X600 chip.
Quoted 1 line
From RH# 581927
--- include/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+)
include/drm/drm_pciids.h +1 -0
@@ -6,6 +6,7 @@ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
PATCH 106/197 x86/amd-iommu: Use helper function to destroy domain
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joerg Roedel <[email protected]>
commit 8b408fe4f853dcfa18d133aa4cf1d7546b4c3870 upstream.
In the amd_iommu_domain_destroy the protection_domain_free function is partly reimplemented. The 'partly' is the bug here because the domain is not deleted from the domain list. This results in use-after-free errors and data-corruption. Fix it by just using protection_domain_free instead.
--- arch/x86/kernel/amd_iommu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/kernel/amd_iommu.c +1 -3
@@ -2239,9 +2239,7 @@ static void amd_iommu_domain_destroy(strfree_pagetable (domain); -domain_id_free (domain->id); - -kfree (domain); +protection_domain_free (domain); dom->priv =NULL ; }
PATCH 107/197 x86/amd-iommu: enable iommu before attaching devices
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Chris Wright <[email protected]>
commit 75f66533bc883f761a7adcab3281fe3323efbc90 upstream.
Hit another kdump problem as reported by Neil Horman. When initializaing the IOMMU, we attach devices to their domains before the IOMMU is fully (re)initialized. Attaching a device will issue some important invalidations. In the context of the newly kexec'd kdump kernel, the IOMMU may have stale cached data from the original kernel. Because we do the attach too early, the invalidation commands are placed in the new command buffer before the IOMMU is updated w/ that buffer. This leaves the stale entries in the kdump context and can renders device unusable. Simply enable the IOMMU before we do the attach.
--- arch/x86/kernel/amd_iommu_init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/x86/kernel/amd_iommu_init.c +4 -2
@@ -1284,6 +1284,8 @@ int __init amd_iommu_init(void)if (ret) goto free; +enable_iommus (); +if (iommu_pass_through) ret =amd_iommu_init_passthrough ();else
@@ -1294,8 +1296,6 @@ int __init amd_iommu_init(void)amd_iommu_init_api (); -enable_iommus (); -if (iommu_pass_through) goto out;
@@ -1314,6 +1314,8 @@ out:return ret; free: +disable_iommus (); +free_pages ((unsigned long )amd_iommu_pd_alloc_bitmap,get_order (MAX_DOMAIN_ID /8 ));
PATCH 108/197 Revert "x86: disable IOMMUs on kernel crash"
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Chris Wright <[email protected]>
commit 8f9f55e83e939724490d7cde3833c4883c6d1310 upstream.
This effectively reverts commit 61d047be99757fd9b0af900d7abce9a13a337488.
Disabling the IOMMU can potetially allow DMA transactions to complete without being translated. Leave it enabled, and allow crash kernel to do the IOMMU reinitialization properly.
--- arch/x86/kernel/crash.c | 6 ------ 1 file changed, 6 deletions(-)
arch/x86/kernel/crash.c +0 -6
@@ -27,7 +27,6 @@#include <asm/cpu.h> #include <asm/reboot.h> #include <asm/virtext.h> -#include <asm/iommu.h> #if defined(CONFIG_SMP ) && defined(CONFIG_X86_LOCAL_APIC )
@@ -104,10 +103,5 @@ void native_machine_crash_shutdown(struc#ifdef CONFIG_HPET_TIMER hpet_disable ();#endif - -#ifdef CONFIG_X86_64 -pci_iommu_shutdown (); -#endif -crash_save_cpu (regs,safe_smp_processor_id ()); }
PATCH 109/197 x86, lib: Add wbinvd smp helpers
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit a7b480e7f30b3813353ec009f10f2ac7a6669f3b upstream.
Add wbinvd_on_cpu and wbinvd_on_all_cpus stubs for executing wbinvd on a particular CPU.
[ hpa: renamed lib/smp.c to lib/cache-smp.c ]
[ hpa: wbinvd_on_all_cpus() returns int, but wbinvd() returns
void. Thus, the former cannot be a macro for the latter, replace with an inline function. ]
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/smp.h | 9 +++++++++ arch/x86/lib/Makefile | 2 +- arch/x86/lib/cache-smp.c | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-)
arch/x86/include/asm/smp.h +9 -0
@@ -135,6 +135,8 @@ int native_cpu_disable(void);void native_cpu_die (unsigned int cpu);void native_play_dead (void );void play_dead_common (void ); +void wbinvd_on_cpu (int cpu); +int wbinvd_on_all_cpus (void );void native_send_call_func_ipi (const struct cpumask *mask);void native_send_call_func_single_ipi (int cpu);
@@ -147,6 +149,13 @@ static inline int num_booting_cpus(void) {return cpumask_weight (cpu_callout_mask); } +#else /* !CONFIG_SMP */ +#define wbinvd_on_cpu (cpu) wbinvd() +static inline int wbinvd_on_all_cpus (void ) +{ +wbinvd (); +return 0 ; +}#endif /* CONFIG_SMP */ extern unsigned disabled_cpus__cpuinitdata ;
arch/x86/lib/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for x86 specific library files. # -obj-$(CONFIG_SMP) += msr-smp.o +obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o lib-y := delay.o lib-y += thunk_$(BITS).o
arch/x86/lib/cache-smp.c new file +19 -0
@@ -0,0 +1,19 @@ +#include <linux/smp.h> +#include <linux/module.h> + +static void __wbinvd (void *dummy) +{ +wbinvd (); +} + +void wbinvd_on_cpu (int cpu) +{ +smp_call_function_single (cpu, __wbinvd,NULL ,1 ); +} +EXPORT_SYMBOL (wbinvd_on_cpu); + +int wbinvd_on_all_cpus (void ) +{ +return on_each_cpu (__wbinvd,NULL ,1 ); +} +EXPORT_SYMBOL (wbinvd_on_all_cpus);
PATCH 110/197 x86, cacheinfo: Fix disabling of L3 cache indices
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit dcf39daf3d6d97f8741e82f0b9fb7554704ed2d1 upstream.
* Correct the masks used for writing the cache index disable indices.
* Do not turn off L3 scrubber - it is not necessary.
* Make sure wbinvd is executed on the same node where the L3 is.
* Check for out-of-bounds values written to the registers.
* Make show_cache_disable hex values unambiguous
* Check for Erratum #388
LKML-Reference: <[email protected]>
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +21 -13
@@ -18,6 +18,7 @@#include <asm/processor.h> #include <linux/smp.h> #include <asm/k8.h> +#include <asm/smp.h> #define LVL_1_INST 1#define LVL_1_DATA 2
@@ -299,8 +300,10 @@ amd_check_l3_disable(int index, struct _if (boot_cpu_data.x86 ==0x11 )return ; -/* see erratum #382 */ -if ((boot_cpu_data.x86 ==0x10 ) && (boot_cpu_data.x86_model <0x8 )) +/* see errata #382 and #388 */ +if ((boot_cpu_data.x86 ==0x10 ) && + ((boot_cpu_data.x86_model <0x9 ) || + (boot_cpu_data.x86_mask <0x1 )))return ; this_leaf->can_disable =1 ;
@@ -741,12 +744,12 @@ static ssize_t show_cache_disable(structreturn -EINVAL ;pci_read_config_dword (dev,0x1BC + index *4 , ®); -return sprintf (buf,"%x\n" , reg); +return sprintf (buf,"0x%08x\n" , reg); }#define SHOW_CACHE_DISABLE (index) \ static ssize_t \ -show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ +show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ { \ return show_cache_disable(this_leaf, buf, index); \ }
@@ -760,7 +763,9 @@ static ssize_t store_cache_disable(strucint node =cpu_to_node (cpu);struct pci_dev *dev =node_to_k8_nb_misc (node);unsigned long val =0 ; -unsigned int scrubber =0 ; + +#define SUBCACHE_MASK (3UL << 20) +#define SUBCACHE_INDEX 0xfffif (!this_leaf->can_disable)return -EINVAL ;
@@ -774,21 +779,24 @@ static ssize_t store_cache_disable(strucif (strict_strtoul (buf,10 , &val) <0 )return -EINVAL ; - val |=0xc0000000 ; - -pci_read_config_dword (dev,0x58 , &scrubber); - scrubber &= ~0x1f000000 ; -pci_write_config_dword (dev,0x58 , scrubber); +/* do not allow writes outside of allowed bits */ +if (val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) +return -EINVAL ; -pci_write_config_dword (dev,0x1BC + index *4 , val & ~0x40000000 ); -wbinvd (); + val |=BIT (30 );pci_write_config_dword (dev,0x1BC + index *4 , val); +/* +* We need to WBINVD on a core on the node containing the L3 cache which +* indices we disable therefore a simple wbinvd() is not sufficient. +*/ +wbinvd_on_cpu (cpu); +pci_write_config_dword (dev,0x1BC + index *4 , val |BIT (31 ));return count; }#define STORE_CACHE_DISABLE (index) \ static ssize_t \ -store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ +store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ const char *buf, size_t count) \ { \ return store_cache_disable(this_leaf, buf, count, index); \
PATCH 111/197 intel-agp: Switch to wbinvd_on_all_cpus
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit 48a719c238bcbb72d6da79de9c5b3b93ab472107 upstream.
Simplify if-statement while at it.
[ hpa: we need to #include <asm/smp.h> ]
LKML-Reference: <[email protected]>
--- drivers/char/agp/intel-agp.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
drivers/char/agp/intel-agp.c +4 -11
@@ -8,6 +8,7 @@#include <linux/kernel.h> #include <linux/pagemap.h> #include <linux/agp_backend.h> +#include <asm/smp.h> #include "agp.h" /*
@@ -815,12 +816,6 @@ static void intel_i830_setup_flush(void)intel_i830_fini_flush (); } -static void -do_wbinvd (void *null) -{ -wbinvd (); -} -/* The chipset_flush interface needs to get data that has already been * flushed out of the CPU all the way out to main memory, because the GPU * doesn't snoop those buffers.
@@ -837,12 +832,10 @@ static void intel_i830_chipset_flush(strmemset (pg,0 ,1024 ); -if (cpu_has_clflush) { +if (cpu_has_clflush)clflush_cache_range (pg,1024 ); - }else { -if (on_each_cpu (do_wbinvd,NULL ,1 ) !=0 ) -printk (KERN_ERR "Timed out waiting for cache flush.\n" ); - } +else if (wbinvd_on_all_cpus () !=0 ) +printk (KERN_ERR "Timed out waiting for cache flush.\n" ); }/* The intel i830 automatically initializes the agp aperture during POST.
PATCH 112/197 x86, cacheinfo: Add cache index disable sysfs attrs only to L3 caches
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit 897de50e08937663912c86fb12ad7f708af2386c upstream.
The cache_disable_[01] attribute in
/sys/devices/system/cpu/cpu?/cache/index[0-3]/
is enabled on all cache levels although only L3 supports it. Add it only to the cache level that actually supports it.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 35 +++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +26 -9
@@ -829,16 +829,24 @@ static struct _cache_attr cache_disable_static struct _cache_attr cache_disable_1 =__ATTR (cache_disable_1,0644 , show_cache_disable_1, store_cache_disable_1); +#define DEFAULT_SYSFS_CACHE_ATTRS \ + &type.attr, \ + &level.attr, \ + &coherency_line_size.attr, \ + &physical_line_partition.attr, \ + &ways_of_associativity.attr, \ + &number_of_sets.attr, \ + &size.attr, \ + &shared_cpu_map.attr, \ + &shared_cpu_list.attr +static struct attribute *default_attrs[] = { - &type.attr, - &level.attr, - &coherency_line_size.attr, - &physical_line_partition.attr, - &ways_of_associativity.attr, - &number_of_sets.attr, - &size.attr, - &shared_cpu_map.attr, - &shared_cpu_list.attr, +DEFAULT_SYSFS_CACHE_ATTRS , +NULL +}; + +static struct attribute *default_l3_attrs[] = { +DEFAULT_SYSFS_CACHE_ATTRS , &cache_disable_0.attr, &cache_disable_1.attr,NULL
@@ -931,6 +939,7 @@ static int __cpuinit cache_add_dev(strucunsigned int cpu = sys_dev->id;unsigned long i, j;struct _index_kobject *this_object; +struct _cpuid4_info *this_leaf;int retval; retval =cpuid4_cache_sysfs_init (cpu);
@@ -949,6 +958,14 @@ static int __cpuinit cache_add_dev(struc this_object =INDEX_KOBJECT_PTR (cpu, i); this_object->cpu = cpu; this_object->index = i; + + this_leaf =CPUID4_INFO_IDX (cpu, i); + +if (this_leaf->can_disable) + ktype_cache.default_attrs = default_l3_attrs; +else + ktype_cache.default_attrs = default_attrs; + retval = kobject_init_and_add(&(this_object->kobj), &ktype_cache, per_cpu(cache_kobject, cpu),
PATCH 113/197 x86, cacheinfo: Calculate L3 indices
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit 048a8774ca43488d78605031f11cc206d7a2682a upstream.
We need to know the valid L3 indices interval when disabling them over /sysfs. Do that when the core is brought online and add boundary checks to the sysfs .store attribute.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 35 ++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +31 -4
@@ -151,7 +151,8 @@ struct _cpuid4_info {union _cpuid4_leaf_ebx ebx;union _cpuid4_leaf_ecx ecx;unsigned long size; -unsigned long can_disable; +bool can_disable; +unsigned int l3_indices;DECLARE_BITMAP (shared_cpu_map,NR_CPUS ); };
@@ -161,7 +162,8 @@ struct _cpuid4_info_regs {union _cpuid4_leaf_ebx ebx;union _cpuid4_leaf_ecx ecx;unsigned long size; -unsigned long can_disable; +bool can_disable; +unsigned int l3_indices; };unsigned short num_cache_leaves;
@@ -291,6 +293,29 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_ (ebx->split.ways_of_associativity +1 ) -1 ; } +static unsigned int __cpuinit amd_calc_l3_indices (void ) +{ +/* +* We're called over smp_call_function_single() and therefore +* are on the correct cpu. +*/ +int cpu =smp_processor_id (); +int node =cpu_to_node (cpu); +struct pci_dev *dev =node_to_k8_nb_misc (node); +unsigned int sc0, sc1, sc2, sc3; +u32 val; + +pci_read_config_dword (dev,0x1C4 , &val); + +/* calculate subcache sizes */ + sc0 = !(val &BIT (0 )); + sc1 = !(val &BIT (4 )); + sc2 = !(val &BIT (8 )) + !(val &BIT (9 )); + sc3 = !(val &BIT (12 )) + !(val &BIT (13 )); + +return (max (max (max (sc0, sc1), sc2), sc3) <<10 ) -1 ; +} +static void __cpuinit amd_check_l3_disable (int index,struct _cpuid4_info_regs *this_leaf) {
@@ -306,7 +331,8 @@ amd_check_l3_disable(int index, struct _ (boot_cpu_data.x86_mask < 0x1)))return ; - this_leaf->can_disable =1 ; + this_leaf->can_disable = true; + this_leaf->l3_indices =amd_calc_l3_indices (); } static int
@@ -780,7 +806,8 @@ static ssize_t store_cache_disable(strucreturn -EINVAL ;/* do not allow writes outside of allowed bits */ -if (val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) +if ((val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) || + ((val &SUBCACHE_INDEX ) > this_leaf->l3_indices))return -EINVAL ; val |=BIT (30 );
Re: [113/197] x86, cacheinfo: Calculate L3 indices
[ added some more CCs ]
Quoted 50 lines · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit
048a8774ca43488d78605031f11cc206d7a2682aupstream.We need to know the valid L3 indices interval when disabling them over /sysfs. Do that when the core is brought online and add boundary checks to the sysfs .store attribute.
Signed-off-by Borislav Petkov <[email protected]>LKML-Reference: <[email protected]>
Signed-off-by H. Peter Anvin <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- arch/x86/kernel/cpu/intel_cacheinfo.c | 35 ++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-)arch/x86/kernel/cpu/intel_cacheinfo.c +7
-2@@ -151,7 +151,8 @@ struct _cpuid4_info {union _cpuid4_leaf_ebx ebx;union _cpuid4_leaf_ecx ecx;unsigned long size; -unsigned long can_disable; +bool can_disable; +unsigned int l3_indices;DECLARE_BITMAP (shared_cpu_map,NR_CPUS ); };@@ -161,7 +162,8 @@ struct _cpuid4_info_regs {union _cpuid4_leaf_ebx ebx;union _cpuid4_leaf_ecx ecx;unsigned long size; -unsigned long can_disable; +bool can_disable; +unsigned int l3_indices; };unsigned short num_cache_leaves;@@ -291,6 +293,29 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_ (ebx->split.ways_of_associativity +1 ) -1 ; } +static unsigned int __cpuinit amd_calc_l3_indices (void ) +{ +/*
arch/x86/kernel/cpu/intel_cacheinfo.c amd_cpuid4(int leaf, union _cpuid4_leaf_ · line 308
Quoted 10 lines
arch/x86/kernel/cpu/intel_cacheinfo.c +10
-0+* We're called over smp_call_function_single() and therefore +* are on the correct cpu. +*/ +int cpu =smp_processor_id (); +int node =cpu_to_node (cpu); +struct pci_dev *dev =node_to_k8_nb_misc (node); +unsigned int sc0, sc1, sc2, sc3; +u32 val; + +pci_read_config_dword (dev,0x1C4 , &val);
This is broken -- the code doesn't handle the case of node_to_k8_nb_misc() returning NULL, causing NULL pointer dereference in pci_read_config_dword() in such case.
[ ... snip ... ]
arch/x86/kernel/cpu/intel_cacheinfo.c static ssize_t store_cache_disable(struc · line 813
Quoted 11 lines
arch/x86/kernel/cpu/intel_cacheinfo.c +2
-1@@ -780,7 +806,8 @@ static ssize_t store_cache_disable(strucreturn -EINVAL ;/* do not allow writes outside of allowed bits */ -if (val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) +if ((val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) || + ((val &SUBCACHE_INDEX ) > this_leaf->l3_indices))return -EINVAL ; val |=BIT (30 );
Please consider applying the patch below, both for 2.6.34 and all the -stable kernels this patch has hit.
From: Jiri Kosina <[email protected]>
Subject: [PATCH] x86, cacheinfo: fix oops in amd_calc_l3_indices()
Commit 048a8774ca4348 ("x86, cacheinfo: Calculate L3 indices") introduced amd_calc_l3_indices(), but this function doesn't properly handle case when node_to_k8_nb_misc() returns NULL, causing immediate oops due to NULL pointer dereference in pci_read_config_dword().
Make amd_calc_l3_indices() return -1 in such cases. This is correct lower bound, as it will make store_cache_disable() return EINVAL in all such cases.
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +3 -0
@@ -314,6 +314,9 @@ static unsigned int __cpuinit amd_calc_l3_indices(void)unsigned int sc0, sc1, sc2, sc3;u32 val =0 ; +if (!dev) +return -1 ; +pci_read_config_dword (dev,0x1C4 , &val);/* calculate subcache sizes */
Signature · 1 line
1.6.4.2
Re: [113/197] x86, cacheinfo: Calculate L3 indices
From: Jiri Kosina <[email protected]>
Date: Wed, May 05, 2010 at 12:26:19PM -0400
Quoted 28 lines
Please consider applying the patch below, both for 2.6.34 and all the -stable kernels this patch has hit.
From: Jiri Kosina <[email protected]>
Subject: [PATCH] x86, cacheinfo: fix oops inamd_calc_l3_indices()Commit
048a8774ca4348("x86, cacheinfo: Calculate L3 indices") introducedamd_calc_l3_indices(), but this function doesn't properly handle case whennode_to_k8_nb_misc()returns NULL, causing immediate oops due to NULL pointer dereference inpci_read_config_dword().Make
amd_calc_l3_indices()return -1 in such cases. This is correct lower bound, as it will makestore_cache_disable()return EINVAL in all such cases.Signed-off-by Jiri Kosina <[email protected]>--- arch/x86/kernel/cpu/intel_cacheinfo.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)arch/x86/kernel/cpu/intel_cacheinfo.c +0
-0
arch/x86/kernel/cpu/intel_cacheinfo.c static unsigned int __cpuinit amd_calc_l3_indices(void) · line 319
Quoted 6 lines
arch/x86/kernel/cpu/intel_cacheinfo.c +3
-0@@ -314,6 +314,9 @@ static unsigned int __cpuinit amd_calc_l3_indices(void)unsigned int sc0, sc1, sc2, sc3;u32 val =0 ; +if (!dev) +return -1 ; +
This won't fly since the function returns an unsigned value and the L3 code would still be entered, which is what you don't want actually when k8_northbridges initialization has somehow failed.
Rather, we have a fix already which should take care of your issue too, see http://git.kernel.org/tip/f2b20e41407fccfcfacf927ff91ec888832a37af
I was waiting for it to hit mainline before I backport it to stable and it would be helpful if you could verify that it works for you along with 0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9 you sent earlier.
Thanks.
Signature · 6 lines
Regards/Gruss, Boris. -- Advanced Micro Devices, Inc. Operating Systems Research Center
Re: [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 26 lines · Borislav Petkov
Quoted 26 lines
From: Jiri Kosina <[email protected]>
Subject: [PATCH] x86, cacheinfo: fix oops inamd_calc_l3_indices()Commit
048a8774ca4348("x86, cacheinfo: Calculate L3 indices") introducedamd_calc_l3_indices(), but this function doesn't properly handle case whennode_to_k8_nb_misc()returns NULL, causing immediate oops due to NULL pointer dereference inpci_read_config_dword().Make
amd_calc_l3_indices()return -1 in such cases. This is correct lower bound, as it will makestore_cache_disable()return EINVAL in all such cases.Signed-off-by Jiri Kosina <[email protected]>--- arch/x86/kernel/cpu/intel_cacheinfo.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)arch/x86/kernel/cpu/intel_cacheinfo.c +0
-0@@ -314,6 +314,9 @@ static unsigned int __cpuinit amd_calc_l3_indices(void)unsigned int sc0, sc1, sc2, sc3;u32 val =0 ;
Quoted 7 lines
arch/x86/kernel/cpu/intel_cacheinfo.c static unsigned int __cpuinit amd_calc_l3_indices(void) · line 319
Quoted 3 lines
arch/x86/kernel/cpu/intel_cacheinfo.c +3
-0+if (!dev) +return -1 ; +This won't fly since the function returns an unsigned value and the L3 code would still be entered, which is what you don't want actually when
k8_northbridgesinitialization has somehow failed.
Yeah, you are right, returning -1 is bogus as well.
The point is though, that we really should be checking for return value of node_to_k8_nb_misc() as it can legitimately return NULL, can't it? (and other places, such as show_cache_disable() and store_cache_disable(), are checking for this being NULL properly).
Quoted 6 lines
Rather, we have a fix already which should take care of your issue too, see http://git.kernel.org/tip/f2b20e41407fccfcfacf927ff91ec888832a37af
I was waiting for it to hit mainline before I backport it to stable and it would be helpful if you could verify that it works for you along with
0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9you sent earlier.
Will let you know.
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs, Novell Inc.
Re: [113/197] x86, cacheinfo: Calculate L3 indices
From: Jiri Kosina <[email protected]>
Date: Wed, May 05, 2010 at 05:33:45PM -0400
Quoted 6 lines
Yeah, you are right, returning -1 is bogus as well.
The point is though, that we really should be checking for return value of
node_to_k8_nb_misc()as it can legitimately return NULL, can't it? (and other places, such asshow_cache_disable()andstore_cache_disable(), are checking for this being NULL properly).
Well, I don't like sprinkling NULL ptr checks all over the place - this makes the code unreadable and means that there's something wrong with its design in the first place.
Therefore, it is better IMO to verify whether the K8_NB thing is initialized properly and exit early if not. And this is what the two patches I'm suggesting try to accomplish:
1. Call into K8_NB on AMD unconditionally so that we have those initialized (we'll be needing them more in the future, I guess)
2. Check in the L3 cache code whether K8_NB has initted properly and bail out if not.
With this, no need for NULL ptr checks anywhere and you got better/smaller/more readable code with the proper assumptions in place.
Thanks.
Signature · 6 lines
Regards/Gruss, Boris. -- Advanced Micro Devices, Inc. Operating Systems Research Center
Re: [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 13 lines · Borislav Petkov
Quoted 4 lines
The point is though, that we really should be checking for return value of
node_to_k8_nb_misc()as it can legitimately return NULL, can't it? (and other places, such asshow_cache_disable()andstore_cache_disable(), are checking for this being NULL properly).Well, I don't like sprinkling NULL ptr checks all over the place - this makes the code unreadable and means that there's something wrong with its design in the first place.
Therefore, it is better IMO to verify whether the
K8_NBthing is initialized properly and exit early if not. And this is what the two patches I'm suggesting try to accomplish:
Quoted 8 lines
1. Call into
K8_NBon AMD unconditionally so that we have those initialized (we'll be needing them more in the future, I guess)2. Check in the L3 cache code whether
K8_NBhas initted properly and bail out if not.With this, no need for NULL ptr checks anywhere and you got better/smaller/more readable code with the proper assumptions in place.
Well, we have
#ifdef CONFIG_K8_NB
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
}
#else
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
return NULL;
}
#endifSo it legitimately returns NULL in two cases:
1) if someone passes too large node
2) if CONFIG_K8_NB is unset
1) Either we assume that node will always be in the range (i.e. amd_get_nb_id() will never go crazy return anything bogus), and then we could just drop the test completely. Or we want to check for such the possibility, and then node_to_k8_nb_misc() is going to return NULL in such cases, and so we want to check for it.
2) is now moot, as all three in-tree callers are now under proper ifdefs (CONFIG_CPU_SUP_AMD, which depends on CONFIG_K8_NB after your patch has been applied). So I believe we could remove it, right?
Either way, current state seems inconsistent. So either we should add the return value check to amd_calc_l3_indices() as well, or remove all the NULL magic altogether, i.e. the (untested) patch below.
What do you think?
From: Jiri Kosina <[email protected]>
Subject: x86, cacheinfo: remove unnecessary NULL pointer checks
As K8_NB thing is now always initialized on AMD CPUs, and we don't have any caller that would be outside CONFIG_CPU_SUP_AMD/CONFIG_K8_NB, it is safe to assume that kb_northbridges has been always initialized).
arch/x86/include/asm/k8.h | 10 +--------- arch/x86/kernel/cpu/intel_cacheinfo.c | 6 ------ 2 files changed, 1 insertions(+), 15 deletions(-)
arch/x86/include/asm/k8.h +1 -9
@@ -15,17 +15,9 @@ extern int k8_get_nodes(struct bootnode *nodes);extern int k8_numa_init (unsigned long start_pfn,unsigned long end_pfn);extern int k8_scan_nodes (void ); -#ifdef CONFIG_K8_NB static inline struct pci_dev *node_to_k8_nb_misc (int node) { -return (node < num_k8_northbridges) ? k8_northbridges[node] :NULL ; +return k8_northbridges[node]; } -#else -static inline struct pci_dev *node_to_k8_nb_misc (int node) -{ -return NULL ; -} -#endif -#endif /* _ASM_X86_K8_H */
arch/x86/kernel/cpu/intel_cacheinfo.c +0 -6
@@ -355,9 +355,6 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,if (!this_leaf->can_disable)return -EINVAL ; -if (!dev) -return -EINVAL ; -pci_read_config_dword (dev,0x1BC + index *4 , ®);return sprintf (buf,"0x%08x\n" , reg); }
@@ -388,9 +385,6 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,if (!capable (CAP_SYS_ADMIN ))return -EPERM ; -if (!dev) -return -EINVAL ; -if (strict_strtoul (buf,10 , &val) <0 )return -EINVAL ;
Signature · 2 lines
Jiri Kosina SUSE Labs, Novell Inc.
Re: [113/197] x86, cacheinfo: Calculate L3 indices
From: Jiri Kosina <[email protected]>
Date: Thu, May 06, 2010 at 09:46:21AM -0400
Quoted 16 lines
Well, we have
#ifdef CONFIG_K8_NB static inline struct pci_dev *node_to_k8_nb_misc(int node) { return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL; } #else static inline struct pci_dev *node_to_k8_nb_misc(int node) { return NULL; } #endifSo it legitimately returns NULL in two cases:
Quoted 8 lines
1) if someone passes too large node
2) ifCONFIG_K8_NBis unset1) Either we assume that node will always be in the range (i.e.
amd_get_nb_id()will never go crazy return anything bogus), and then we could just drop the test completely. Or we want to check for such the possibility, and thennode_to_k8_nb_misc()is going to return NULL in such cases, and so we want to check for it.
No, we want to check it since K8_NB has many users - not only L3.
Quoted 3 lines
2) is now moot, as all three in-tree callers are now under proper ifdefs (
CONFIG_CPU_SUP_AMD, which depends onCONFIG_K8_NBafter your patch has been applied). So I believe we could remove it, right?
I don't think I understand "remove it" here. Which "it" you're referring to?
Quoted 5 lines
Either way, current state seems inconsistent. So either we should add the return value check to
amd_calc_l3_indices()as well, or remove all the NULL magic altogether, i.e. the (untested) patch below.What do you think?
Take a look at
This does
+ if (num_k8_northbridges == 0)
+ return;
in amd_check_l3_disable().
So if K8_NB has failed initializing for some reason, we never go near the pci devs and the node_to_k8_nb_misc() calls since we effectively disable the L3 functionality.
Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
Quoted 67 lines
From: Jiri Kosina <[email protected]>
Subject: x86, cacheinfo: remove unnecessary NULL pointer checksAs
K8_NBthing is now always initialized on AMD CPUs, and we don't have any caller that would be outside CONFIG_CPU_SUP_AMD/CONFIG_K8_NB, it is safe to assume thatkb_northbridgeshas been always initialized).Signed-off-by Jiri Kosina <[email protected]>arch/x86/include/asm/k8.h | 10 +--------- arch/x86/kernel/cpu/intel_cacheinfo.c | 6 ------ 2 files changed, 1 insertions(+), 15 deletions(-)arch/x86/include/asm/k8.h +1
-9@@ -15,17 +15,9 @@ extern int k8_get_nodes(struct bootnode *nodes);extern int k8_numa_init (unsigned long start_pfn,unsigned long end_pfn);extern int k8_scan_nodes (void ); -#ifdef CONFIG_K8_NB static inline struct pci_dev *node_to_k8_nb_misc (int node) { -return (node < num_k8_northbridges) ? k8_northbridges[node] :NULL ; +return k8_northbridges[node]; } -#else -static inline struct pci_dev *node_to_k8_nb_misc (int node) -{ -return NULL ; -} -#endif -#endif /* _ASM_X86_K8_H */ arch/x86/kernel/cpu/intel_cacheinfo.c +0
-6@@ -355,9 +355,6 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,if (!this_leaf->can_disable)return -EINVAL ; -if (!dev) -return -EINVAL ; -pci_read_config_dword (dev,0x1BC + index *4 , ®);return sprintf (buf,"0x%08x\n" , reg); }@@ -388,9 +385,6 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,if (!capable (CAP_SYS_ADMIN ))return -EPERM ; -if (!dev) -return -EINVAL ; -if (strict_strtoul (buf,10 , &val) <0 )return -EINVAL ;Signature · 3 lines
-- Jiri Kosina SUSE Labs, Novell Inc.
Signature · 6 lines
Regards/Gruss, Boris. -- Advanced Micro Devices, Inc. Operating Systems Research Center
Re: [stable] [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 53 lines · Borislav Petkov
From: Jiri Kosina <[email protected]>
Date: Thu, May 06, 2010 at 09:46:21AM -0400Quoted 16 lines
Well, we have
#ifdef CONFIG_K8_NB static inline struct pci_dev *node_to_k8_nb_misc(int node) { return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL; } #else static inline struct pci_dev *node_to_k8_nb_misc(int node) { return NULL; } #endifSo it legitimately returns NULL in two cases:
Quoted 8 lines
1) if someone passes too large node
2) ifCONFIG_K8_NBis unset1) Either we assume that node will always be in the range (i.e.
amd_get_nb_id()will never go crazy return anything bogus), and then we could just drop the test completely. Or we want to check for such the possibility, and thennode_to_k8_nb_misc()is going to return NULL in such cases, and so we want to check for it.No, we want to check it since
K8_NBhas many users - not only L3.Quoted 3 lines
2) is now moot, as all three in-tree callers are now under proper ifdefs (
CONFIG_CPU_SUP_AMD, which depends onCONFIG_K8_NBafter your patch has been applied). So I believe we could remove it, right?I don't think I understand "remove it" here. Which "it" you're referring to?
Quoted 5 lines
Either way, current state seems inconsistent. So either we should add the return value check to
amd_calc_l3_indices()as well, or remove all the NULL magic altogether, i.e. the (untested) patch below.What do you think?
Take a look at
This does
(quoted diff) +2
-0+ if (num_k8_northbridges == 0) + return;in
amd_check_l3_disable().
Quoted 7 lines
So if
K8_NBhas failed initializing for some reason, we never go near the pci devs and thenode_to_k8_nb_misc()calls since we effectively disable the L3 functionality.Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
So, was there ever a patch applied that fixed the bug that Jiri found in the stable kernels with this original patch that I could apply?
thanks,
greg k-h
H. Peter Anvin
reviewerRe: [stable] [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 5 lines · Greg KH
Quoted 5 lines
So if
K8_NBhas failed initializing for some reason, we never go near the pci devs and thenode_to_k8_nb_misc()calls since we effectively disable the L3 functionality.
Quoted 7 lines
Quoted 3 lines
Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
So, was there ever a patch applied that fixed the bug that Jiri found in the stable kernels with this original patch that I could apply?
Sounds like this patch in -tip should be promoted to mainline/stable... could the AMD people please confirm?
-hpa
H. Peter Anvin
reviewerRe: [stable] [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 10 lines · H. Peter Anvin
Quoted 9 lines · Greg KH
Quoted 8 lines
So if
K8_NBhas failed initializing for some reason, we never go near the pci devs and thenode_to_k8_nb_misc()calls since we effectively disable the L3 functionality.Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
Quoted 7 lines
Quoted 3 lines
So, was there ever a patch applied that fixed the bug that Jiri found in the stable kernels with this original patch that I could apply?
Sounds like this patch in -tip should be promoted to mainline/stable... could the AMD people please confirm?
Specifically, "waiting to hit mainline" is not an option since they are currently queued for .35, but we need a minimal fix in .34 -- this is the "stable backport". If this "stable backport" is simply a subset of the patch series then let me know which ones should be moved to urgent and sent to Linus immediately. I obviously don't have access to a setup which can replicate this particular problem.
-hpa
Re: [stable] [113/197] x86, cacheinfo: Calculate L3 indices
Quoted 16 lines · H. Peter Anvin
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
So if
K8_NBhas failed initializing for some reason, we never go near the pci devs and thenode_to_k8_nb_misc()calls since we effectively disable the L3 functionality.Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
Quoted 7 lines
Quoted 3 lines
So, was there ever a patch applied that fixed the bug that Jiri found in the stable kernels with this original patch that I could apply?
Sounds like this patch in -tip should be promoted to mainline/stable... could the AMD people please confirm?
Quoted 6 lines
Specifically, "waiting to hit mainline" is not an option since they are currently queued for .35, but we need a minimal fix in .34 -- this is the "stable backport". If this "stable backport" is simply a subset of the patch series then let me know which ones should be moved to urgent and sent to Linus immediately. I obviously don't have access to a setup which can replicate this particular problem.
One is already there -- 0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9. This particular one solely was enough to fix the problem I have been hitting.
Plus there is f2b20e41407fccfcf ("x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments") in -tip tree, which fixes a crash of similar nature I have been seeing on bare metal, but for virtualized environments.
This one might be considered for .34/stable still.
Signature · 2 lines
Jiri Kosina SUSE Labs, Novell Inc.
Re: [stable] [113/197] x86, cacheinfo: Calculate L3 indices
From: Jiri Kosina <[email protected]>
Date: Thu, May 13, 2010 at 01:26:15AM -0400
Quoted 25 lines · H. Peter Anvin
Quoted 17 lines
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
So if
K8_NBhas failed initializing for some reason, we never go near the pci devs and thenode_to_k8_nb_misc()calls since we effectively disable the L3 functionality.Thus the NULL pointer checks you remove in the patch below are superfluous, I agree, and I have already removed those in my tree along with the other improvements/fixes I'm working on right now.
Quoted 7 lines
Quoted 3 lines
So, was there ever a patch applied that fixed the bug that Jiri found in the stable kernels with this original patch that I could apply?
Sounds like this patch in -tip should be promoted to mainline/stable... could the AMD people please confirm?
Quoted 6 lines
Specifically, "waiting to hit mainline" is not an option since they are currently queued for .35, but we need a minimal fix in .34 -- this is the "stable backport". If this "stable backport" is simply a subset of the patch series then let me know which ones should be moved to urgent and sent to Linus immediately. I obviously don't have access to a setup which can replicate this particular problem.
Quoted 8 lines
One is already there --
0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9. This particular one solely was enough to fix the problem I have been hitting.Plus there is
f2b20e41407fccfcf("x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments") in -tip tree, which fixes a crash of similar nature I have been seeing on bare metal, but for virtualized environments.
This one might be considered for .34/stable still.
Correct, so 0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9 is in mainline and makes sure we cache the k8 northbridges before using them in other code and f2b20e41407fccfcf is an early-exit kludge in case we're running as a guest and we get no northbirdge PCI devices exported from the hypervisor.
And Peter you're right, "waiting for mainline" is not an excuse here, the last one (f2b20e41407fccfcf) should've been sent to Linus right away. However, he said -rc7 is gonna be the last one so I'm hoping there's still time to get it in.
Thanks.
Signature · 6 lines
Regards/Gruss, Boris. -- Advanced Micro Devices, Inc. Operating Systems Research Center
PATCH 114/197 x86, cacheinfo: Remove NUMA dependency, fix for AMD Fam10h rev D1
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit f619b3d8427eb57f0134dab75b0d217325c72411 upstream.
The show/store_cache_disable routines depend unnecessarily on NUMA's cpu_to_node and the disabling of cache indices broke when !CONFIG_NUMA. Remove that dependency by using a helper which is always correct.
While at it, enable L3 Cache Index disable on rev D1 Istanbuls which sport the feature too.
LKML-Reference: <20100218184339.GG20473@aftab>
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +3 -3
@@ -327,7 +327,7 @@ amd_check_l3_disable(int index, struct _/* see errata #382 and #388 */ if ((boot_cpu_data.x86 ==0x10 ) && - ((boot_cpu_data.x86_model <0x9 ) || + ((boot_cpu_data.x86_model <0x8 ) || (boot_cpu_data.x86_mask <0x1 )))return ;
@@ -759,7 +759,7 @@ static ssize_t show_cache_disable(struct unsigned int index) {int cpu =cpumask_first (to_cpumask (this_leaf->shared_cpu_map)); -int node =cpu_to_node (cpu); +int node =amd_get_nb_id (cpu);struct pci_dev *dev =node_to_k8_nb_misc (node);unsigned int reg =0 ;
@@ -786,7 +786,7 @@ static ssize_t store_cache_disable(struc const char *buf, size_t count, unsigned int index) { int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); -int node =cpu_to_node (cpu); +int node =amd_get_nb_id (cpu);struct pci_dev *dev =node_to_k8_nb_misc (node);unsigned long val =0 ;
PATCH 115/197 x86, cacheinfo: Enable L3 CID only on AMD
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
commit cb19060abfdecac0d1eb2d2f0e7d6b7a3f8bc4f4 upstream.
Final stage linking can fail with
arch/x86/built-in.o: In function `store_cache_disable':
intel_cacheinfo.c:(.text+0xc509): undefined reference to amd_get_nb_id' arch/x86/built-in.o: In function show_cache_disable':
intel_cacheinfo.c:(.text+0xc7d3): undefined reference to `amd_get_nb_id'
when CONFIG_CPU_SUP_AMD is not enabled because the amd_get_nb_id helper is defined in AMD-specific code but also used in generic code (intel_cacheinfo.c). Reorganize the L3 cache index disable code under CONFIG_CPU_SUP_AMD since it is AMD-only anyway.
LKML-Reference: <20100218184210.GF20473@aftab>
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 186 +++++++++++++++++----------------- 1 file changed, 98 insertions(+), 88 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +98 -88
@@ -293,6 +293,13 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_ (ebx->split.ways_of_associativity +1 ) -1 ; } +struct _cache_attr { +struct attribute attr; +ssize_t (*show)(struct _cpuid4_info *,char *); +ssize_t (*store)(struct _cpuid4_info *,const char *,size_t count); +}; + +#ifdef CONFIG_CPU_SUP_AMD static unsigned int __cpuinit amd_calc_l3_indices (void ) {/*
@@ -303,7 +310,7 @@ static unsigned int __cpuinit amd_calc_lint node =cpu_to_node (cpu);struct pci_dev *dev =node_to_k8_nb_misc (node);unsigned int sc0, sc1, sc2, sc3; -u32 val; +u32 val =0 ;pci_read_config_dword (dev,0x1C4 , &val);
@@ -335,6 +342,94 @@ amd_check_l3_disable(int index, struct _ this_leaf->l3_indices =amd_calc_l3_indices (); } +static ssize_t show_cache_disable (struct _cpuid4_info *this_leaf,char *buf, +unsigned int index) +{ +int cpu =cpumask_first (to_cpumask (this_leaf->shared_cpu_map)); +int node =amd_get_nb_id (cpu); +struct pci_dev *dev =node_to_k8_nb_misc (node); +unsigned int reg =0 ; + +if (!this_leaf->can_disable) +return -EINVAL ; + +if (!dev) +return -EINVAL ; + +pci_read_config_dword (dev,0x1BC + index *4 , ®); +return sprintf (buf,"0x%08x\n" , reg); +} + +#define SHOW_CACHE_DISABLE (index) \ +static ssize_t \ +show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ +{ \ + return show_cache_disable(this_leaf, buf, index); \ +} +SHOW_CACHE_DISABLE(0) +SHOW_CACHE_DISABLE(1) + +static ssize_t store_cache_disable (struct _cpuid4_info *this_leaf, +const char *buf,size_t count,unsigned int index) +{ +int cpu =cpumask_first (to_cpumask (this_leaf->shared_cpu_map)); +int node =amd_get_nb_id (cpu); +struct pci_dev *dev =node_to_k8_nb_misc (node); +unsigned long val =0 ; + +#define SUBCACHE_MASK (3UL << 20) +#define SUBCACHE_INDEX 0xfff + +if (!this_leaf->can_disable) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (!dev) +return -EINVAL ; + +if (strict_strtoul (buf,10 , &val) <0 ) +return -EINVAL ; + +/* do not allow writes outside of allowed bits */ +if ((val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) || + ((val &SUBCACHE_INDEX ) > this_leaf->l3_indices)) +return -EINVAL ; + + val |=BIT (30 ); +pci_write_config_dword (dev,0x1BC + index *4 , val); +/* +* We need to WBINVD on a core on the node containing the L3 cache which +* indices we disable therefore a simple wbinvd() is not sufficient. +*/ +wbinvd_on_cpu (cpu); +pci_write_config_dword (dev,0x1BC + index *4 , val |BIT (31 )); +return count; +} + +#define STORE_CACHE_DISABLE (index) \ +static ssize_t \ +store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ + const char *buf, size_t count) \ +{ \ + return store_cache_disable(this_leaf, buf, count, index); \ +} +STORE_CACHE_DISABLE(0) +STORE_CACHE_DISABLE(1) + +static struct _cache_attr cache_disable_0 =__ATTR (cache_disable_0,0644 , + show_cache_disable_0, store_cache_disable_0); +static struct _cache_attr cache_disable_1 =__ATTR (cache_disable_1,0644 , + show_cache_disable_1, store_cache_disable_1); + +#else /* CONFIG_CPU_SUP_AMD */ +static void __cpuinit +amd_check_l3_disable (int index,struct _cpuid4_info_regs *this_leaf) +{ +}; +#endif /* CONFIG_CPU_SUP_AMD */ +static int __cpuinit cpuid4_cache_lookup_regs (int index,struct _cpuid4_info_regs *this_leaf)
@@ -755,88 +850,6 @@ static ssize_t show_type(struct _cpuid4_#define to_object (k) container_of(k, struct _index_kobject, kobj)#define to_attr (a) container_of(a, struct _cache_attr, attr) -static ssize_t show_cache_disable (struct _cpuid4_info *this_leaf,char *buf, -unsigned int index) -{ -int cpu =cpumask_first (to_cpumask (this_leaf->shared_cpu_map)); -int node =amd_get_nb_id (cpu); -struct pci_dev *dev =node_to_k8_nb_misc (node); -unsigned int reg =0 ; - -if (!this_leaf->can_disable) -return -EINVAL ; - -if (!dev) -return -EINVAL ; - -pci_read_config_dword (dev,0x1BC + index *4 , ®); -return sprintf (buf,"0x%08x\n" , reg); -} - -#define SHOW_CACHE_DISABLE (index) \ -static ssize_t \ -show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ -{ \ - return show_cache_disable(this_leaf, buf, index); \ -} -SHOW_CACHE_DISABLE(0) -SHOW_CACHE_DISABLE(1) - -static ssize_t store_cache_disable (struct _cpuid4_info *this_leaf, -const char *buf,size_t count,unsigned int index) -{ -int cpu =cpumask_first (to_cpumask (this_leaf->shared_cpu_map)); -int node =amd_get_nb_id (cpu); -struct pci_dev *dev =node_to_k8_nb_misc (node); -unsigned long val =0 ; - -#define SUBCACHE_MASK (3UL << 20) -#define SUBCACHE_INDEX 0xfff - -if (!this_leaf->can_disable) -return -EINVAL ; - -if (!capable (CAP_SYS_ADMIN )) -return -EPERM ; - -if (!dev) -return -EINVAL ; - -if (strict_strtoul (buf,10 , &val) <0 ) -return -EINVAL ; - -/* do not allow writes outside of allowed bits */ -if ((val & ~(SUBCACHE_MASK |SUBCACHE_INDEX )) || - ((val &SUBCACHE_INDEX ) > this_leaf->l3_indices)) -return -EINVAL ; - - val |=BIT (30 ); -pci_write_config_dword (dev,0x1BC + index *4 , val); -/* -* We need to WBINVD on a core on the node containing the L3 cache which -* indices we disable therefore a simple wbinvd() is not sufficient. -*/ -wbinvd_on_cpu (cpu); -pci_write_config_dword (dev,0x1BC + index *4 , val |BIT (31 )); -return count; -} - -#define STORE_CACHE_DISABLE (index) \ -static ssize_t \ -store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ - const char *buf, size_t count) \ -{ \ - return store_cache_disable(this_leaf, buf, count, index); \ -} -STORE_CACHE_DISABLE(0) -STORE_CACHE_DISABLE(1) - -struct _cache_attr { -struct attribute attr; -ssize_t (*show)(struct _cpuid4_info *,char *); -ssize_t (*store)(struct _cpuid4_info *,const char *,size_t count); -}; -#define define_one_ro (_name) \ static struct _cache_attr _name = \ __ATTR(_name, 0444, show_##_name, NULL)
@@ -851,11 +864,6 @@ define_one_ro(size);define_one_ro (shared_cpu_map);define_one_ro (shared_cpu_list); -static struct _cache_attr cache_disable_0 =__ATTR (cache_disable_0,0644 , - show_cache_disable_0, store_cache_disable_0); -static struct _cache_attr cache_disable_1 =__ATTR (cache_disable_1,0644 , - show_cache_disable_1, store_cache_disable_1); -#define DEFAULT_SYSFS_CACHE_ATTRS \ &type.attr, \ &level.attr, \
@@ -874,8 +882,10 @@ static struct attribute *default_attrs[]static struct attribute *default_l3_attrs[] = {DEFAULT_SYSFS_CACHE_ATTRS , +#ifdef CONFIG_CPU_SUP_AMD &cache_disable_0.attr, &cache_disable_1.attr, +#endifNULL };
PATCH 116/197 vgaarb: fix "target=default" passing
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
Commit 77c1ff3982c6b36961725dd19e872a1c07df7f3b fixed the userspace pointer dereference, but introduced another bug pointed out by Eugene Teo in RH bug #564264. Instead of comparing the point we were at in the string, we instead compared the beginning of the string to "default".
--- drivers/gpu/vga/vgaarb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/vga/vgaarb.c +1 -1
@@ -961,7 +961,7 @@ static ssize_t vga_arb_write(struct file remaining -=7 ;pr_devel ("client 0x%p called 'target'\n" , priv);/* if target is default */ -if (!strncmp (buf,"default" ,7 )) +if (!strncmp (curr_pos,"default" ,7 )) pdev =pci_dev_get (vga_default_device ()); else { if (!vga_pci_str_to_vars(curr_pos, remaining,
PATCH 117/197 x86-32: clean up rwsem inline asm statements
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 59c33fa7791e9948ba467c2b83e307a0d087ab49 upstream.
This makes gcc use the right register names and instruction operand sizes automatically for the rwsem inline asm statements.
So instead of using "(%%eax)" to specify the memory address that is the semaphore, we use "(%1)" or similar. And instead of forcing the operation to always be 32-bit, we use "%z0", taking the size from the actual semaphore data structure itself.
This doesn't actually matter on x86-32, but if we want to use the same inline asm for x86-64, we'll need to have the compiler generate the proper 64-bit names for the registers (%rax instead of %eax), and if we want to use a 64-bit counter too (in order to avoid the 15-bit limit on the write counter that limits concurrent users to 32767 threads), we'll need to be able to generate instructions with "q" accesses rather than "l".
Since this header currently isn't enabled on x86-64, none of that matters, but we do want to use the xadd version of the semaphores rather than have to take spinlocks to do a rwsem. The mm->mmap_sem can be heavily contended when you have lots of threads all taking page faults, and the fallback rwsem code that uses a spinlock performs abysmally badly in that case.
[ hpa: modified the patch to skip size suffixes entirely when they are
redundant due to register operands. ]
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/rwsem.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
arch/x86/include/asm/rwsem.h +15 -15
@@ -105,7 +105,7 @@ do { \static inline void __down_read (struct rw_semaphore *sem) { asmvolatile ("# beginning down_read\n\t" -LOCK_PREFIX " incl (%%eax)\n\t" +LOCK_PREFIX " inc%z0 (%1)\n\t" /* adds 0x00000001, returns the old value */ " jns 1f\n" " call call_rwsem_down_read_failed\n"
@@ -123,12 +123,12 @@ static inline int __down_read_trylock(st {__s32 result, tmp; asmvolatile ("# beginning __down_read_trylock\n\t" -" movl %0,%1\n\t" +" mov %0,%1\n\t" "1:\n\t" -" movl %1,%2\n\t" -" addl %3,%2\n\t" +" mov %1,%2\n\t" +" add %3,%2\n\t" " jle 2f\n\t" -LOCK_PREFIX " cmpxchgl %2,%0\n\t" +LOCK_PREFIX " cmpxchg %2,%0\n\t" " jnz 1b\n\t" "2:\n\t" "# ending __down_read_trylock\n\t"
@@ -147,9 +147,9 @@ static inline void __down_write_nested(s tmp =RWSEM_ACTIVE_WRITE_BIAS ; asmvolatile ("# beginning down_write\n\t" -LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" +LOCK_PREFIX " xadd %1,(%2)\n\t" /* subtract 0x0000ffff, returns the old value */ -" testl %%edx,%%edx\n\t" +" test %1,%1\n\t" /* was the count 0 before? */ " jz 1f\n" " call call_rwsem_down_write_failed\n"
@@ -185,7 +185,7 @@ static inline void __up_read(struct rw_s {__s32 tmp = -RWSEM_ACTIVE_READ_BIAS ; asmvolatile ("# beginning __up_read\n\t" -LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" +LOCK_PREFIX " xadd %1,(%2)\n\t" /* subtracts 1, returns the old value */ " jns 1f\n\t" " call call_rwsem_wake\n"
@@ -201,18 +201,18 @@ static inline void __up_read(struct rw_s*/ static inline void __up_write (struct rw_semaphore *sem) { +unsigned long tmp; asmvolatile ("# beginning __up_write\n\t" -" movl %2,%%edx\n\t" -LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" +LOCK_PREFIX " xadd %1,(%2)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ " jz 1f\n" " call call_rwsem_wake\n" "1:\n\t" "# ending __up_write\n" - :"+m" (sem->count) - :"a" (sem),"i" (-RWSEM_ACTIVE_WRITE_BIAS ) - :"memory" ,"cc" ,"edx" ); + :"+m" (sem->count),"=d" (tmp) + :"a" (sem),"1" (-RWSEM_ACTIVE_WRITE_BIAS ) + :"memory" ,"cc" ); }/*
@@ -221,7 +221,7 @@ static inline void __up_write(struct rw_static inline void __downgrade_write (struct rw_semaphore *sem) { asmvolatile ("# beginning __downgrade_write\n\t" -LOCK_PREFIX " addl %2,(%%eax)\n\t" +LOCK_PREFIX " add%z0 %2,(%1)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ " jns 1f\n\t" " call call_rwsem_downgrade_wake\n"
@@ -237,7 +237,7 @@ static inline void __downgrade_write(str*/ static inline void rwsem_atomic_add (int delta,struct rw_semaphore *sem) { - asmvolatile (LOCK_PREFIX "addl %1,%0" + asmvolatile (LOCK_PREFIX "add%z0 %1,%0" :"+m" (sem->count) :"ir" (delta)); }
PATCH 118/197 x86: clean up rwsem type system
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 5d0b7235d83eefdafda300656e97d368afcafc9a upstream.
The fast version of the rwsems (the code that uses xadd) has traditionally only worked on x86-32, and as a result it mixes different kinds of types wildly - they just all happen to be 32-bit. We have "long", we have "__s32", and we have "int".
To make it work on x86-64, the types suddenly matter a lot more. It can be either a 32-bit or 64-bit signed type, and both work (with the caveat that a 32-bit counter will only have 15 bits of effective write counters, so it's limited to 32767 users). But whatever type you choose, it needs to be used consistently.
This makes a new 'rwsem_counter_t', that is a 32-bit signed type. For a 64-bit type, you'd need to also update the BIAS values.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/rwsem.h | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
arch/x86/include/asm/rwsem.h +15 -10
@@ -55,6 +55,9 @@ extern asmregparm struct rw_semaphore */* * the semaphore definition +* +* The bias values and the counter type needs to be extended to 64 bits +* if we want to have more than 32767 potential readers/writers */ #define RWSEM_UNLOCKED_VALUE 0x00000000
@@ -64,8 +67,10 @@ extern asmregparm struct rw_semaphore *#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) +typedef signed int rwsem_count_t ; +struct rw_semaphore { -signed long count; +rwsem_count_t count;spinlock_t wait_lock;struct list_head wait_list;#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -121,7 +126,7 @@ static inline void __down_read(struct rw*/ static inline int __down_read_trylock (struct rw_semaphore *sem) { -__s32 result, tmp; +rwsem_count_t result, tmp; asmvolatile ("# beginning __down_read_trylock\n\t" " mov %0,%1\n\t" "1:\n\t"
@@ -143,7 +148,7 @@ static inline int __down_read_trylock(st*/ static inline void __down_write_nested (struct rw_semaphore *sem,int subclass) { -int tmp; +rwsem_count_t tmp; tmp =RWSEM_ACTIVE_WRITE_BIAS ; asm volatile("# beginning down_write\n\t"
@@ -170,9 +175,9 @@ static inline void __down_write(struct r*/ static inline int __down_write_trylock (struct rw_semaphore *sem) { -signed long ret =cmpxchg (&sem->count, -RWSEM_UNLOCKED_VALUE , -RWSEM_ACTIVE_WRITE_BIAS ); +rwsem_count_t ret =cmpxchg (&sem->count, +RWSEM_UNLOCKED_VALUE , +RWSEM_ACTIVE_WRITE_BIAS );if (ret ==RWSEM_UNLOCKED_VALUE )return 1 ;return 0 ;
@@ -183,7 +188,7 @@ static inline int __down_write_trylock(s*/ static inline void __up_read (struct rw_semaphore *sem) { -__s32 tmp = -RWSEM_ACTIVE_READ_BIAS ; +rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS ; asmvolatile ("# beginning __up_read\n\t" LOCK_PREFIX " xadd %1,(%2)\n\t" /* subtracts 1, returns the old value */
@@ -201,7 +206,7 @@ static inline void __up_read(struct rw_s*/ static inline void __up_write (struct rw_semaphore *sem) { -unsigned long tmp; +rwsem_count_t tmp; asmvolatile ("# beginning __up_write\n\t" LOCK_PREFIX " xadd %1,(%2)\n\t" /* tries to transition
@@ -245,9 +250,9 @@ static inline void rwsem_atomic_add(int/* * implement exchange and add functionality */ -static inline int rwsem_atomic_update (int delta,struct rw_semaphore *sem) +static inline rwsem_count_t rwsem_atomic_update (int delta,struct rw_semaphore *sem) { -int tmp = delta; +rwsem_count_t tmp = delta; asmvolatile (LOCK_PREFIX "xadd %0,%1" : "+r" (tmp), "+m" (sem->count)
PATCH 119/197 x86-64, rwsem: 64-bit xadd rwsem implementation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: H. Peter Anvin <[email protected]>
commit 1838ef1d782f7527e6defe87e180598622d2d071 upstream.
For x86-64, 32767 threads really is not enough. Change rwsem_count_t to a signed long, so that it is 64 bits on x86-64.
This required the following changes to the assembly code:
a) %z0 doesn't work on all versions of gcc! At least gcc 4.4.2 as shipped with Fedora 12 emits "ll" not "q" for 64 bits, even for integer operands. Newer gccs apparently do this correctly, but avoid this problem by using the _ASM_ macros instead of %z.
b) 64 bits immediates are only allowed in "movq $imm,%reg" constructs... no others. Change some of the constraints to "e", and fix the one case where we would have had to use an invalid immediate -- in that case, we only care about the upper half anyway, so just access the upper half.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/rwsem.h | 53 ++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-)
arch/x86/include/asm/rwsem.h +40 -13
@@ -41,6 +41,7 @@#include <linux/list.h> #include <linux/spinlock.h> #include <linux/lockdep.h> +#include <asm/asm.h> struct rwsem_waiter ;
@@ -56,18 +57,24 @@ extern asmregparm struct rw_semaphore */* * the semaphore definition * -* The bias values and the counter type needs to be extended to 64 bits -* if we want to have more than 32767 potential readers/writers +* The bias values and the counter type limits the number of +* potential readers/writers to 32767 for 32 bits and 2147483647 +* for 64 bits. */ -#define RWSEM_UNLOCKED_VALUE 0x00000000 -#define RWSEM_ACTIVE_BIAS 0x00000001 -#define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS (-0x00010000) +#ifdef CONFIG_X86_64 +# define RWSEM_ACTIVE_MASK 0xffffffffL +#else +# define RWSEM_ACTIVE_MASK 0x0000ffffL +#endif + +#define RWSEM_UNLOCKED_VALUE 0x00000000L +#define RWSEM_ACTIVE_BIAS 0x00000001L +#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) -typedef signed int rwsem_count_t ; +typedef signed long rwsem_count_t ;struct rw_semaphore {rwsem_count_t count;
@@ -110,7 +117,7 @@ do { \static inline void __down_read (struct rw_semaphore *sem) { asmvolatile ("# beginning down_read\n\t" -LOCK_PREFIX " inc%z0 (%1)\n\t" +LOCK_PREFIX _ASM_INC"(%1)\n\t" /* adds 0x00000001, returns the old value */ " jns 1f\n" " call call_rwsem_down_read_failed\n"
@@ -225,8 +232,25 @@ static inline void __up_write(struct rw_*/ static inline void __downgrade_write (struct rw_semaphore *sem) { +#ifdef CONFIG_X86_64 +# if RWSEM_WAITING_BIAS !=-0x100000000 +# error "This code assumes RWSEM_WAITING_BIAS == -2^32" +# endif + +/* 64-bit immediates are special and expensive, and not needed here */ + asmvolatile ("# beginning __downgrade_write\n\t" +LOCK_PREFIX "incl 4(%1)\n\t" +/* transitions 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 */ +" jns 1f\n\t" +" call call_rwsem_downgrade_wake\n" +"1:\n\t" +"# ending __downgrade_write\n" + :"+m" (sem->count) + :"a" (sem) + :"memory" ,"cc" ); +#else asmvolatile ("# beginning __downgrade_write\n\t" -LOCK_PREFIX " add%z0 %2,(%1)\n\t" +LOCK_PREFIX _ASM_ADD"%2,(%1)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ " jns 1f\n\t" " call call_rwsem_downgrade_wake\n"
@@ -235,22 +259,25 @@ static inline void __downgrade_write(str : "+m" (sem->count) : "a" (sem), "i" (-RWSEM_WAITING_BIAS) : "memory", "cc"); +#endif }/* * implement atomic add functionality */ -static inline void rwsem_atomic_add (int delta,struct rw_semaphore *sem) +static inline void rwsem_atomic_add (rwsem_count_t delta, +struct rw_semaphore *sem) { - asmvolatile (LOCK_PREFIX "add%z0 %1,%0" + asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" :"+m" (sem->count) - :"ir" (delta)); + :"er" (delta)); }/* * implement exchange and add functionality */ -static inline rwsem_count_t rwsem_atomic_update (int delta,struct rw_semaphore *sem) +static inline rwsem_count_t rwsem_atomic_update (rwsem_count_t delta, +struct rw_semaphore *sem) {rwsem_count_t tmp = delta;
PATCH 120/197 x86-64: support native xadd rwsem implementation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit bafaecd11df15ad5b1e598adc7736afcd38ee13d upstream.
This one is much faster than the spinlock based fallback rwsem code, with certain artifical benchmarks having shown 300%+ improvement on threaded page faults etc.
Again, note the 32767-thread limit here. So this really does need that whole "make rwsem_count_t be 64-bit and fix the BIAS values to match" extension on top of it, but that is conceptually a totally independent issue.
NOT TESTED! The original patch that this all was based on were tested by KAMEZAWA Hiroyuki, but maybe I screwed up something when I created the cleaned-up series, so caveat emptor..
Also note that it _may_ be a good idea to mark some more registers clobbered on x86-64 in the inline asms instead of saving/restoring them. They are inline functions, but they are only used in places where there are not a lot of live registers _anyway_, so doing for example the clobbers of %r8-%r11 in the asm wouldn't make the fast-path code any worse, and would make the slow-path code smaller.
(Not that the slow-path really matters to that degree. Saving a few unnecessary registers is the _least_ of our problems when we hit the slow path. The instruction/cycle counting really only matters in the fast path).
LKML-Reference: <[email protected]>
--- arch/x86/Kconfig.cpu | 2 - arch/x86/lib/Makefile | 1 arch/x86/lib/rwsem_64.S | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-)
arch/x86/Kconfig.cpu +1 -1
@@ -323,7 +323,7 @@ config X86_L1_CACHE_SHIFT config X86_XADD def_bool y - depends on X86_32 && !M386 + depends on X86_64 || !M386 config X86_PPRO_FENCE bool "PentiumPro memory ordering errata workaround"
arch/x86/lib/Makefile +1 -0
@@ -26,4 +26,5 @@ else lib-y += thunk_64.o clear_page_64.o copy_page_64.o lib-y += memmove_64.o memset_64.o lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o + lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o endif
arch/x86/lib/rwsem_64.S new file +81 -0
81 lines not on this page · raw message
PATCH 121/197 x86: Fix breakage of UML from the changes in the rwsem system
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 4126faf0ab7417fbc6eb99fb0fd407e01e9e9dfe upstream.
The patches 5d0b7235d83eefdafda300656e97d368afcafc9a and bafaecd11df15ad5b1e598adc7736afcd38ee13d broke the UML build:
Quoted 14 lines · Ingo Molnar
FYI, -tip testing found that these changes break the UML build:
kernel/built-in.o: In function `__up_read':/home/mingo/tip/arch/x86/include/asm/rwsem.h:192: undefined reference tocall_rwsem_wake' kernel/built-in.o: In function__up_write':/home/mingo/tip/arch/x86/include/asm/rwsem.h:210: undefined reference tocall_rwsem_wake' kernel/built-in.o: In function__downgrade_write':/home/mingo/tip/arch/x86/include/asm/rwsem.h:228: undefined reference tocall_rwsem_downgrade_wake' kernel/built-in.o: In function__down_read':/home/mingo/tip/arch/x86/include/asm/rwsem.h:112: undefined reference tocall_rwsem_down_read_failed' kernel/built-in.o: In function__down_write_nested':/home/mingo/tip/arch/x86/include/asm/rwsem.h:154: undefined reference to `call_rwsem_down_write_failed'
collect2: ld returned 1 exit status
Add lib/rwsem_64.o to the UML subarch objects to fix.
LKML-Reference: <[email protected]>
--- arch/um/sys-x86_64/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/um/sys-x86_64/Makefile +2 -1
@@ -8,7 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ sysrq.o ksyms.o tls.o -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o +subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ + lib/rwsem_64.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o ldt-y = ../sys-i386/ldt.o
PATCH 122/197 x86-64, rwsem: Avoid store forwarding hazard in __downgrade_write
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Avi Kivity <[email protected]>
commit 0d1622d7f526311d87d7da2ee7dd14b73e45d3fc upstream.
The Intel Architecture Optimization Reference Manual states that a short load that follows a long store to the same object will suffer a store forwading penalty, particularly if the two accesses use different addresses. Trivially, a long load that follows a short store will also suffer a penalty.
__downgrade_write() in rwsem incurs both penalties: the increment operation will not be able to reuse a recently-loaded rwsem value, and its result will not be reused by any recently-following rwsem operation.
A comment in the code states that this is because 64-bit immediates are special and expensive; but while they are slightly special (only a single instruction allows them), they aren't expensive: a test shows that two loops, one loading a 32-bit immediate and one loading a 64-bit immediate, both take 1.5 cycles per iteration.
Fix this by changing __downgrade_write to use the same add instruction on i386 and on x86_64, so that it uses the same operand size as all the other rwsem functions.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/rwsem.h | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-)
arch/x86/include/asm/rwsem.h +5 -20
@@ -232,34 +232,19 @@ static inline void __up_write(struct rw_*/ static inline void __downgrade_write (struct rw_semaphore *sem) { -#ifdef CONFIG_X86_64 -# if RWSEM_WAITING_BIAS !=-0x100000000 -# error "This code assumes RWSEM_WAITING_BIAS == -2^32" -# endif - -/* 64-bit immediates are special and expensive, and not needed here */ - asmvolatile ("# beginning __downgrade_write\n\t" -LOCK_PREFIX "incl 4(%1)\n\t" -/* transitions 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 */ -" jns 1f\n\t" -" call call_rwsem_downgrade_wake\n" -"1:\n\t" -"# ending __downgrade_write\n" - :"+m" (sem->count) - :"a" (sem) - :"memory" ,"cc" ); -#else asmvolatile ("# beginning __downgrade_write\n\t" LOCK_PREFIX _ASM_ADD"%2,(%1)\n\t" -/* transitions 0xZZZZ0001 -> 0xYYYY0001 */ +/* +* transitions 0xZZZZ0001 -> 0xYYYY0001 (i386) +* 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64) +*/ " jns 1f\n\t" " call call_rwsem_downgrade_wake\n" "1:\n\t" "# ending __downgrade_write\n" :"+m" (sem->count) - :"a" (sem),"i" (-RWSEM_WAITING_BIAS ) + :"a" (sem),"er" (-RWSEM_WAITING_BIAS ) :"memory" ,"cc" ); -#endif }/*
PATCH 123/197 fix NFS4 handling of mountpoint stat
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Al Viro <[email protected]>
commit 462d60577a997aa87c935ae4521bd303733a9f2b upstream.
RFC says we need to follow the chain of mounts if there's more than one stacked on that point.
--- fs/nfsd/nfs4xdr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/nfsd/nfs4xdr.c +9 -3
@@ -2129,9 +2129,15 @@ out_acl:* and this is the root of a cross-mounted filesystem. */ if (ignore_crossmnt ==0 && - exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) { - err =vfs_getattr (exp->ex_path.mnt->mnt_parent, - exp->ex_path.mnt->mnt_mountpoint, &stat); + dentry == exp->ex_path.mnt->mnt_root) { +struct path path = exp->ex_path; +path_get (&path); +while (follow_up (&path)) { +if (path.dentry != path.mnt->mnt_root) +break ; + } + err =vfs_getattr (path.mnt, path.dentry, &stat); +path_put (&path);if (err) goto out_nfserr; }
PATCH 124/197 dm mpath: fix stall when requeueing io
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Kiyoshi Ueda <[email protected]>
upstream commit 9eef87da2a8ea4920e0d913ff977cac064b68ee0 backported to 2.6.32.10 by Nikanth Karthikesan <[email protected]>
This patch fixes the problem that system may stall if target's ->map_rq returns DM_MAPIO_REQUEUE in map_request().
E.g. stall happens on 1 CPU box when a dm-mpath device with queue_if_no_path
bounces between all-paths-down and paths-up on I/O load.
When target's ->map_rq returns DM_MAPIO_REQUEUE, map_request() requeues the request and returns to dm_request_fn(). Then, dm_request_fn() doesn't exit the I/O dispatching loop and continues processing the requeued request again.
This map and requeue loop can be done with interrupt disabled, so 1 CPU system can be stalled if this situation happens.
For example, commands below can stall my 1 CPU box within 1 minute or so:
# dmsetup table mp mp: 0 2097152 multipath 1 queue_if_no_path 0 1 1 service-time 0 1 2 8:144 1 1 # while true; do dd if=/dev/mapper/mp of=/dev/null bs=1M count=100; done & # while true; do \
Quoted 5 lines
dmsetup message mp 0 "
fail_path8:144" \
dmsetup suspend --noflush mp \
dmsetup resume mp \
dmsetup message mp 0 "reinstate_path8:144" \
done
To fix the problem above, this patch changes dm_request_fn() to exit the I/O dispatching loop once if a request is requeued in map_request().
--- drivers/md/dm.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/md/dm.c +17 -4
@@ -1487,10 +1487,15 @@ static int dm_prep_fn(struct request_quereturn BLKPREP_OK ; } -static void map_request (struct dm_target *ti,struct request *rq, -struct mapped_device *md) +/* +* Returns: +* 0 : the request has been processed (not requeued) +* !0 : the request has been requeued +*/ +static int map_request (struct dm_target *ti,struct request *rq, +struct mapped_device *md) { -int r; +int r, requeued =0 ;struct request *clone = rq->special;struct dm_rq_target_io *tio = clone->end_io_data;
@@ -1516,6 +1521,7 @@ static void map_request(struct dm_targetcase DM_MAPIO_REQUEUE :/* The target wants to requeue the I/O */ dm_requeue_unmapped_request (clone); + requeued =1 ;break ;default :if (r >0 ) {
@@ -1527,6 +1533,8 @@ static void map_request(struct dm_targetdm_kill_unmapped_request (clone, r);break ; } + +return requeued; }/*
@@ -1568,12 +1576,17 @@ static void dm_request_fn(struct requestblk_start_request (rq);spin_unlock (q->queue_lock); -map_request (ti, rq, md); +if (map_request (ti, rq, md)) + goto requeued; +spin_lock_irq (q->queue_lock); } goto out; +requeued: +spin_lock_irq (q->queue_lock); + plug_and_out:if (!elv_queue_empty (q))/* Some requests still remain, retry later */
PATCH 125/197 quota: Fix possible dq_flags corruption
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Perepechko <[email protected]>
commit 08261673cb6dc638c39f44d69b76fffb57b92a8b upstream.
dq_flags are modified non-atomically in do_set_dqblk via __set_bit calls and atomically for example in mark_dquot_dirty or clear_dquot_dirty. Hence a change done by an atomic operation can be overwritten by a change done by a non-atomic one. Fix the problem by using atomic bitops even in do_set_dqblk.
--- fs/quota/dquot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
fs/quota/dquot.c +6 -6
@@ -2389,34 +2389,34 @@ static int do_set_dqblk(struct dquot *dqif (di->dqb_valid &QIF_SPACE ) { dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; check_blim =1 ; -__set_bit (DQ_LASTSET_B +QIF_SPACE_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_SPACE_B , &dquot->dq_flags); }if (di->dqb_valid &QIF_BLIMITS ) { dm->dqb_bsoftlimit =qbtos (di->dqb_bsoftlimit); dm->dqb_bhardlimit =qbtos (di->dqb_bhardlimit); check_blim =1 ; -__set_bit (DQ_LASTSET_B +QIF_BLIMITS_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_BLIMITS_B , &dquot->dq_flags); }if (di->dqb_valid &QIF_INODES ) { dm->dqb_curinodes = di->dqb_curinodes; check_ilim =1 ; -__set_bit (DQ_LASTSET_B +QIF_INODES_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_INODES_B , &dquot->dq_flags); }if (di->dqb_valid &QIF_ILIMITS ) { dm->dqb_isoftlimit = di->dqb_isoftlimit; dm->dqb_ihardlimit = di->dqb_ihardlimit; check_ilim =1 ; -__set_bit (DQ_LASTSET_B +QIF_ILIMITS_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_ILIMITS_B , &dquot->dq_flags); }if (di->dqb_valid &QIF_BTIME ) { dm->dqb_btime = di->dqb_btime; check_blim =1 ; -__set_bit (DQ_LASTSET_B +QIF_BTIME_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_BTIME_B , &dquot->dq_flags); }if (di->dqb_valid &QIF_ITIME ) { dm->dqb_itime = di->dqb_itime; check_ilim =1 ; -__set_bit (DQ_LASTSET_B +QIF_ITIME_B , &dquot->dq_flags); +set_bit (DQ_LASTSET_B +QIF_ITIME_B , &dquot->dq_flags); }if (check_blim) {
PATCH 126/197 Staging: comedi: fix usbdux timeout bug
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bernd Porr <[email protected]>
commit ea25371a78c33e276527361d3ab19393d558b2fd upstream.
I've fixed a bug in the USBDUX driver which caused timeouts while sending commands to the boards. This was mainly because of one bulk transfer which had a timeout of 1ms (!). I've now set all timeouts to 1000ms.
From: Bernd Porr <[email protected]>
--- drivers/staging/comedi/drivers/usbdux.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/staging/comedi/drivers/usbdux.c +9 -8
@@ -1,4 +1,4 @@ -#define DRIVER_VERSION "v2.2" +#define DRIVER_VERSION "v2.3"#define DRIVER_AUTHOR "Bernd Porr, [email protected]"#define DRIVER_DESC "Stirling/ITL USB-DUX -- [email protected]"/*
@@ -80,6 +80,7 @@ sampling rate. If you sample two channel* 2.0: PWM seems to be stable and is not interfering with the other functions * 2.1: changed PWM API * 2.2: added firmware kernel request to fix an udev problem +* 2.3: corrected a bug in bulk timeouts which were far too short * */
@@ -101,8 +102,8 @@ sampling rate. If you sample two channel#define BOARDNAME "usbdux" -/* timeout for the USB-transfer */ -#define EZTIMEOUT 30 +/* timeout for the USB-transfer in ms*/ +#define BULK_TIMEOUT 1000/* constants for "firmware" upload and download */ #define USBDUXSUB_FIRMWARE 0xA0
@@ -750,7 +751,7 @@ static int usbduxsub_start(struct usbdux/* Length */ 1 ,/* Timeout */ - EZTIMEOUT); + BULK_TIMEOUT);if (errcode <0 ) {dev_err (&usbduxsub->interface->dev,"comedi_: control msg failed (start)\n" );
@@ -780,7 +781,7 @@ static int usbduxsub_stop(struct usbduxs/* Length */ 1 ,/* Timeout */ - EZTIMEOUT); + BULK_TIMEOUT);if (errcode <0 ) {dev_err (&usbduxsub->interface->dev,"comedi_: control msg failed (stop)\n" );
@@ -810,7 +811,7 @@ static int usbduxsub_upload(struct usbdu/* length */ len,/* timeout */ - EZTIMEOUT); + BULK_TIMEOUT);dev_dbg (&usbduxsub->interface->dev,"comedi_: result=%d\n" , errcode);if (errcode <0 ) {dev_err (&usbduxsub->interface->dev,"comedi_: upload failed\n" );
@@ -1110,7 +1111,7 @@ static int send_dux_commands(struct usbdusb_sndbulkpipe (this_usbduxsub->usbdev,COMMAND_OUT_EP ), this_usbduxsub->dux_commands,SIZEOFDUXBUFFER , - &nsent, 10); + &nsent, BULK_TIMEOUT);if (result <0 )dev_err (&this_usbduxsub->interface->dev,"comedi%d: " "could not transmit dux_command to the usb-device, "
@@ -1130,7 +1131,7 @@ static int receive_dux_commands(struct uusb_rcvbulkpipe (this_usbduxsub->usbdev,COMMAND_IN_EP ), this_usbduxsub->insnBuffer,SIZEINSNBUF , - &nrec, 1); + &nrec, BULK_TIMEOUT);if (result <0 ) {dev_err (&this_usbduxsub->interface->dev,"comedi%d: " "insn: USB error %d while receiving DUX command"
PATCH 127/197 Staging: comedi: usbdux.c: fix locking up of the driver when the comedi ringbuffer runs empty
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bernd Porr <[email protected]>
commit d4c3a56587af3edbe5f618b20e800e9f9fde13cb upstream.
Jan-Matthias Braun spotted a bug which locks up the driver when the comedi ring buffer runs empty and provided a patch. The driver would still send the data to comedi but the reader won't wake up any more. What's required is setting the flag COMEDI_CB_BLOCK after new data has arrived which wakes up the reader and therefore the read() command.
--- drivers/staging/comedi/drivers/usbdux.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/staging/comedi/drivers/usbdux.c +4 -1
@@ -1,4 +1,4 @@ -#define DRIVER_VERSION "v2.3" +#define DRIVER_VERSION "v2.4"#define DRIVER_AUTHOR "Bernd Porr, [email protected]"#define DRIVER_DESC "Stirling/ITL USB-DUX -- [email protected]"/*
@@ -81,6 +81,8 @@ sampling rate. If you sample two channel* 2.1: changed PWM API * 2.2: added firmware kernel request to fix an udev problem * 2.3: corrected a bug in bulk timeouts which were far too short +* 2.4: fixed a bug which causes the driver to hang when it ran out of data. +* Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it. * */
@@ -532,6 +534,7 @@ static void usbduxsub_ai_IsocIrq(struct } }/* tell comedi that data is there */ + s->async->events |=COMEDI_CB_BLOCK |COMEDI_CB_EOS ;comedi_event (this_usbduxsub->comedidev, s); }
PATCH 128/197 ocfs2: set i_mode on disk during acl operations
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mark Fasheh <[email protected]>
commit fcefd25ac89239cb57fa198f125a79ff85468c75 upstream.
ocfs2_set_acl() and ocfs2_init_acl() were setting i_mode on the in-memory inode, but never setting it on the disk copy. Thus, acls were some times not getting propagated between nodes. This patch fixes the issue by adding a helper function ocfs2_acl_set_mode() which does this the right way. ocfs2_set_acl() and ocfs2_init_acl() are then updated to call ocfs2_acl_set_mode().
--- fs/ocfs2/acl.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 5 deletions(-)
fs/ocfs2/acl.c +72 -5
@@ -30,6 +30,8 @@#include "alloc.h" #include "dlmglue.h" #include "file.h" +#include "inode.h" +#include "journal.h" #include "ocfs2_fs.h" #include "xattr.h"
@@ -170,6 +172,60 @@ static struct posix_acl *ocfs2_get_acl(s }/* +* Helper function to set i_mode in memory and disk. Some call paths +* will not have di_bh or a journal handle to pass, in which case it +* will create it's own. +*/ +static int ocfs2_acl_set_mode (struct inode *inode,struct buffer_head *di_bh, +handle_t *handle,umode_t new_mode) +{ +int ret, commit_handle =0 ; +struct ocfs2_dinode *di; + +if (di_bh ==NULL ) { + ret =ocfs2_read_inode_block (inode, &di_bh); +if (ret) { +mlog_errno (ret); + goto out; + } + }else +get_bh (di_bh); + +if (handle ==NULL ) { + handle =ocfs2_start_trans (OCFS2_SB (inode->i_sb), +OCFS2_INODE_UPDATE_CREDITS ); +if (IS_ERR (handle)) { + ret =PTR_ERR (handle); +mlog_errno (ret); + goto out_brelse; + } + + commit_handle =1 ; + } + + di = (struct ocfs2_dinode *)di_bh->b_data; + ret =ocfs2_journal_access_di (handle,INODE_CACHE (inode), di_bh, +OCFS2_JOURNAL_ACCESS_WRITE ); +if (ret) { +mlog_errno (ret); + goto out_commit; + } + + inode->i_mode = new_mode; + di->i_mode =cpu_to_le16 (inode->i_mode); + +ocfs2_journal_dirty (handle, di_bh); + +out_commit: +if (commit_handle) +ocfs2_commit_trans (OCFS2_SB (inode->i_sb), handle); +out_brelse: +brelse (di_bh); +out: +return ret; +} + +/* * Set the access or default ACL of an inode. */ static int ocfs2_set_acl(handle_t *handle,
@@ -197,9 +253,14 @@ static int ocfs2_set_acl(handle_t *handlif (ret <0 )return ret;else { - inode->i_mode = mode;if (ret ==0 ) acl =NULL ; + + ret =ocfs2_acl_set_mode (inode, di_bh, + handle, mode); +if (ret) +return ret; + } }break ;
@@ -287,6 +348,7 @@ int ocfs2_init_acl(handle_t *handle,struct ocfs2_super *osb =OCFS2_SB (inode->i_sb);struct posix_acl *acl =NULL ;int ret =0 ; +mode_t mode;if (!S_ISLNK (inode->i_mode)) {if (osb->s_mount_opt &OCFS2_MOUNT_POSIX_ACL ) {
@@ -295,12 +357,17 @@ int ocfs2_init_acl(handle_t *handle,if (IS_ERR (acl))return PTR_ERR (acl); } -if (!acl) - inode->i_mode &= ~current_umask (); +if (!acl) { + mode = inode->i_mode & ~current_umask (); + ret =ocfs2_acl_set_mode (inode, di_bh, handle, mode); +if (ret) { +mlog_errno (ret); + goto cleanup; + } + } }if ((osb->s_mount_opt &OCFS2_MOUNT_POSIX_ACL ) && acl) {struct posix_acl *clone; -mode_t mode;if (S_ISDIR (inode->i_mode)) { ret = ocfs2_set_acl(handle, inode, di_bh,
@@ -317,7 +384,7 @@ int ocfs2_init_acl(handle_t *handle, mode = inode->i_mode; ret =posix_acl_create_masq (clone, &mode);if (ret >=0 ) { - inode->i_mode = mode; + ret =ocfs2_acl_set_mode (inode, di_bh, handle, mode);if (ret >0 ) { ret = ocfs2_set_acl(handle, inode, di_bh, ACL_TYPE_ACCESS,
PATCH 129/197 ocfs2: Change bg_chain check for ocfs2_validate_gd_parent.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tao Ma <[email protected]>
commit 78c37eb0d5e6a9727b12ea0f1821795ffaa66cfe upstream.
In ocfs2_validate_gd_parent, we check bg_chain against the cl_next_free_rec of the dinode. Actually in resize, we have the chance of bg_chain == cl_next_free_rec. So add some additional condition check for it.
I also rename paramter "clean_error" to "resize", since the old one is not clearly enough to indicate that we should only meet with this case in resize.
btw, the correpsonding bug is
http://oss.oracle.com/bugzilla/show_bug.cgi?id=1230.
--- fs/ocfs2/suballoc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
fs/ocfs2/suballoc.c +8 -5
@@ -152,7 +152,7 @@ static u32 ocfs2_bits_per_group(struct o#define do_error (fmt, ...) \ do{ \ - if (clean_error) \ + if (resize) \ mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \ else \ ocfs2_error(sb, fmt, ##__VA_ARGS__); \
@@ -160,7 +160,7 @@ static u32 ocfs2_bits_per_group(struct ostatic int ocfs2_validate_gd_self (struct super_block *sb,struct buffer_head *bh, -int clean_error) +int resize) {struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
@@ -211,7 +211,7 @@ static int ocfs2_validate_gd_self(structstatic int ocfs2_validate_gd_parent (struct super_block *sb,struct ocfs2_dinode *di,struct buffer_head *bh, -int clean_error) +int resize) {unsigned int max_bits;struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
@@ -233,8 +233,11 @@ static int ocfs2_validate_gd_parent(strureturn -EINVAL ; } -if (le16_to_cpu (gd->bg_chain) >= -le16_to_cpu (di->id2.i_chain.cl_next_free_rec)) { +/* In resize, we may meet the case bg_chain == cl_next_free_rec. */ +if ((le16_to_cpu (gd->bg_chain) > +le16_to_cpu (di->id2.i_chain.cl_next_free_rec)) || + ((le16_to_cpu (gd->bg_chain) == +le16_to_cpu (di->id2.i_chain.cl_next_free_rec)) && !resize)) {do_error ("Group descriptor #%llu has bad chain %u" , (unsigned long long )bh->b_blocknr,le16_to_cpu (gd->bg_chain));
PATCH 130/197 9p: Skip check for mandatory locks when unlocking
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sachin Prabhu <[email protected]>
commit f78233dd44a110c574fe760ad6f9c1e8741a0d00 upstream.
While investigating a bug, I came across a possible bug in v9fs. The problem is similar to the one reported for NFS by ASANO Masahiro in
http://lkml.org/lkml/2005/12/21/334.
v9fs_file_lock() will skip locks on file which has mode set to 02666. This is a problem in cases where the mode of the file is changed after a process has obtained a lock on the file. Such a lock will be skipped during unlock and the machine will end up with a BUG in locks_remove_flock().
v9fs_file_lock() should skip the check for mandatory locks when unlocking a file.
--- fs/9p/vfs_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/9p/vfs_file.c +1 -1
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *fP9_DPRINTK (P9_DEBUG_VFS ,"filp: %p lock: %p\n" , filp, fl);/* No mandatory locks */ -if (__mandatory_lock (inode)) +if (__mandatory_lock (inode) && fl->fl_type !=F_UNLCK )return -ENOLCK ;if ((IS_SETLK (cmd) ||IS_SETLKW (cmd)) && fl->fl_type !=F_UNLCK ) {
PATCH 131/197 fc class: fail fast bsg requests
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Christie <[email protected]>
commit 2bc1c59dbdefdb6f9767e06efb86bbdb2923a8be upstream.
If the port state is blocked and the fast io fail tmo has fired then this patch will fail bsg requests immediately. This is needed if userspace is sending IOs to test the transport like with fcping, so it will not have to wait for the dev loss tmo. With this patch he bsg req fast io fail code behaves like the normal and sg io/passthrough fast io fail.
--- drivers/scsi/scsi_transport_fc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/scsi_transport_fc.c +3 -2
@@ -3796,8 +3796,9 @@ fc_bsg_request_handler(struct request_qureturn ;while (!blk_queue_plugged (q)) { -if (rport && (rport->port_state ==FC_PORTSTATE_BLOCKED )) -break ; +if (rport && (rport->port_state ==FC_PORTSTATE_BLOCKED ) && + !(rport->flags &FC_RPORT_FAST_FAIL_TIMEDOUT )) +break ; req =blk_fetch_request (q);if (!req)
PATCH 132/197 SCSI: add scsi target reset support to scsi ioctl
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Christie <[email protected]>
commit 3f9daedfcb197d784c6e7ecd731e3aa9859bc951 upstream.
The scsi ioctl code path was missing scsi target reset support. This patch just adds it.
--- drivers/scsi/scsi_ioctl.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/scsi_ioctl.c +3 -0
@@ -308,6 +308,9 @@ int scsi_nonblockable_ioctl(struct scsi_case SG_SCSI_RESET_DEVICE : val =SCSI_TRY_RESET_DEVICE ;break ; +case SG_SCSI_RESET_TARGET : + val =SCSI_TRY_RESET_TARGET ; +break ;case SG_SCSI_RESET_BUS : val =SCSI_TRY_RESET_BUS ;break ;
PATCH 133/197 igb: add support for 82576NS SerDes adapter
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alexander Duyck <[email protected]>
commit 747d49baaf4e3f4ad5ae77477830da026eeef69d upstream.
This patch adds the device ID necessary to support the 82576NS SerDes adapter.
--- drivers/net/igb/e1000_82575.c | 1 + drivers/net/igb/e1000_hw.h | 1 + drivers/net/igb/igb_main.c | 1 + 3 files changed, 3 insertions(+)
drivers/net/igb/e1000_82575.c +1 -0
@@ -81,6 +81,7 @@ static s32 igb_get_invariants_82575(strubreak ;case E1000_DEV_ID_82576 :case E1000_DEV_ID_82576_NS : +case E1000_DEV_ID_82576_NS_SERDES :case E1000_DEV_ID_82576_FIBER :case E1000_DEV_ID_82576_SERDES :case E1000_DEV_ID_82576_QUAD_COPPER :
drivers/net/igb/e1000_hw.h +1 -0
@@ -42,6 +42,7 @@ struct e1000_hw;#define E1000_DEV_ID_82576_SERDES 0x10E7#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8#define E1000_DEV_ID_82576_NS 0x150A +#define E1000_DEV_ID_82576_NS_SERDES 0x1518#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D#define E1000_DEV_ID_82575EB_COPPER 0x10A7#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
drivers/net/igb/igb_main.c +1 -0
@@ -63,6 +63,7 @@ static const struct e1000_info *igb_infostatic struct pci_device_id igb_pci_tbl[] = { {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576 ), board_82575 }, {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576_NS ), board_82575 }, + {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576_NS_SERDES ), board_82575 }, {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576_FIBER ), board_82575 }, {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576_SERDES ), board_82575 }, {PCI_VDEVICE (INTEL ,E1000_DEV_ID_82576_SERDES_QUAD ), board_82575 },
PATCH 134/197 PCIe AER: prevent AER injection if hardware masks error reporting
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Youquan Song <[email protected]>
commit b49bfd32901625e4adcfee011d2b32a43b4db67d upstream.
The Correcteable/Uncorrectable Error Mask Registers are used by PCIe AER driver which will controls the reporting of individual errors to PCIe RC via PCIe error messages.
If hardware masks special error reporting to RC, the aer_inject driver should not inject aer error.
--- drivers/pci/pcie/aer/aer_inject.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/pci/pcie/aer/aer_inject.c +19 -1
@@ -302,7 +302,7 @@ static int aer_inject(struct aer_error_iunsigned long flags;unsigned int devfn =PCI_DEVFN (einj->dev, einj->fn);int pos_cap_err, rp_pos_cap_err; -u32 sever; +u32 sever, mask;int ret =0 ; dev =pci_get_bus_and_slot (einj->bus, devfn);
@@ -354,6 +354,24 @@ static int aer_inject(struct aer_error_i err->header_log2 = einj->header_log2; err->header_log3 = einj->header_log3; +pci_read_config_dword (dev, pos_cap_err +PCI_ERR_COR_MASK , &mask); +if (einj->cor_status && !(einj->cor_status & ~mask)) { + ret = -EINVAL ; +printk (KERN_WARNING "The correctable error(s) is masked " +"by device\n" ); +spin_unlock_irqrestore (&inject_lock, flags); + goto out_put; + } + +pci_read_config_dword (dev, pos_cap_err +PCI_ERR_UNCOR_MASK , &mask); +if (einj->uncor_status && !(einj->uncor_status & ~mask)) { + ret = -EINVAL ; +printk (KERN_WARNING "The uncorrectable error(s) is masked " +"by device\n" ); +spin_unlock_irqrestore (&inject_lock, flags); + goto out_put; + } + rperr =__find_aer_error_by_dev (rpdev);if (!rperr) { rperr = rperr_alloc;
PATCH 135/197 vgaarb: Fix VGA arbiter to accept PCI domains other than 0
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Travis <[email protected]>
commit 773a38dbdad03474c5ee235f7d9bf9f51c9e3c2b upstream.
Update the VGA Arbiter to accept PCI Domains other than 0.
LKML-Reference: <[email protected]>
--- drivers/gpu/vga/vgaarb.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/gpu/vga/vgaarb.c +19 -4
@@ -954,6 +954,7 @@ static ssize_t vga_arb_write(struct file } }else if (strncmp (curr_pos,"target " ,7 ) ==0 ) { +struct pci_bus *pbus;unsigned int domain, bus, devfn;struct vga_device *vgadev;
@@ -969,18 +970,31 @@ static ssize_t vga_arb_write(struct file ret_val = -EPROTO ; goto done; } +pr_devel ("vgaarb: %s ==> %x:%x:%x.%x\n" , curr_pos, + domain, bus,PCI_SLOT (devfn),PCI_FUNC (devfn)); - pdev =pci_get_bus_and_slot (bus, devfn); + pbus =pci_find_bus (domain, bus); +pr_devel ("vgaarb: pbus %p\n" , pbus); +if (pbus ==NULL ) { +pr_err ("vgaarb: invalid PCI domain and/or bus address %x:%x\n" , + domain, bus); + ret_val = -ENODEV ; + goto done; + } + pdev =pci_get_slot (pbus, devfn); +pr_devel ("vgaarb: pdev %p\n" , pdev);if (!pdev) { -pr_info ("vgaarb: invalid PCI address!\n" ); +pr_err ("vgaarb: invalid PCI address %x:%x\n" , + bus, devfn); ret_val = -ENODEV ; goto done; } } vgadev =vgadev_find (pdev); +pr_devel ("vgaarb: vgadev %p\n" , vgadev);if (vgadev ==NULL ) { -pr_info ("vgaarb: this pci device is not a vga device\n" ); +pr_err ("vgaarb: this pci device is not a vga device\n" );pci_dev_put (pdev); ret_val = -ENODEV ; goto done;
@@ -998,7 +1012,8 @@ static ssize_t vga_arb_write(struct file } }if (i ==MAX_USER_CARDS ) { -pr_err ("vgaarb: maximum user cards number reached!\n" ); +pr_err ("vgaarb: maximum user cards (%d) number reached!\n" , +MAX_USER_CARDS );pci_dev_put (pdev);/* XXX: which value to return? */ ret_val = -ENOMEM ;
PATCH 136/197 SCSI: fc-transport: Use packed modifier for fc_bsg_request structure.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Harish Zunjarrao <[email protected]>
commit eda05a28ec52be40086400a1b606d211276f0e41 upstream.
The 32bit kernel does not add padding bytes in the fc_bsg_request structure whereas the 64bit kernel adds padding bytes in the fc_bsg_request structure. Due to this, structure elements gets mismatched with 32bit application and 64bit kernel.To resolve this, used packed modifier to avoid adding padding bytes.
--- include/scsi/scsi_bsg_fc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/scsi/scsi_bsg_fc.h +1 -1
@@ -292,7 +292,7 @@ struct fc_bsg_request {struct fc_bsg_rport_els r_els;struct fc_bsg_rport_ct r_ct; } rqst_data; -}; +} __attribute__((packed));/* response (request sense data) structure of the sg_io_v4 */
PATCH 137/197 pci: Update pci_set_vga_state() to call arch functions
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Travis <[email protected]>
commit 95a8b6efc5d07103583f706c8a5889437d537939 upstream.
Update pci_set_vga_state to call arch dependent functions to enable Legacy VGA I/O transactions to be redirected to correct target.
LKML-Reference: <[email protected]>
--- drivers/pci/pci.c | 25 ++++++++++++++++++++++++- include/linux/pci.h | 5 +++++ 2 files changed, 29 insertions(+), 1 deletion(-)
drivers/pci/pci.c +24 -1
@@ -2541,6 +2541,23 @@ int pci_resource_bar(struct pci_dev *devreturn 0 ; } +/* Some architectures require additional programming to enable VGA */ +static arch_set_vga_state_t arch_set_vga_state; + +void __init pci_register_set_vga_state (arch_set_vga_state_t func) +{ + arch_set_vga_state = func;/* NULL disables */ +} + +static int pci_set_vga_state_arch (struct pci_dev *dev,bool decode, +unsigned int command_bits,bool change_bridge) +{ +if (arch_set_vga_state) +return arch_set_vga_state (dev, decode, command_bits, + change_bridge); +return 0 ; +} +/** * pci_set_vga_state - set VGA decode state on device and parents if requested * @dev: the PCI device
@@ -2554,9 +2571,15 @@ int pci_set_vga_state(struct pci_dev *destruct pci_bus *bus;struct pci_dev *bridge;u16 cmd; +int rc;WARN_ON (command_bits & ~(PCI_COMMAND_IO |PCI_COMMAND_MEMORY )); +/* ARCH specific VGA enables */ + rc =pci_set_vga_state_arch (dev, decode, command_bits, change_bridge); +if (rc) +return rc; +pci_read_config_word (dev,PCI_COMMAND , &cmd);if (decode == true) cmd |= command_bits;
@@ -2771,6 +2794,7 @@ EXPORT_SYMBOL(pcim_pin_device);EXPORT_SYMBOL (pci_disable_device);EXPORT_SYMBOL (pci_find_capability);EXPORT_SYMBOL (pci_bus_find_capability); +EXPORT_SYMBOL (pci_register_set_vga_state);EXPORT_SYMBOL (pci_release_regions);EXPORT_SYMBOL (pci_request_regions);EXPORT_SYMBOL (pci_request_regions_exclusive);
@@ -2803,4 +2827,3 @@ EXPORT_SYMBOL(pci_target_state);EXPORT_SYMBOL (pci_prepare_to_sleep);EXPORT_SYMBOL (pci_back_from_sleep);EXPORT_SYMBOL_GPL (pci_set_pcie_reset_state); -
include/linux/pci.h +5 -0
@@ -945,6 +945,11 @@ static inline int pci_proc_domain(struct }#endif /* CONFIG_PCI_DOMAINS */ +/* some architectures require additional setup to direct VGA traffic */ +typedef int (*arch_set_vga_state_t )(struct pci_dev *pdev,bool decode, +unsigned int command_bits,bool change_bridge); +extern void pci_register_set_vga_state (arch_set_vga_state_t func); +#else /* CONFIG_PCI is not enabled */ /*
PATCH 138/197 PCI: kill off pci_register_set_vga_state() symbol export.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Paul Mundt <[email protected]>
commit ded1d8f29b4d315a2093cafc3ee17ac870a87972 upstream.
When pci_register_set_vga_state() was made __init, the EXPORT_SYMBOL() was retained, which now leaves us with a section mismatch.
--- drivers/pci/pci.c | 1 - 1 file changed, 1 deletion(-)
drivers/pci/pci.c +0 -1
@@ -2794,7 +2794,6 @@ EXPORT_SYMBOL(pcim_pin_device);EXPORT_SYMBOL (pci_disable_device);EXPORT_SYMBOL (pci_find_capability);EXPORT_SYMBOL (pci_bus_find_capability); -EXPORT_SYMBOL (pci_register_set_vga_state);EXPORT_SYMBOL (pci_release_regions);EXPORT_SYMBOL (pci_request_regions);EXPORT_SYMBOL (pci_request_regions_exclusive);
PATCH 139/197 PCI: fix nested spinlock hang in aer_inject
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Patterson <[email protected]>
commit bd1f46deba615971a58193afd0202878cadf19a7 upstream.
The aer_inject module hangs in aer_inject() when checking the device's error masks. The hang is due to a recursive use of the aer_inject lock. The aer_inject() routine grabs the lock while processing the error and then calls pci_read_config_dword to read the masks. The pci_read_config_dword routine is earlier overridden by pci_read_aer, which among other things, grabs the aer_inject lock.
Fixed by moving the pci_read_config_dword calls to read the masks to before the lock is taken.
--- drivers/pci/pcie/aer/aer_inject.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/pci/pcie/aer/aer_inject.c +6 -6
@@ -302,7 +302,7 @@ static int aer_inject(struct aer_error_iunsigned long flags;unsigned int devfn =PCI_DEVFN (einj->dev, einj->fn);int pos_cap_err, rp_pos_cap_err; -u32 sever, mask; +u32 sever, cor_mask, uncor_mask;int ret =0 ; dev =pci_get_bus_and_slot (einj->bus, devfn);
@@ -320,6 +320,9 @@ static int aer_inject(struct aer_error_i goto out_put; }pci_read_config_dword (dev, pos_cap_err +PCI_ERR_UNCOR_SEVER , &sever); +pci_read_config_dword (dev, pos_cap_err +PCI_ERR_COR_MASK , &cor_mask); +pci_read_config_dword (dev, pos_cap_err +PCI_ERR_UNCOR_MASK , + &uncor_mask); rp_pos_cap_err =pci_find_ext_capability (rpdev,PCI_EXT_CAP_ID_ERR );if (!rp_pos_cap_err) {
@@ -354,17 +357,14 @@ static int aer_inject(struct aer_error_i err->header_log2 = einj->header_log2; err->header_log3 = einj->header_log3; -pci_read_config_dword (dev, pos_cap_err +PCI_ERR_COR_MASK , &mask); -if (einj->cor_status && !(einj->cor_status & ~mask)) { +if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { ret = -EINVAL ;printk (KERN_WARNING "The correctable error(s) is masked " "by device\n" );spin_unlock_irqrestore (&inject_lock, flags); goto out_put; } - -pci_read_config_dword (dev, pos_cap_err +PCI_ERR_UNCOR_MASK , &mask); -if (einj->uncor_status && !(einj->uncor_status & ~mask)) { +if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { ret = -EINVAL ;printk (KERN_WARNING "The uncorrectable error(s) is masked " "by device\n" );
PATCH 140/197 IPoIB: Fix TX queue lockup with mixed UD/CM traffic
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eli Cohen <[email protected]>
commit f0dc117abdfa9a0e96c3d013d836460ef3cd08c7 upstream.
The IPoIB UD QP reports send completions to priv->send_cq, which is usually left unarmed; it only gets armed when the number of outstanding send requests reaches the size of the TX queue. This arming is done only in the send path for the UD QP. However, when sending CM packets, the net queue may be stopped for the same reasons but no measures are taken to recover the UD path from a lockup.
Consider this scenario: a host sends high rate of both CM and UD packets, with a TX queue length of N. If at some time the number of outstanding UD packets is more than N/2 and the overall outstanding packets is N-1, and CM sends a packet (making the number of outstanding sends equal N), the TX queue will be stopped. When all the CM packets complete, the number of outstanding packets will still be higher than N/2 so the TX queue will not be restarted.
Fix this by calling ib_req_notify_cq() when the queue is stopped in the CM path.
--- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/ulp/ipoib/ipoib_cm.c +2 -0
@@ -752,6 +752,8 @@ void ipoib_cm_send(struct net_device *deif (++priv->tx_outstanding == ipoib_sendq_size) {ipoib_dbg (priv,"TX ring 0x%x full, stopping kernel net queue\n" , tx->qp->qp_num); +if (ib_req_notify_cq (priv->send_cq,IB_CQ_NEXT_COMP )) +ipoib_warn (priv,"request notify on send CQ failed\n" );netif_stop_queue (dev); } }
PATCH 141/197 x86/PCI: irq and pci_ids patch for Intel Cougar Point DeviceIDs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Seth Heasley <[email protected]>
commit 93da6202264ce1256b04db8008a43882ae62d060 upstream.
This patch adds the Intel Cougar Point (PCH) LPC and SMBus Controller DeviceIDs.
--- arch/x86/pci/irq.c | 2 ++ include/linux/pci_ids.h | 3 +++ 2 files changed, 5 insertions(+)
arch/x86/pci/irq.c +2 -0
@@ -590,6 +590,8 @@ static __init int intel_router_probe(strcase PCI_DEVICE_ID_INTEL_ICH10_1 :case PCI_DEVICE_ID_INTEL_ICH10_2 :case PCI_DEVICE_ID_INTEL_ICH10_3 : +case PCI_DEVICE_ID_INTEL_CPT_LPC1 : +case PCI_DEVICE_ID_INTEL_CPT_LPC2 : r->name ="PIIX/ICH" ; r->get = pirq_piix_get; r->set = pirq_piix_set;
include/linux/pci_ids.h +3 -0
@@ -2412,6 +2412,9 @@#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_CPT_SMBUS 0x1c22 +#define PCI_DEVICE_ID_INTEL_CPT_LPC1 0x1c42 +#define PCI_DEVICE_ID_INTEL_CPT_LPC2 0x1c43#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
PATCH 142/197 ALSA: hda_intel: ALSA HD Audio patch for Intel Cougar Point DeviceIDs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Seth Heasley <[email protected]>
commit d2f2fcd2541bae004db7f4798ffd9d2cb75ae817 upstream.
This patch adds the Intel Cougar Point (PCH) HD Audio Controller DeviceIDs.
--- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/hda/hda_intel.c +3 -0
@@ -116,6 +116,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"{Intel, ICH9}," "{Intel, ICH10}," "{Intel, PCH}," +"{Intel, CPT}," "{Intel, SCH}," "{ATI, SB450}," "{ATI, SB600},"
@@ -2666,6 +2667,8 @@ static struct pci_device_id azx_ids[] = { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, /* PCH */ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, + /* CPT */ + { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_ICH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },/* ATI SB 450/600 */