Book3S_32 doesn't know about segment faults. It only knows about page faults.
So in order to know that we didn't map a segment, we need to fake segment
faults.

We do this by setting invalid segment registers to an invalid VSID and then
check for that VSID on normal page faults.

Signed-off-by: Alexander Graf <ag...@suse.de>
---
 arch/powerpc/kvm/book3s.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b917b97..178ddd4 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -774,6 +774,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
        switch (exit_nr) {
        case BOOK3S_INTERRUPT_INST_STORAGE:
                vcpu->stat.pf_instruc++;
+
+#ifdef CONFIG_PPC_BOOK3S_32
+               /* We set segments as unused segments when invalidating them. So
+                * treat the respective fault as segment fault. */
+               if (to_svcpu(vcpu)->sr[kvmppc_get_pc(vcpu) >> SID_SHIFT]
+                   == SR_INVALID) {
+                       kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu));
+                       r = RESUME_GUEST;
+                       break;
+               }
+#endif
+
                /* only care about PTEG not found errors, but leave NX alone */
                if (to_svcpu(vcpu)->shadow_srr1 & 0x40000000) {
                        r = kvmppc_handle_pagefault(run, vcpu, 
kvmppc_get_pc(vcpu), exit_nr);
@@ -798,6 +810,17 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
        {
                ulong dar = kvmppc_get_fault_dar(vcpu);
                vcpu->stat.pf_storage++;
+
+#ifdef CONFIG_PPC_BOOK3S_32
+               /* We set segments as unused segments when invalidating them. So
+                * treat the respective fault as segment fault. */
+               if ((to_svcpu(vcpu)->sr[dar >> SID_SHIFT]) == SR_INVALID) {
+                       kvmppc_mmu_map_segment(vcpu, dar);
+                       r = RESUME_GUEST;
+                       break;
+               }
+#endif
+
                /* The only case we need to handle is missing shadow PTEs */
                if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) {
                        r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr);
-- 
1.6.0.2

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

Reply via email to