Commit 22f7ff0d authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

KVM: PPC: Book3S HV Nested: Fix nested HFSCR being clobbered with multiple vCPUs



The L0 is storing HFSCR requested by the L1 for the L2 in struct
kvm_nested_guest when the L1 requests a vCPU enter L2. kvm_nested_guest
is not a per-vCPU structure. Hilarity ensues.

Fix it by moving the nested hfscr into the vCPU structure together with
the other per-vCPU nested fields.

Fixes: 8b210a88 ("KVM: PPC: Book3S HV Nested: Make nested HFSCR state accessible")
Cc: stable@vger.kernel.org # v5.15+
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarFabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220122105530.3477250-1-npiggin@gmail.com
parent fb6433b4
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ struct kvm_nested_guest {
	pgd_t *shadow_pgtable;		/* our page table for this guest */
	u64 l1_gr_to_hr;		/* L1's addr of part'n-scoped table */
	u64 process_table;		/* process table entry for this guest */
	u64 hfscr;			/* HFSCR that the L1 requested for this nested guest */
	long refcnt;			/* number of pointers to this struct */
	struct mutex tlb_lock;		/* serialize page faults and tlbies */
	struct kvm_nested_guest *next;
+1 −0
Original line number Diff line number Diff line
@@ -818,6 +818,7 @@ struct kvm_vcpu_arch {

	/* For support of nested guests */
	struct kvm_nested_guest *nested;
	u64 nested_hfscr;	/* HFSCR that the L1 requested for the nested guest */
	u32 nested_vcpu_id;
	gpa_t nested_io_gpr;
#endif
+1 −2
Original line number Diff line number Diff line
@@ -1816,7 +1816,6 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu,

static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
{
	struct kvm_nested_guest *nested = vcpu->arch.nested;
	int r;
	int srcu_idx;

@@ -1922,7 +1921,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
		 * it into a HEAI.
		 */
		if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) ||
					(nested->hfscr & (1UL << cause))) {
				(vcpu->arch.nested_hfscr & (1UL << cause))) {
			vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST;

			/*
+1 −1
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
	/* set L1 state to L2 state */
	vcpu->arch.nested = l2;
	vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token;
	l2->hfscr = l2_hv.hfscr;
	vcpu->arch.nested_hfscr = l2_hv.hfscr;
	vcpu->arch.regs = l2_regs;

	/* Guest must always run with ME enabled, HV disabled. */