diff mbox series

[RFC,09/32] KVM: PPC: Book3S HV: Handle hypervisor instruction faults better

Message ID 1537524123-9578-10-git-send-email-paulus@ozlabs.org
State Superseded
Headers show
Series KVM: PPC: Book3S HV: Nested HV virtualization | expand

Commit Message

Paul Mackerras Sept. 21, 2018, 10:01 a.m. UTC
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.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
 arch/powerpc/include/asm/reg.h | 1 +
 arch/powerpc/kvm/book3s_hv.c   | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

Comments

David Gibson Sept. 25, 2018, 6:53 a.m. UTC | #1
On Fri, Sep 21, 2018 at 08:01:40PM +1000, Paul Mackerras wrote:
> 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.
> 
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  arch/powerpc/include/asm/reg.h | 1 +
>  arch/powerpc/kvm/book3s_hv.c   | 5 ++++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index e5b314e..6fda746 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -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 */
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 8576a7b..e0e92f2 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -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;
>  	/*
diff mbox series

Patch

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index e5b314e..6fda746 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -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 */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 8576a7b..e0e92f2 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -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;
 	/*