powerpc/kvm: Use UV_RETURN ucall to return to ultravisor
When an SVM makes an hypercall or incurs some other exception, the Ultravisor usually forwards (a.k.a. reflects) the exceptions to the Hypervisor. After processing the exception, Hypervisor uses the UV_RETURN ultracall to return control back to the SVM. The expected register state on entry to this ultracall is: * Non-volatile registers are restored to their original values. * If returning from an hypercall, register R0 contains the return value (unlike other ultracalls) and, registers R4 through R12 contain any output values of the hypercall. * R3 contains the ultracall number, i.e UV_RETURN. * If returning with a synthesized interrupt, R2 contains the synthesized interrupt number. Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson. Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com> Acked-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190822034838.27876-8-cclaudio@linux.ibm.com
This commit is contained in:
parent
512a5a6452
commit
6c85b7bc63
|
@ -283,6 +283,7 @@ struct kvm_arch {
|
|||
cpumask_t cpu_in_guest;
|
||||
u8 radix;
|
||||
u8 fwnmi_enabled;
|
||||
u8 secure_guest;
|
||||
bool threads_indep;
|
||||
bool nested_enable;
|
||||
pgd_t *pgtable;
|
||||
|
|
|
@ -24,5 +24,6 @@
|
|||
|
||||
/* opcodes */
|
||||
#define UV_WRITE_PATE 0xF104
|
||||
#define UV_RETURN 0xF11C
|
||||
|
||||
#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
|
||||
|
|
|
@ -506,6 +506,7 @@ int main(void)
|
|||
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
|
||||
OFFSET(KVM_RADIX, kvm, arch.radix);
|
||||
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
|
||||
OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
|
||||
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
|
||||
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
|
||||
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <asm/asm-compat.h>
|
||||
#include <asm/feature-fixups.h>
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/ultravisor-api.h>
|
||||
|
||||
/* Sign-extend HDEC if not on POWER9 */
|
||||
#define EXTEND_HDEC(reg) \
|
||||
|
@ -1085,16 +1086,10 @@ 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)
|
||||
ld r10, VCPU_GPR(R10)(r4)
|
||||
|
@ -1112,10 +1107,42 @@ BEGIN_FTR_SECTION
|
|||
mtspr SPRN_HDSISR, r0
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
|
||||
|
||||
ld r6, VCPU_KVM(r4)
|
||||
lbz r7, KVM_SECURE_GUEST(r6)
|
||||
cmpdi r7, 0
|
||||
ld r6, VCPU_GPR(R6)(r4)
|
||||
ld r7, VCPU_GPR(R7)(r4)
|
||||
bne ret_to_ultra
|
||||
|
||||
lwz r0, VCPU_CR(r4)
|
||||
mtcr r0
|
||||
|
||||
ld r0, VCPU_GPR(R0)(r4)
|
||||
ld r2, VCPU_GPR(R2)(r4)
|
||||
ld r3, VCPU_GPR(R3)(r4)
|
||||
ld r4, VCPU_GPR(R4)(r4)
|
||||
HRFI_TO_GUEST
|
||||
b .
|
||||
/*
|
||||
* Use UV_RETURN ultracall to return control back to the Ultravisor after
|
||||
* processing an hypercall or interrupt that was forwarded (a.k.a. reflected)
|
||||
* to the Hypervisor.
|
||||
*
|
||||
* All registers have already been loaded, except:
|
||||
* R0 = hcall result
|
||||
* R2 = SRR1, so UV can detect a synthesized interrupt (if any)
|
||||
* R3 = UV_RETURN
|
||||
*/
|
||||
ret_to_ultra:
|
||||
lwz r0, VCPU_CR(r4)
|
||||
mtcr r0
|
||||
|
||||
ld r0, VCPU_GPR(R3)(r4)
|
||||
mfspr r2, SPRN_SRR1
|
||||
li r3, 0
|
||||
ori r3, r3, UV_RETURN
|
||||
ld r4, VCPU_GPR(R4)(r4)
|
||||
sc 2
|
||||
|
||||
/*
|
||||
* Enter the guest on a P9 or later system where we have exactly
|
||||
|
|
Loading…
Reference in New Issue