From: Sukadev Bhattiprolu <sukadev@xxxxxxxxxxxxxxxxxx> All hcalls from a secure VM go to the ultravisor from where they are reflected into the HV. When we (HV) complete processing such hcalls, we should return to the UV rather than to the guest kernel. Before reflecting the hcall, the ultravisor sets the MSR_S bit in SRR1 (which gets copied into HSRR1 in kvmppc_interrupt_hv()). If the S bit is set in HSRR1, return to ultravisor (using UV_RETURN ucall). Otherwise return to the guest. Thanks to input from Ram Pai and Mike Anderson. Signed-off-by: Sukadev Bhattiprolu <sukadev@xxxxxxxxxxxxxxxxxx> Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx> [fix: UV_RETURN token number] --- arch/powerpc/include/uapi/asm/uapi_uvcall.h | 1 + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/uapi_uvcall.h b/arch/powerpc/include/uapi/asm/uapi_uvcall.h index bbcd026..b657af6 100644 --- a/arch/powerpc/include/uapi/asm/uapi_uvcall.h +++ b/arch/powerpc/include/uapi/asm/uapi_uvcall.h @@ -11,4 +11,5 @@ #define UV_WRITE_PATE 0xf104 #define UV_RESTRICTED_SPR_WRITE 0xf108 #define UV_RESTRICTED_SPR_READ 0xf10C +#define UV_RETURN 0xf11C #endif /* #ifndef UAPI_UC_H */ diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 9b8d50a..6f2f786 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -35,6 +35,7 @@ #include <asm/thread_info.h> #include <asm/asm-compat.h> #include <asm/feature-fixups.h> +#include <asm/ucall-api.h> /* Sign-extend HDEC if not on POWER9 */ #define EXTEND_HDEC(reg) \ @@ -1092,15 +1093,12 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ld r5, VCPU_LR(r4) - ld r6, VCPU_CR(r4) mtlr r5 - mtcr r6 ld r1, VCPU_GPR(R1)(r4) ld r2, VCPU_GPR(R2)(r4) ld r3, VCPU_GPR(R3)(r4) ld r5, VCPU_GPR(R5)(r4) - ld r6, VCPU_GPR(R6)(r4) ld r7, VCPU_GPR(R7)(r4) ld r8, VCPU_GPR(R8)(r4) ld r9, VCPU_GPR(R9)(r4) @@ -1119,10 +1117,33 @@ BEGIN_FTR_SECTION mtspr SPRN_HDSISR, r0 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + mfspr r6, SPRN_HSRR1 + andis. r6, r6, MSR_S@high + cmplwi r6, 0 + bne ret_to_ultra; + + lwz r6, VCPU_CR(r4) + mtcr r6 + + ld r6, VCPU_GPR(R6)(r4) ld r0, VCPU_GPR(R0)(r4) ld r4, VCPU_GPR(R4)(r4) HRFI_TO_GUEST b . +/* + * The hcall we just completed was from Ultravisor. Use UV_RETURN + * ultra call to return to the Ultravisor. Results from the hcall + * are already in the appropriate registers (r3:12), except for + * R6 which we used as a temporary register above. Restore that, + * and set R0 to the ucall number (UV_RETURN). + */ +ret_to_ultra: + lwz r6, VCPU_CR(r4) + mtcr r6 + LOAD_REG_IMMEDIATE(r0, UV_RETURN) + ld r6, VCPU_GPR(R6)(r4) + ld r4, VCPU_GPR(R4)(r4) + sc 2 /* * Enter the guest on a P9 or later system where we have exactly -- 1.8.3.1