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

Commit 02143947 authored by Paul Mackerras's avatar Paul Mackerras Committed by Avi Kivity
Browse files

KVM: PPC: book3s_pr: Simplify transitions between virtual and real mode



This simplifies the way that the book3s_pr makes the transition to
real mode when entering the guest.  We now call kvmppc_entry_trampoline
(renamed from kvmppc_rmcall) in the base kernel using a normal function
call instead of doing an indirect call through a pointer in the vcpu.
If kvm is a module, the module loader takes care of generating a
trampoline as it does for other calls to functions outside the module.

kvmppc_entry_trampoline then disables interrupts and jumps to
kvmppc_handler_trampoline_enter in real mode using an rfi[d].
That then uses the link register as the address to return to
(potentially in module space) when the guest exits.

This also simplifies the way that we call the Linux interrupt handler
when we exit the guest due to an external, decrementer or performance
monitor interrupt.  Instead of turning on the MMU, then deciding that
we need to call the Linux handler and turning the MMU back off again,
we now go straight to the handler at the point where we would turn the
MMU on.  The handler will then return to the virtual-mode code
(potentially in the module).

Along the way, this moves the setting and clearing of the HID5 DCBZ32
bit into real-mode interrupts-off code, and also makes sure that
we clear the MSR[RI] bit before loading values into SRR0/1.

The net result is that we no longer need any code addresses to be
stored in vcpu->arch.

Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent 177339d7
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -141,9 +141,7 @@ extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu);
extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn);

extern void kvmppc_handler_lowmem_trampoline(void);
extern void kvmppc_handler_trampoline_enter(void);
extern void kvmppc_rmcall(ulong srr0, ulong srr1);
extern void kvmppc_entry_trampoline(void);
extern void kvmppc_hv_entry_trampoline(void);
extern void kvmppc_load_up_fpu(void);
extern void kvmppc_load_up_altivec(void);
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ struct kvmppc_host_state {
	ulong scratch0;
	ulong scratch1;
	u8 in_guest;
	u8 restore_hid5;

#ifdef CONFIG_KVM_BOOK3S_64_HV
	struct kvm_vcpu *kvm_vcpu;
+0 −8
Original line number Diff line number Diff line
@@ -258,14 +258,6 @@ struct kvm_vcpu_arch {
	ulong host_stack;
	u32 host_pid;
#ifdef CONFIG_PPC_BOOK3S
	ulong host_msr;
	ulong host_r2;
	void *host_retip;
	ulong trampoline_lowmem;
	ulong trampoline_enter;
	ulong highmem_handler;
	ulong rmcall;
	ulong host_paca_phys;
	struct kvmppc_slb slb[64];
	int slb_max;		/* 1 + index of last valid entry in slb[] */
	int slb_nr;		/* total number of entries in SLB */
+1 −6
Original line number Diff line number Diff line
@@ -449,8 +449,6 @@ int main(void)
#ifdef CONFIG_PPC_BOOK3S
	DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
	DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id));
	DEFINE(VCPU_HOST_RETIP, offsetof(struct kvm_vcpu, arch.host_retip));
	DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
	DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr));
	DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr));
	DEFINE(VCPU_DSCR, offsetof(struct kvm_vcpu, arch.dscr));
@@ -458,10 +456,6 @@ int main(void)
	DEFINE(VCPU_UAMOR, offsetof(struct kvm_vcpu, arch.uamor));
	DEFINE(VCPU_CTRL, offsetof(struct kvm_vcpu, arch.ctrl));
	DEFINE(VCPU_DABR, offsetof(struct kvm_vcpu, arch.dabr));
	DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
	DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
	DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
	DEFINE(VCPU_RMCALL, offsetof(struct kvm_vcpu, arch.rmcall));
	DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
	DEFINE(VCPU_DEC, offsetof(struct kvm_vcpu, arch.dec));
	DEFINE(VCPU_DEC_EXPIRES, offsetof(struct kvm_vcpu, arch.dec_expires));
@@ -537,6 +531,7 @@ int main(void)
	HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
	HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
	HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
	HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);

#ifdef CONFIG_KVM_BOOK3S_64_HV
	HSTATE_FIELD(HSTATE_KVM_VCPU, kvm_vcpu);
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
	 * R1 = host R1
	 * R2 = host R2
	 * R3 = shadow vcpu
	 * all other volatile GPRS = free
	 * all other volatile GPRS = free except R4, R6
	 * SVCPU[CR]  = guest CR
	 * SVCPU[XER] = guest XER
	 * SVCPU[CTR] = guest CTR
Loading