KVM: PPC: Book3S HV: Fix list traversal in error case

Message ID 20150429044907.GA18720@drongo
State New, archived
Headers show

Commit Message

Paul Mackerras April 29, 2015, 4:49 a.m.
This fixes a regression introduced in commit 25fedfca94cf, "KVM: PPC:
Book3S HV: Move vcore preemption point up into kvmppc_run_vcpu", which
leads to a user-triggerable oops.

In the case where we try to run a vcore on a physical core that is
not in single-threaded mode, or the vcore has too many threads for
the physical core, we iterate the list of runnable vcpus to make
each one return an EBUSY error to userspace.  Since this involves
taking each vcpu off the runnable_threads list for the vcore, we
need to use list_for_each_entry_safe rather than list_for_each_entry
to traverse the list.  Otherwise the kernel will crash with an oops
message like this:

Unable to handle kernel paging request for data at address 0x000fff88
Faulting instruction address: 0xd00000001e635dc8
Oops: Kernel access of bad area, sig: 11 [#2]
SMP NR_CPUS=1024 NUMA PowerNV
...
CPU: 48 PID: 91256 Comm: qemu-system-ppc Tainted: G      D        3.18.0 #1
task: c00000274e507500 ti: c0000027d1924000 task.ti: c0000027d1924000
NIP: d00000001e635dc8 LR: d00000001e635df8 CTR: c00000000011ba50
REGS: c0000027d19275b0 TRAP: 0300   Tainted: G      D         (3.18.0)
MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE>  CR: 22002824  XER: 00000000
CFAR: c000000000008468 DAR: 00000000000fff88 DSISR: 40000000 SOFTE: 1
GPR00: d00000001e635df8 c0000027d1927830 d00000001e64c850 0000000000000001
GPR04: 0000000000000001 0000000000000001 0000000000000000 0000000000000000
GPR08: 0000000000200200 0000000000000000 0000000000000000 d00000001e63e588
GPR12: 0000000000002200 c000000007dbc800 c000000fc7800000 000000000000000a
GPR16: fffffffffffffffc c000000fd5439690 c000000fc7801c98 0000000000000001
GPR20: 0000000000000003 c0000027d1927aa8 c000000fd543b348 c000000fd543b350
GPR24: 0000000000000000 c000000fa57f0000 0000000000000030 0000000000000000
GPR28: fffffffffffffff0 c000000fd543b328 00000000000fe468 c000000fd543b300
NIP [d00000001e635dc8] kvmppc_run_core+0x198/0x17c0 [kvm_hv]
LR [d00000001e635df8] kvmppc_run_core+0x1c8/0x17c0 [kvm_hv]
Call Trace:
[c0000027d1927830] [d00000001e635df8] kvmppc_run_core+0x1c8/0x17c0 [kvm_hv] (unreliable)
[c0000027d1927a30] [d00000001e638350] kvmppc_vcpu_run_hv+0x5b0/0xdd0 [kvm_hv]
[c0000027d1927b70] [d00000001e510504] kvmppc_vcpu_run+0x44/0x60 [kvm]
[c0000027d1927ba0] [d00000001e50d4a4] kvm_arch_vcpu_ioctl_run+0x64/0x170 [kvm]
[c0000027d1927be0] [d00000001e504be8] kvm_vcpu_ioctl+0x5e8/0x7a0 [kvm]
[c0000027d1927d40] [c0000000002d6720] do_vfs_ioctl+0x490/0x780
[c0000027d1927de0] [c0000000002d6ae4] SyS_ioctl+0xd4/0xf0
[c0000027d1927e30] [c000000000009358] syscall_exit+0x0/0x98
Instruction dump:
60000000 60420000 387e1b30 38800003 38a00001 38c00000 480087d9 e8410018
ebde1c98 7fbdf040 3bdee368 419e0048 <813e1b20> 939e1b18 2f890001 409effcc
---[ end trace 8cdf50251cca6680 ]---

Fixes: 25fedfca94cf
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
Since this is a regression fix for a patch that went in post 4.0,
it should go in for 4.1.

 arch/powerpc/kvm/book3s_hv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Alexander Graf May 9, 2015, 7:50 p.m. | #1
On 29.04.15 06:49, Paul Mackerras wrote:
> This fixes a regression introduced in commit 25fedfca94cf, "KVM: PPC:
> Book3S HV: Move vcore preemption point up into kvmppc_run_vcpu", which
> leads to a user-triggerable oops.
> 
> In the case where we try to run a vcore on a physical core that is
> not in single-threaded mode, or the vcore has too many threads for
> the physical core, we iterate the list of runnable vcpus to make
> each one return an EBUSY error to userspace.  Since this involves
> taking each vcpu off the runnable_threads list for the vcore, we
> need to use list_for_each_entry_safe rather than list_for_each_entry
> to traverse the list.  Otherwise the kernel will crash with an oops
> message like this:
> 
> Unable to handle kernel paging request for data at address 0x000fff88
> Faulting instruction address: 0xd00000001e635dc8
> Oops: Kernel access of bad area, sig: 11 [#2]
> SMP NR_CPUS=1024 NUMA PowerNV
> ...
> CPU: 48 PID: 91256 Comm: qemu-system-ppc Tainted: G      D        3.18.0 #1
> task: c00000274e507500 ti: c0000027d1924000 task.ti: c0000027d1924000
> NIP: d00000001e635dc8 LR: d00000001e635df8 CTR: c00000000011ba50
> REGS: c0000027d19275b0 TRAP: 0300   Tainted: G      D         (3.18.0)
> MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE>  CR: 22002824  XER: 00000000
> CFAR: c000000000008468 DAR: 00000000000fff88 DSISR: 40000000 SOFTE: 1
> GPR00: d00000001e635df8 c0000027d1927830 d00000001e64c850 0000000000000001
> GPR04: 0000000000000001 0000000000000001 0000000000000000 0000000000000000
> GPR08: 0000000000200200 0000000000000000 0000000000000000 d00000001e63e588
> GPR12: 0000000000002200 c000000007dbc800 c000000fc7800000 000000000000000a
> GPR16: fffffffffffffffc c000000fd5439690 c000000fc7801c98 0000000000000001
> GPR20: 0000000000000003 c0000027d1927aa8 c000000fd543b348 c000000fd543b350
> GPR24: 0000000000000000 c000000fa57f0000 0000000000000030 0000000000000000
> GPR28: fffffffffffffff0 c000000fd543b328 00000000000fe468 c000000fd543b300
> NIP [d00000001e635dc8] kvmppc_run_core+0x198/0x17c0 [kvm_hv]
> LR [d00000001e635df8] kvmppc_run_core+0x1c8/0x17c0 [kvm_hv]
> Call Trace:
> [c0000027d1927830] [d00000001e635df8] kvmppc_run_core+0x1c8/0x17c0 [kvm_hv] (unreliable)
> [c0000027d1927a30] [d00000001e638350] kvmppc_vcpu_run_hv+0x5b0/0xdd0 [kvm_hv]
> [c0000027d1927b70] [d00000001e510504] kvmppc_vcpu_run+0x44/0x60 [kvm]
> [c0000027d1927ba0] [d00000001e50d4a4] kvm_arch_vcpu_ioctl_run+0x64/0x170 [kvm]
> [c0000027d1927be0] [d00000001e504be8] kvm_vcpu_ioctl+0x5e8/0x7a0 [kvm]
> [c0000027d1927d40] [c0000000002d6720] do_vfs_ioctl+0x490/0x780
> [c0000027d1927de0] [c0000000002d6ae4] SyS_ioctl+0xd4/0xf0
> [c0000027d1927e30] [c000000000009358] syscall_exit+0x0/0x98
> Instruction dump:
> 60000000 60420000 387e1b30 38800003 38a00001 38c00000 480087d9 e8410018
> ebde1c98 7fbdf040 3bdee368 419e0048 <813e1b20> 939e1b18 2f890001 409effcc
> ---[ end trace 8cdf50251cca6680 ]---
> 
> Fixes: 25fedfca94cf
> Signed-off-by: Paul Mackerras <paulus@samba.org>

Reviewed-by: Alexander Graf <agraf@suse.de>

Paolo, can you please take this patch into 4.1 directly?


Thanks a lot,

Alex
--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini May 10, 2015, 3:05 p.m. | #2
On 09/05/2015 21:50, Alexander Graf wrote:
> Reviewed-by: Alexander Graf <agraf@suse.de>
> 
> Paolo, can you please take this patch into 4.1 directly?

Sure.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 48d3c5d..df81caa 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1952,7 +1952,7 @@  static void post_guest_process(struct kvmppc_vcore *vc)
  */
 static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 {
-	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *vcpu, *vnext;
 	int i;
 	int srcu_idx;
 
@@ -1982,7 +1982,8 @@  static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 	 */
 	if ((threads_per_core > 1) &&
 	    ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) {
-		list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
+		list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,
+					 arch.run_list) {
 			vcpu->arch.ret = -EBUSY;
 			kvmppc_remove_runnable(vc, vcpu);
 			wake_up(&vcpu->arch.cpu_run);