aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2015-10-27 01:10:20 -0400
committerPaul Mackerras <paulus@samba.org>2015-11-05 23:40:42 -0500
commitcf29b21595b91eecce6ca69b0f92d60bca076ef0 (patch)
tree503357c2f4b036259c6061923170047dfbdcf2f5
parenta3eaa8649e4c6a6afdafaa04b9114fb230617bb1 (diff)
KVM: PPC: Book3S HV: Synthesize segment fault if SLB lookup fails
When handling a hypervisor data or instruction storage interrupt (HDSI or HISI), we look up the SLB entry for the address being accessed in order to translate the effective address to a virtual address which can be looked up in the guest HPT. This lookup can occasionally fail due to the guest replacing an SLB entry without invalidating the evicted SLB entry. In this situation an ERAT (effective to real address translation cache) entry can persist and be used by the hardware even though there is no longer a corresponding SLB entry. Previously we would just deliver a data or instruction storage interrupt (DSI or ISI) to the guest in this case. However, this is not correct and has been observed to cause guests to crash, typically with a data storage protection interrupt on a store to the vmemmap area. Instead, what we do now is to synthesize a data or instruction segment interrupt. That should cause the guest to reload an appropriate entry into the SLB and retry the faulting instruction. If it still faults, we should find an appropriate SLB entry next time and be able to handle the fault. Tested-by: Thomas Huth <thuth@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b1dab8d1d885..3c6badcd53ef 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1749,7 +1749,8 @@ kvmppc_hdsi:
1749 beq 3f 1749 beq 3f
1750 clrrdi r0, r4, 28 1750 clrrdi r0, r4, 28
1751 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */ 1751 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
1752 bne 1f /* if no SLB entry found */ 1752 li r0, BOOK3S_INTERRUPT_DATA_SEGMENT
1753 bne 7f /* if no SLB entry found */
17534: std r4, VCPU_FAULT_DAR(r9) 17544: std r4, VCPU_FAULT_DAR(r9)
1754 stw r6, VCPU_FAULT_DSISR(r9) 1755 stw r6, VCPU_FAULT_DSISR(r9)
1755 1756
@@ -1768,14 +1769,15 @@ kvmppc_hdsi:
1768 cmpdi r3, -2 /* MMIO emulation; need instr word */ 1769 cmpdi r3, -2 /* MMIO emulation; need instr word */
1769 beq 2f 1770 beq 2f
1770 1771
1771 /* Synthesize a DSI for the guest */ 1772 /* Synthesize a DSI (or DSegI) for the guest */
1772 ld r4, VCPU_FAULT_DAR(r9) 1773 ld r4, VCPU_FAULT_DAR(r9)
1773 mr r6, r3 1774 mr r6, r3
17741: mtspr SPRN_DAR, r4 17751: li r0, BOOK3S_INTERRUPT_DATA_STORAGE
1775 mtspr SPRN_DSISR, r6 1776 mtspr SPRN_DSISR, r6
17777: mtspr SPRN_DAR, r4
1776 mtspr SPRN_SRR0, r10 1778 mtspr SPRN_SRR0, r10
1777 mtspr SPRN_SRR1, r11 1779 mtspr SPRN_SRR1, r11
1778 li r10, BOOK3S_INTERRUPT_DATA_STORAGE 1780 mr r10, r0
1779 bl kvmppc_msr_interrupt 1781 bl kvmppc_msr_interrupt
1780fast_interrupt_c_return: 1782fast_interrupt_c_return:
17816: ld r7, VCPU_CTR(r9) 17836: ld r7, VCPU_CTR(r9)
@@ -1823,7 +1825,8 @@ kvmppc_hisi:
1823 beq 3f 1825 beq 3f
1824 clrrdi r0, r10, 28 1826 clrrdi r0, r10, 28
1825 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */ 1827 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
1826 bne 1f /* if no SLB entry found */ 1828 li r0, BOOK3S_INTERRUPT_INST_SEGMENT
1829 bne 7f /* if no SLB entry found */
18274: 18304:
1828 /* Search the hash table. */ 1831 /* Search the hash table. */
1829 mr r3, r9 /* vcpu pointer */ 1832 mr r3, r9 /* vcpu pointer */
@@ -1840,11 +1843,12 @@ kvmppc_hisi:
1840 cmpdi r3, -1 /* handle in kernel mode */ 1843 cmpdi r3, -1 /* handle in kernel mode */
1841 beq guest_exit_cont 1844 beq guest_exit_cont
1842 1845
1843 /* Synthesize an ISI for the guest */ 1846 /* Synthesize an ISI (or ISegI) for the guest */
1844 mr r11, r3 1847 mr r11, r3
18451: mtspr SPRN_SRR0, r10 18481: li r0, BOOK3S_INTERRUPT_INST_STORAGE
18497: mtspr SPRN_SRR0, r10
1846 mtspr SPRN_SRR1, r11 1850 mtspr SPRN_SRR1, r11
1847 li r10, BOOK3S_INTERRUPT_INST_STORAGE 1851 mr r10, r0
1848 bl kvmppc_msr_interrupt 1852 bl kvmppc_msr_interrupt
1849 b fast_interrupt_c_return 1853 b fast_interrupt_c_return
1850 1854