From: Greg Kroah-Hartman Date: Fri, 3 May 2013 17:42:08 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.77~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=375168b2f9710d0bd236274854e181faa50b3e4d;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: fix-initialization-of-cmci-cmcp-interrupts.patch fs-fscache-stats.c-fix-memory-leak.patch pci-acpi-don-t-query-osc-support-with-all-possible-controls.patch wrong-asm-register-contraints-in-the-futex-implementation.patch wrong-asm-register-contraints-in-the-kvm-implementation.patch --- diff --git a/queue-3.0/fix-initialization-of-cmci-cmcp-interrupts.patch b/queue-3.0/fix-initialization-of-cmci-cmcp-interrupts.patch new file mode 100644 index 00000000000..0eed1c318e6 --- /dev/null +++ b/queue-3.0/fix-initialization-of-cmci-cmcp-interrupts.patch @@ -0,0 +1,128 @@ +From d303e9e98fce56cdb3c6f2ac92f626fc2bd51c77 Mon Sep 17 00:00:00 2001 +From: Tony Luck +Date: Wed, 20 Mar 2013 10:30:15 -0700 +Subject: Fix initialization of CMCI/CMCP interrupts + +From: Tony Luck + +commit d303e9e98fce56cdb3c6f2ac92f626fc2bd51c77 upstream. + +Back 2010 during a revamp of the irq code some initializations +were moved from ia64_mca_init() to ia64_mca_late_init() in + + commit c75f2aa13f5b268aba369b5dc566088b5194377c + Cannot use register_percpu_irq() from ia64_mca_init() + +But this was hideously wrong. First of all these initializations +are now down far too late. Specifically after all the other cpus +have been brought up and initialized their own CMC vectors from +smp_callin(). Also ia64_mca_late_init() may be called from any cpu +so the line: + ia64_mca_cmc_vector_setup(); /* Setup vector on BSP */ +is generally not executed on the BSP, and so the CMC vector isn't +setup at all on that processor. + +Make use of the arch_early_irq_init() hook to get this code executed +at just the right moment: not too early, not too late. + +Reported-by: Fred Hartnett +Tested-by: Fred Hartnett +Signed-off-by: Tony Luck +Signed-off-by: Greg Kroah-Hartman + +--- + arch/ia64/include/asm/mca.h | 1 + + arch/ia64/kernel/irq.c | 8 ++++++++ + arch/ia64/kernel/mca.c | 37 ++++++++++++++++++++++++------------- + 3 files changed, 33 insertions(+), 13 deletions(-) + +--- a/arch/ia64/include/asm/mca.h ++++ b/arch/ia64/include/asm/mca.h +@@ -143,6 +143,7 @@ extern unsigned long __per_cpu_mca[NR_CP + extern int cpe_vector; + extern int ia64_cpe_irq; + extern void ia64_mca_init(void); ++extern void ia64_mca_irq_init(void); + extern void ia64_mca_cpu_init(void *); + extern void ia64_os_mca_dispatch(void); + extern void ia64_os_mca_dispatch_end(void); +--- a/arch/ia64/kernel/irq.c ++++ b/arch/ia64/kernel/irq.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. +@@ -83,6 +85,12 @@ bool is_affinity_mask_valid(const struct + + #endif /* CONFIG_SMP */ + ++int __init arch_early_irq_init(void) ++{ ++ ia64_mca_irq_init(); ++ return 0; ++} ++ + #ifdef CONFIG_HOTPLUG_CPU + unsigned int vectors_in_migration[NR_IRQS]; + +--- a/arch/ia64/kernel/mca.c ++++ b/arch/ia64/kernel/mca.c +@@ -2071,22 +2071,16 @@ ia64_mca_init(void) + printk(KERN_INFO "MCA related initialization done\n"); + } + ++ + /* +- * ia64_mca_late_init +- * +- * Opportunity to setup things that require initialization later +- * than ia64_mca_init. Setup a timer to poll for CPEs if the +- * platform doesn't support an interrupt driven mechanism. +- * +- * Inputs : None +- * Outputs : Status ++ * These pieces cannot be done in ia64_mca_init() because it is called before ++ * early_irq_init() which would wipe out our percpu irq registrations. But we ++ * cannot leave them until ia64_mca_late_init() because by then all the other ++ * processors have been brought online and have set their own CMC vectors to ++ * point at a non-existant action. Called from arch_early_irq_init(). + */ +-static int __init +-ia64_mca_late_init(void) ++void __init ia64_mca_irq_init(void) + { +- if (!mca_init) +- return 0; +- + /* + * Configure the CMCI/P vector and handler. Interrupts for CMC are + * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). +@@ -2105,6 +2099,23 @@ ia64_mca_late_init(void) + /* Setup the CPEI/P handler */ + register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); + #endif ++} ++ ++/* ++ * ia64_mca_late_init ++ * ++ * Opportunity to setup things that require initialization later ++ * than ia64_mca_init. Setup a timer to poll for CPEs if the ++ * platform doesn't support an interrupt driven mechanism. ++ * ++ * Inputs : None ++ * Outputs : Status ++ */ ++static int __init ++ia64_mca_late_init(void) ++{ ++ if (!mca_init) ++ return 0; + + register_hotcpu_notifier(&mca_cpu_notifier); + diff --git a/queue-3.0/fs-fscache-stats.c-fix-memory-leak.patch b/queue-3.0/fs-fscache-stats.c-fix-memory-leak.patch new file mode 100644 index 00000000000..fbc4bf252df --- /dev/null +++ b/queue-3.0/fs-fscache-stats.c-fix-memory-leak.patch @@ -0,0 +1,41 @@ +From ec686c9239b4d472052a271c505d04dae84214cc Mon Sep 17 00:00:00 2001 +From: Anurup m +Date: Mon, 29 Apr 2013 15:05:52 -0700 +Subject: fs/fscache/stats.c: fix memory leak + +From: Anurup m + +commit ec686c9239b4d472052a271c505d04dae84214cc upstream. + +There is a kernel memory leak observed when the proc file +/proc/fs/fscache/stats is read. + +The reason is that in fscache_stats_open, single_open is called and the +respective release function is not called during release. Hence fix +with correct release function - single_release(). + +Addresses https://bugzilla.kernel.org/show_bug.cgi?id=57101 + +Signed-off-by: Anurup m +Cc: shyju pv +Cc: Sanil kumar +Cc: Nataraj m +Cc: Li Zefan +Cc: David Howells +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fscache/stats.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/fscache/stats.c ++++ b/fs/fscache/stats.c +@@ -276,5 +276,5 @@ const struct file_operations fscache_sta + .open = fscache_stats_open, + .read = seq_read, + .llseek = seq_lseek, +- .release = seq_release, ++ .release = single_release, + }; diff --git a/queue-3.0/pci-acpi-don-t-query-osc-support-with-all-possible-controls.patch b/queue-3.0/pci-acpi-don-t-query-osc-support-with-all-possible-controls.patch new file mode 100644 index 00000000000..d9938fd6823 --- /dev/null +++ b/queue-3.0/pci-acpi-don-t-query-osc-support-with-all-possible-controls.patch @@ -0,0 +1,67 @@ +From 545d6e189a41c94c11f55045a771118eccc9d9eb Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Thu, 28 Mar 2013 04:28:58 +0000 +Subject: PCI / ACPI: Don't query OSC support with all possible controls + +From: Yinghai Lu + +commit 545d6e189a41c94c11f55045a771118eccc9d9eb upstream. + +Found problem on system that firmware that could handle pci aer. +Firmware get error reporting after pci injecting error, before os boots. +But after os boots, firmware can not get report anymore, even pci=noaer +is passed. + +Root cause: BIOS _OSC has problem with query bit checking. +It turns out that BIOS vendor is copying example code from ACPI Spec. +In ACPI Spec 5.0, page 290: + + If (Not(And(CDW1,1))) // Query flag clear? + { // Disable GPEs for features granted native control. + If (And(CTRL,0x01)) // Hot plug control granted? + { + Store(0,HPCE) // clear the hot plug SCI enable bit + Store(1,HPCS) // clear the hot plug SCI status bit + } + ... + } + +When Query flag is set, And(CDW1,1) will be 1, Not(1) will return 0xfffffffe. +So it will get into code path that should be for control set only. +BIOS acpi code should be changed to "If (LEqual(And(CDW1,1), 0)))" + +Current kernel code is using _OSC query to notify firmware about support +from OS and then use _OSC to set control bits. +During query support, current code is using all possible controls. +So will execute code that should be only for control set stage. + +That will have problem when pci=noaer or aer firmware_first is used. +As firmware have that control set for os aer already in query support stage, +but later will not os aer handling. + +We should avoid passing all possible controls, just use osc_control_set +instead. +That should workaround BIOS bugs with affected systems on the field +as more bios vendors are copying sample code from ACPI spec. + +Signed-off-by: Yinghai Lu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/pci_root.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -247,8 +247,8 @@ static acpi_status acpi_pci_query_osc(st + *control &= OSC_PCI_CONTROL_MASKS; + capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; + } else { +- /* Run _OSC query for all possible controls. */ +- capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; ++ /* Run _OSC query only with existing controls. */ ++ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set; + } + + status = acpi_pci_run_osc(root->device->handle, capbuf, &result); diff --git a/queue-3.0/series b/queue-3.0/series index 3785564320f..d05dc1ad64d 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -19,3 +19,8 @@ tracing-fix-off-by-one-on-allocating-stat-pages.patch tracing-check-return-value-of-tracing_init_dentry.patch tracing-reset-ftrace_graph_filter_enabled-if-count-is-zero.patch i2c-xiic-must-always-write-16-bit-words-to-tx_fifo.patch +fix-initialization-of-cmci-cmcp-interrupts.patch +pci-acpi-don-t-query-osc-support-with-all-possible-controls.patch +wrong-asm-register-contraints-in-the-futex-implementation.patch +wrong-asm-register-contraints-in-the-kvm-implementation.patch +fs-fscache-stats.c-fix-memory-leak.patch diff --git a/queue-3.0/wrong-asm-register-contraints-in-the-futex-implementation.patch b/queue-3.0/wrong-asm-register-contraints-in-the-futex-implementation.patch new file mode 100644 index 00000000000..5576caa8133 --- /dev/null +++ b/queue-3.0/wrong-asm-register-contraints-in-the-futex-implementation.patch @@ -0,0 +1,292 @@ +From 136f39ddc53db3bcee2befbe323a56d4fbf06da8 Mon Sep 17 00:00:00 2001 +From: Stephan Schreiber +Date: Tue, 19 Mar 2013 15:22:27 -0700 +Subject: Wrong asm register contraints in the futex implementation + +From: Stephan Schreiber + +commit 136f39ddc53db3bcee2befbe323a56d4fbf06da8 upstream. + +The Linux Kernel contains some inline assembly source code which has +wrong asm register constraints in arch/ia64/include/asm/futex.h. + +I observed this on Kernel 3.2.23 but it is also true on the most +recent Kernel 3.9-rc1. + +File arch/ia64/include/asm/futex.h: + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + { + register unsigned long r8 __asm ("r8"); + unsigned long prev; + __asm__ __volatile__( + " mf;; \n" + " mov %0=r0 \n" + " mov ar.ccv=%4;; \n" + "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " .xdata4 \"__ex_table\", 1b-., 2f-. \n" + "[2:]" + : "=r" (r8), "=r" (prev) + : "r" (uaddr), "r" (newval), + "rO" ((long) (unsigned) oldval) + : "memory"); + *uval = prev; + return r8; + } +} + +The list of output registers is + : "=r" (r8), "=r" (prev) +The constraint "=r" means that the GCC has to maintain that these vars +are in registers and contain valid info when the program flow leaves +the assembly block (output registers). +But "=r" also means that GCC can put them in registers that are used +as input registers. Input registers are uaddr, newval, oldval on the +example. +The second assembly instruction + " mov %0=r0 \n" +is the first one which writes to a register; it sets %0 to 0. %0 means +the first register operand; it is r8 here. (The r0 is read-only and +always 0 on the Itanium; it can be used if an immediate zero value is +needed.) +This instruction might overwrite one of the other registers which are +still needed. +Whether it really happens depends on how GCC decides what registers it +uses and how it optimizes the code. + +The objdump utility can give us disassembly. +The futex_atomic_cmpxchg_inatomic() function is inline, so we have to +look for a module that uses the funtion. This is the +cmpxchg_futex_value_locked() function in +kernel/futex.c: + +static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr, + u32 uval, u32 newval) +{ + int ret; + + pagefault_disable(); + ret = futex_atomic_cmpxchg_inatomic(curval, uaddr, uval, newval); + pagefault_enable(); + + return ret; +} + +Now the disassembly. At first from the Kernel package 3.2.23 which has +been compiled with GCC 4.4, remeber this Kernel seemed to work: +objdump -d linux-3.2.23/debian/build/build_ia64_none_mckinley/kernel/futex.o + +0000000000000230 : + 230: 0b 18 80 1b 18 21 [MMI] adds r3=3168,r13;; + 236: 80 40 0d 00 42 00 adds r8=40,r3 + 23c: 00 00 04 00 nop.i 0x0;; + 240: 0b 50 00 10 10 10 [MMI] ld4 r10=[r8];; + 246: 90 08 28 00 42 00 adds r9=1,r10 + 24c: 00 00 04 00 nop.i 0x0;; + 250: 09 00 00 00 01 00 [MMI] nop.m 0x0 + 256: 00 48 20 20 23 00 st4 [r8]=r9 + 25c: 00 00 04 00 nop.i 0x0;; + 260: 08 10 80 06 00 21 [MMI] adds r2=32,r3 + 266: 00 00 00 02 00 00 nop.m 0x0 + 26c: 02 08 f1 52 extr.u r16=r33,0,61 + 270: 05 40 88 00 08 e0 [MLX] addp4 r8=r34,r0 + 276: ff ff 0f 00 00 e0 movl r15=0xfffffffbfff;; + 27c: f1 f7 ff 65 + 280: 09 70 00 04 18 10 [MMI] ld8 r14=[r2] + 286: 00 00 00 02 00 c0 nop.m 0x0 + 28c: f0 80 1c d0 cmp.ltu p6,p7=r15,r16;; + 290: 08 40 fc 1d 09 3b [MMI] cmp.eq p8,p9=-1,r14 + 296: 00 00 00 02 00 40 nop.m 0x0 + 29c: e1 08 2d d0 cmp.ltu p10,p11=r14,r33 + 2a0: 56 01 10 00 40 10 [BBB] (p10) br.cond.spnt.few 2e0 + + 2a6: 02 08 00 80 21 03 (p08) br.cond.dpnt.few 2b0 + + 2ac: 40 00 00 41 (p06) br.cond.spnt.few 2e0 + + 2b0: 0a 00 00 00 22 00 [MMI] mf;; + 2b6: 80 00 00 00 42 00 mov r8=r0 + 2bc: 00 00 04 00 nop.i 0x0 + 2c0: 0b 00 20 40 2a 04 [MMI] mov.m ar.ccv=r8;; + 2c6: 10 1a 85 22 20 00 cmpxchg4.acq r33=[r33],r35,ar.ccv + 2cc: 00 00 04 00 nop.i 0x0;; + 2d0: 10 00 84 40 90 11 [MIB] st4 [r32]=r33 + 2d6: 00 00 00 02 00 00 nop.i 0x0 + 2dc: 20 00 00 40 br.few 2f0 + + 2e0: 09 40 c8 f9 ff 27 [MMI] mov r8=-14 + 2e6: 00 00 00 02 00 00 nop.m 0x0 + 2ec: 00 00 04 00 nop.i 0x0;; + 2f0: 0b 58 20 1a 19 21 [MMI] adds r11=3208,r13;; + 2f6: 20 01 2c 20 20 00 ld4 r18=[r11] + 2fc: 00 00 04 00 nop.i 0x0;; + 300: 0b 88 fc 25 3f 23 [MMI] adds r17=-1,r18;; + 306: 00 88 2c 20 23 00 st4 [r11]=r17 + 30c: 00 00 04 00 nop.i 0x0;; + 310: 11 00 00 00 01 00 [MIB] nop.m 0x0 + 316: 00 00 00 02 00 80 nop.i 0x0 + 31c: 08 00 84 00 br.ret.sptk.many b0;; + +The lines + 2b0: 0a 00 00 00 22 00 [MMI] mf;; + 2b6: 80 00 00 00 42 00 mov r8=r0 + 2bc: 00 00 04 00 nop.i 0x0 + 2c0: 0b 00 20 40 2a 04 [MMI] mov.m ar.ccv=r8;; + 2c6: 10 1a 85 22 20 00 cmpxchg4.acq r33=[r33],r35,ar.ccv + 2cc: 00 00 04 00 nop.i 0x0;; +are the instructions of the assembly block. +The line + 2b6: 80 00 00 00 42 00 mov r8=r0 +sets the r8 register to 0 and after that + 2c0: 0b 00 20 40 2a 04 [MMI] mov.m ar.ccv=r8;; +prepares the 'oldvalue' for the cmpxchg but it takes it from r8. This +is wrong. +What happened here is what I explained above: An input register is +overwritten which is still needed. +The register operand constraints in futex.h are wrong. + +(The problem doesn't occur when the Kernel is compiled with GCC 4.6.) + +The attached patch fixes the register operand constraints in futex.h. +The code after patching of it: + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + { + register unsigned long r8 __asm ("r8") = 0; + unsigned long prev; + __asm__ __volatile__( + " mf;; \n" + " mov ar.ccv=%4;; \n" + "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " .xdata4 \"__ex_table\", 1b-., 2f-. \n" + "[2:]" + : "+r" (r8), "=&r" (prev) + : "r" (uaddr), "r" (newval), + "rO" ((long) (unsigned) oldval) + : "memory"); + *uval = prev; + return r8; + } +} + +I also initialized the 'r8' var with the C programming language. +The _asm qualifier on the definition of the 'r8' var forces GCC to use +the r8 processor register for it. +I don't believe that we should use inline assembly for zeroing out a +local variable. +The constraint is +"+r" (r8) +what means that it is both an input register and an output register. +Note that the page fault handler will modify the r8 register which +will be the return value of the function. +The real fix is +"=&r" (prev) +The & means that GCC must not use any of the input registers to place +this output register in. + +Patched the Kernel 3.2.23 and compiled it with GCC4.4: + +0000000000000230 : + 230: 0b 18 80 1b 18 21 [MMI] adds r3=3168,r13;; + 236: 80 40 0d 00 42 00 adds r8=40,r3 + 23c: 00 00 04 00 nop.i 0x0;; + 240: 0b 50 00 10 10 10 [MMI] ld4 r10=[r8];; + 246: 90 08 28 00 42 00 adds r9=1,r10 + 24c: 00 00 04 00 nop.i 0x0;; + 250: 09 00 00 00 01 00 [MMI] nop.m 0x0 + 256: 00 48 20 20 23 00 st4 [r8]=r9 + 25c: 00 00 04 00 nop.i 0x0;; + 260: 08 10 80 06 00 21 [MMI] adds r2=32,r3 + 266: 20 12 01 10 40 00 addp4 r34=r34,r0 + 26c: 02 08 f1 52 extr.u r16=r33,0,61 + 270: 05 40 00 00 00 e1 [MLX] mov r8=r0 + 276: ff ff 0f 00 00 e0 movl r15=0xfffffffbfff;; + 27c: f1 f7 ff 65 + 280: 09 70 00 04 18 10 [MMI] ld8 r14=[r2] + 286: 00 00 00 02 00 c0 nop.m 0x0 + 28c: f0 80 1c d0 cmp.ltu p6,p7=r15,r16;; + 290: 08 40 fc 1d 09 3b [MMI] cmp.eq p8,p9=-1,r14 + 296: 00 00 00 02 00 40 nop.m 0x0 + 29c: e1 08 2d d0 cmp.ltu p10,p11=r14,r33 + 2a0: 56 01 10 00 40 10 [BBB] (p10) br.cond.spnt.few 2e0 + + 2a6: 02 08 00 80 21 03 (p08) br.cond.dpnt.few 2b0 + + 2ac: 40 00 00 41 (p06) br.cond.spnt.few 2e0 + + 2b0: 0b 00 00 00 22 00 [MMI] mf;; + 2b6: 00 10 81 54 08 00 mov.m ar.ccv=r34 + 2bc: 00 00 04 00 nop.i 0x0;; + 2c0: 09 58 8c 42 11 10 [MMI] cmpxchg4.acq r11=[r33],r35,ar.ccv + 2c6: 00 00 00 02 00 00 nop.m 0x0 + 2cc: 00 00 04 00 nop.i 0x0;; + 2d0: 10 00 2c 40 90 11 [MIB] st4 [r32]=r11 + 2d6: 00 00 00 02 00 00 nop.i 0x0 + 2dc: 20 00 00 40 br.few 2f0 + + 2e0: 09 40 c8 f9 ff 27 [MMI] mov r8=-14 + 2e6: 00 00 00 02 00 00 nop.m 0x0 + 2ec: 00 00 04 00 nop.i 0x0;; + 2f0: 0b 88 20 1a 19 21 [MMI] adds r17=3208,r13;; + 2f6: 30 01 44 20 20 00 ld4 r19=[r17] + 2fc: 00 00 04 00 nop.i 0x0;; + 300: 0b 90 fc 27 3f 23 [MMI] adds r18=-1,r19;; + 306: 00 90 44 20 23 00 st4 [r17]=r18 + 30c: 00 00 04 00 nop.i 0x0;; + 310: 11 00 00 00 01 00 [MIB] nop.m 0x0 + 316: 00 00 00 02 00 80 nop.i 0x0 + 31c: 08 00 84 00 br.ret.sptk.many b0;; + +Much better. +There is a + 270: 05 40 00 00 00 e1 [MLX] mov r8=r0 +which was generated by C code r8 = 0. Below + 2b6: 00 10 81 54 08 00 mov.m ar.ccv=r34 +what means that oldval is no longer overwritten. + +This is Debian bug#702641 +(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702641). + +The patch is applicable on Kernel 3.9-rc1, 3.2.23 and many other versions. + +Signed-off-by: Stephan Schreiber +Signed-off-by: Tony Luck +Signed-off-by: Greg Kroah-Hartman + +--- + arch/ia64/include/asm/futex.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/ia64/include/asm/futex.h ++++ b/arch/ia64/include/asm/futex.h +@@ -107,16 +107,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, + return -EFAULT; + + { +- register unsigned long r8 __asm ("r8"); ++ register unsigned long r8 __asm ("r8") = 0; + unsigned long prev; + __asm__ __volatile__( + " mf;; \n" +- " mov %0=r0 \n" + " mov ar.ccv=%4;; \n" + "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " .xdata4 \"__ex_table\", 1b-., 2f-. \n" + "[2:]" +- : "=r" (r8), "=r" (prev) ++ : "+r" (r8), "=&r" (prev) + : "r" (uaddr), "r" (newval), + "rO" ((long) (unsigned) oldval) + : "memory"); diff --git a/queue-3.0/wrong-asm-register-contraints-in-the-kvm-implementation.patch b/queue-3.0/wrong-asm-register-contraints-in-the-kvm-implementation.patch new file mode 100644 index 00000000000..99c754b842c --- /dev/null +++ b/queue-3.0/wrong-asm-register-contraints-in-the-kvm-implementation.patch @@ -0,0 +1,95 @@ +From de53e9caa4c6149ef4a78c2f83d7f5b655848767 Mon Sep 17 00:00:00 2001 +From: Stephan Schreiber +Date: Tue, 19 Mar 2013 15:27:12 -0700 +Subject: Wrong asm register contraints in the kvm implementation + +From: Stephan Schreiber + +commit de53e9caa4c6149ef4a78c2f83d7f5b655848767 upstream. + +The Linux Kernel contains some inline assembly source code which has +wrong asm register constraints in arch/ia64/kvm/vtlb.c. + +I observed this on Kernel 3.2.35 but it is also true on the most +recent Kernel 3.9-rc1. + +File arch/ia64/kvm/vtlb.c: + +u64 guest_vhpt_lookup(u64 iha, u64 *pte) +{ + u64 ret; + struct thash_data *data; + + data = __vtr_lookup(current_vcpu, iha, D_TLB); + if (data != NULL) + thash_vhpt_insert(current_vcpu, data->page_flags, + data->itir, iha, D_TLB); + + asm volatile ( + "rsm psr.ic|psr.i;;" + "srlz.d;;" + "ld8.s r9=[%1];;" + "tnat.nz p6,p7=r9;;" + "(p6) mov %0=1;" + "(p6) mov r9=r0;" + "(p7) extr.u r9=r9,0,53;;" + "(p7) mov %0=r0;" + "(p7) st8 [%2]=r9;;" + "ssm psr.ic;;" + "srlz.d;;" + "ssm psr.i;;" + "srlz.d;;" + : "=r"(ret) : "r"(iha), "r"(pte):"memory"); + + return ret; +} + +The list of output registers is + : "=r"(ret) : "r"(iha), "r"(pte):"memory"); +The constraint "=r" means that the GCC has to maintain that these vars +are in registers and contain valid info when the program flow leaves +the assembly block (output registers). +But "=r" also means that GCC can put them in registers that are used +as input registers. Input registers are iha, pte on the example. +If the predicate p7 is true, the 8th assembly instruction + "(p7) mov %0=r0;" +is the first one which writes to a register which is maintained by the +register constraints; it sets %0. %0 means the first register operand; +it is ret here. +This instruction might overwrite the %2 register (pte) which is needed +by the next instruction: + "(p7) st8 [%2]=r9;;" +Whether it really happens depends on how GCC decides what registers it +uses and how it optimizes the code. + +The attached patch fixes the register operand constraints in +arch/ia64/kvm/vtlb.c. +The register constraints should be + : "=&r"(ret) : "r"(iha), "r"(pte):"memory"); +The & means that GCC must not use any of the input registers to place +this output register in. + +This is Debian bug#702639 +(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702639). + +The patch is applicable on Kernel 3.9-rc1, 3.2.35 and many other versions. + +Signed-off-by: Stephan Schreiber +Signed-off-by: Tony Luck +Signed-off-by: Greg Kroah-Hartman + +--- + arch/ia64/kvm/vtlb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/ia64/kvm/vtlb.c ++++ b/arch/ia64/kvm/vtlb.c +@@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) + "srlz.d;;" + "ssm psr.i;;" + "srlz.d;;" +- : "=r"(ret) : "r"(iha), "r"(pte):"memory"); ++ : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); + + return ret; + }