Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32eb150a authored by Paul Mackerras's avatar Paul Mackerras Committed by Michael Ellerman
Browse files

KVM: PPC: Book3S HV: Handle hypervisor instruction faults better



Currently the code for handling hypervisor instruction page faults
passes 0 for the flags indicating the type of fault, which is OK in
the usual case that the page is not mapped in the partition-scoped
page tables.  However, there are other causes for hypervisor
instruction page faults, such as not being to update a reference
(R) or change (C) bit.  The cause is indicated in bits in HSRR1,
including a bit which indicates that the fault is due to not being
able to write to a page (for example to update an R or C bit).
Not handling these other kinds of faults correctly can lead to a
loop of continual faults without forward progress in the guest.

In order to handle these faults better, this patch constructs a
"DSISR-like" value from the bits which DSISR and SRR1 (for a HISI)
have in common, and passes it to kvmppc_book3s_hv_page_fault() so
that it knows what caused the fault.

Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 95a6432c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -766,6 +766,7 @@
#define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
#define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
#define   HSRR1_HISI_WRITE	0x00010000 /* HISI bcs couldn't update mem */

#define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
#define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
+4 −1
Original line number Diff line number Diff line
@@ -1188,7 +1188,10 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
		break;
	case BOOK3S_INTERRUPT_H_INST_STORAGE:
		vcpu->arch.fault_dar = kvmppc_get_pc(vcpu);
		vcpu->arch.fault_dsisr = 0;
		vcpu->arch.fault_dsisr = vcpu->arch.shregs.msr &
			DSISR_SRR1_MATCH_64S;
		if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE)
			vcpu->arch.fault_dsisr |= DSISR_ISSTORE;
		r = RESUME_PAGE_FAULT;
		break;
	/*