From c8b6cd3285edb33d41adf1208eba0e72f1144428 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Wed, 11 Mar 2020 19:13:32 -0300 Subject: [PATCH] PPC: KVM: Book3S HV: Fix conflicting use of HSTATE_HOST_R1 Currently it's possible to crash a host from a guest by calling a hypercall when CPU is in TM suspended mode. Whilst on guest a TM Bad Thing is caught, on host the following traces are observed: [ 618.563991] Oops: Exception in kernel mode, sig: 4 [#1] [ 618.563994] LE SMP NR_CPUS=2048 NUMA PowerNV [ 618.563999] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp bridge stp llc ebtable_filter ebtables devlink ip6table_filter ip6_tables iptable_filter kvm_hv kvm vmx_crypto ipmi_powernv ipmi_devintf ipmi_msghandler uio_pdrv_genirq uio leds_powernv crct10dif_vpmsum ibmpowernv powernv_rng sch_fq_codel nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables x_tables autofs4 xfs btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear lpfc crc32c_vpmsum nvmet_fc nvmet nvme_fc nvme_fabrics nvme_core tg3 ipr scsi_transport_fc [ 618.564064] CPU: 51 PID: 0 Comm: swapper/51 Not tainted 4.15.0-76-generic #86-Ubuntu [ 618.564066] NIP: 0000000000000000 LR: 0000000000000000 CTR: d0000000072f0580 [ 618.564068] REGS: c00000003fd9bca0 TRAP: 0e40 Not tainted (4.15.0-76-generic) [ 618.564068] MSR: 9000000102883003 CR: 28200222 XER: 20000000 [ 618.564077] CFAR: c0000000000f53f0 SOFTE: 0 [ 618.564077] GPR00: 0000000000000000 c00000003fd9bf20 c00000000171c800 0000000000000000 [ 618.564077] GPR04: c000000ff4d10000 c0000000ff067400 000000000ad0cc9e c0000000000fb4bc [ 618.564077] GPR08: 804800000180f000 c000000dcabcbe80 0000000000000000 0000000020000000 [ 618.564077] GPR12: 0000000000000e80 c00000000faa3100 0000000000000000 0000000000000000 [ 618.564077] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 618.564077] GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 618.564077] GPR24: 0000000000000000 d0000000072e0158 000000000000009b 000000000000009c [ 618.564077] GPR28: 000000000000009c 0000000000000000 0000000000000000 0010000000000000 [ 618.564100] NIP [0000000000000000] (null) [ 618.564101] LR [0000000000000000] (null) [ 618.564101] Call Trace: [ 618.564102] Instruction dump: [ 618.564105] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX [ 618.564109] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX 0100421c f2820104 0000001b 00000132 [ 618.564118] ---[ end trace f0be3cc10ea6fc44 ]--- [ 618.569897] [ 618.593555] KVM: CPU 51 seems to be stuck [ 258.967652] Kernel panic - not syncing: Attempted to kill the idle task! [ 258.967677] Unable to handle kernel paging request for data at address 0xc000001ff6c9d700 [ 618.596478] Faulting instruction address: 0xc000000000077cf0 [ 618.596479] Oops: Kernel access of bad area, sig: 11 [#2] [ 618.596480] LE SMP NR_CPUS=2048 NUMA PowerNV [ 618.596482] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp bridge stp llc ebtable_filter ebtables devlink ip6table_filter ip6_tables iptable_filter kvm_hv kvm vmx_crypto ipmi_powernv ipmi_devintf ipmi_msghandler uio_pdrv_genirq uio leds_powernv crct10dif_vpmsum ibmpowernv powernv_rng sch_fq_codel nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables x_tables autofs4 xfs btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear lpfc crc32c_vpmsum nvmet_fc nvmet nvme_fc nvme_fabrics nvme_core tg3 ipr scsi_transport_fc [ 618.596521] CPU: 51 PID: 0 Comm: swapper/51 Tainted: G D 4.15.0-76-generic #86-Ubuntu [ 618.596522] NIP: c000000000077cf0 LR: c000000000080c84 CTR: c000000000077c90 [ 618.596524] REGS: c00000003fd9b040 TRAP: 0300 Tainted: G D (4.15.0-76-generic) [ 618.596524] MSR: 9000000000001033 CR: 28244242 XER: 00000000 [ 618.596530] CFAR: c000000000080c80 DAR: c000001ff6c9d700 DSISR: 40000000 SOFTE: 0 [ 618.596530] GPR00: c000000000080c84 c00000003fd9b2c0 c00000000171c800 0000000006c9d700 [ 618.596530] GPR04: 00000000000001ac 0071d13aa0080040 0000000000000002 0000000000000002 [ 618.596530] GPR08: 0000000000000001 0000000000000002 00000e3a27540100 c000001ff6c9d700 [ 618.596530] GPR12: c000001ff0000000 c00000000faa3100 0000000000000000 0000000000000000 [ 618.596530] GPR16: 0000000000000004 0071d13aa0080040 00000000000001ac c0000000018be858 [ 618.596530] GPR20: 800000000000000e d00038008004000c 00000000071d13aa c0000000018be280 [ 618.596530] GPR24: 0000000000000001 0000000000000002 0000000000000300 0000000000000300 [ 618.596530] GPR28: 4000000000000000 0000000000000000 c0000000018be2d0 00000000000000b0 [ 618.596560] NIP [c000000000077cf0] native_hpte_updatepp+0x60/0x680 [ 618.596562] LR [c000000000080c84] __hash_page_64K+0x4c4/0x560 [ 618.596562] Call Trace: [ 618.596563] Instruction dump: [ 618.596565] 791cf046 3fc2001a 3bde1ad0 3d62001a 396b2188 91810008 f821ff71 7fbefa14 [ 618.596570] ebbd0048 e98b0000 7d4ae878 7d6c1a14 <7c0c1c28> 794a3e24 7f9c5378 48000018 [ 618.596576] ---[ end trace f0be3cc10ea6fc45 ]--- [ 618.602738] [ 618.625946] KVM: CPU 51 seems to be stuck [ 258.999498] Kernel panic - not syncing: Attempted to kill the idle task! [ 618.653500] KVM: CPU 51 seems to be stuck This is due to conflicting use of HSTATE_HOST_R1 to store r1 state in kvmppc_hv_entry plus in kvmppc_{save,restore}_tm leading to a stack corruption. The commit that introduced such a conflict is f024ee098476 ("KVM: PPC: Book3S HV: Pull out TM state save/restore into separate procedures") but issue really appears when change 87a11bb6a7f7 ("KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode") is applied too because it creates a new stack to the two conflicting r1 stored to HSTATE_HOST_R1 are different. The issue was fixed accidentally by 6f597c6b63b6 ("KVM: PPC: Book3S PR: Add guest MSR parameter for kvmppc_save_tm()/kvmppc_restore_tm()") which is actually a change most related to Book3S PR. This commit fixes the issue by backporting from 6f597c6b63b6 the part only responsible for storing r1 to a different memory location (HSTATE_SCRATCH2) avoiding the conflict and so the stack corruption. On Ubuntu Bionic, tag "Ubuntu-4.15.0-91.92" is affected. --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b5bd2f4902b3..8760e86a5615 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -3080,7 +3080,7 @@ kvmppc_save_tm: rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 beq 1f /* TM not active in guest. */ - std r1, HSTATE_HOST_R1(r13) + std r1, HSTATE_SCRATCH2(r13) li r3, TM_CAUSE_KVM_RESCHED BEGIN_FTR_SECTION @@ -3124,7 +3124,7 @@ BEGIN_FTR_SECTION * we already have it), therefore we can now use any volatile GPR. */ /* Reload stack pointer and TOC. */ - ld r1, HSTATE_HOST_R1(r13) + ld r1, HSTATE_SCRATCH2(r13) ld r2, PACATOC(r13) /* Set MSR RI now we have r1 and r13 back. */ li r5, MSR_RI @@ -3179,7 +3179,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST) std r4, VCPU_GPRS_TM(9)(r9) /* Reload stack pointer and TOC. */ - ld r1, HSTATE_HOST_R1(r13) + ld r1, HSTATE_SCRATCH2(r13) ld r2, PACATOC(r13) /* Set MSR RI now we have r1 and r13 back. */ @@ -3267,7 +3267,7 @@ kvmppc_restore_tm: ld r5, VCPU_MSR(r4) rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 beqlr /* TM not active in guest */ - std r1, HSTATE_HOST_R1(r13) + std r1, HSTATE_SCRATCH2(r13) /* Make sure the failure summary is set, otherwise we'll program check * when we trechkpt. It's possible that this might have been not set @@ -3352,7 +3352,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST) ld r29, HSTATE_DSCR(r13) mtspr SPRN_DSCR, r29 ld r4, HSTATE_KVM_VCPU(r13) - ld r1, HSTATE_HOST_R1(r13) + ld r1, HSTATE_SCRATCH2(r13) ld r2, PACATMSCRATCH(r13) /* Set the MSR RI since we have our registers back. */ -- 2.17.1