lkml.org 
[lkml]   [2021]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 17/25] KVM: PPC: Book3S HV P9: Fixes for TM softpatch interrupt NIP
    Date
    From: Nicholas Piggin <npiggin@gmail.com>

    [ Upstream commit 4782e0cd0d184d727ad3b0cfe20d1d44d9f98239 ]

    The softpatch interrupt sets HSRR0 to the faulting instruction +4, so
    it should subtract 4 for the faulting instruction address in the case
    it is a TM softpatch interrupt (the instruction was not executed) and
    it was not emulated.

    Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20210811160134.904987-4-npiggin@gmail.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/kvm/book3s_hv_tm.c | 17 +++++++++++++++--
    1 file changed, 15 insertions(+), 2 deletions(-)

    diff --git a/arch/powerpc/kvm/book3s_hv_tm.c b/arch/powerpc/kvm/book3s_hv_tm.c
    index e7fd60cf9780..327abfbe13c3 100644
    --- a/arch/powerpc/kvm/book3s_hv_tm.c
    +++ b/arch/powerpc/kvm/book3s_hv_tm.c
    @@ -49,6 +49,15 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    u64 newmsr, bescr;
    int ra, rs;

    + /*
    + * The TM softpatch interrupt sets NIP to the instruction following
    + * the faulting instruction, which is not executed. Rewind nip to the
    + * faulting instruction so it looks like a normal synchronous
    + * interrupt, then update nip in the places where the instruction is
    + * emulated.
    + */
    + vcpu->arch.regs.nip -= 4;
    +
    /*
    * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit
    * in these instructions, so masking bit 31 out doesn't change these
    @@ -70,7 +79,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    (newmsr & MSR_TM)));
    newmsr = sanitize_msr(newmsr);
    vcpu->arch.shregs.msr = newmsr;
    - vcpu->arch.cfar = vcpu->arch.regs.nip - 4;
    + vcpu->arch.cfar = vcpu->arch.regs.nip;
    vcpu->arch.regs.nip = vcpu->arch.shregs.srr0;
    return RESUME_GUEST;

    @@ -103,7 +112,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    vcpu->arch.bescr = bescr;
    msr = (msr & ~MSR_TS_MASK) | MSR_TS_T;
    vcpu->arch.shregs.msr = msr;
    - vcpu->arch.cfar = vcpu->arch.regs.nip - 4;
    + vcpu->arch.cfar = vcpu->arch.regs.nip;
    vcpu->arch.regs.nip = vcpu->arch.ebbrr;
    return RESUME_GUEST;

    @@ -119,6 +128,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    newmsr = (newmsr & ~MSR_LE) | (msr & MSR_LE);
    newmsr = sanitize_msr(newmsr);
    vcpu->arch.shregs.msr = newmsr;
    + vcpu->arch.regs.nip += 4;
    return RESUME_GUEST;

    /* ignore bit 31, see comment above */
    @@ -155,6 +165,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    msr = (msr & ~MSR_TS_MASK) | MSR_TS_S;
    }
    vcpu->arch.shregs.msr = msr;
    + vcpu->arch.regs.nip += 4;
    return RESUME_GUEST;

    /* ignore bit 31, see comment above */
    @@ -192,6 +203,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
    (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
    vcpu->arch.shregs.msr &= ~MSR_TS_MASK;
    + vcpu->arch.regs.nip += 4;
    return RESUME_GUEST;

    /* ignore bit 31, see comment above */
    @@ -223,6 +235,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
    vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
    (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
    vcpu->arch.shregs.msr = msr | MSR_TS_S;
    + vcpu->arch.regs.nip += 4;
    return RESUME_GUEST;
    }

    --
    2.30.2
    \
     
     \ /
      Last update: 2021-09-10 03:02    [W:2.216 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site