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: 8b210a880b
("KVM: PPC: Book3S HV Nested: Make nested HFSCR state accessible")
Cc: stable@vger.kernel.org # v5.15+
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220122105530.3477250-1-npiggin@gmail.com
This commit is contained in:
Родитель
fb6433b48a
Коммит
22f7ff0dea
|
@ -39,7 +39,6 @@ struct kvm_nested_guest {
|
||||||
pgd_t *shadow_pgtable; /* our page table for this 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 l1_gr_to_hr; /* L1's addr of part'n-scoped table */
|
||||||
u64 process_table; /* process table entry for this guest */
|
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 */
|
long refcnt; /* number of pointers to this struct */
|
||||||
struct mutex tlb_lock; /* serialize page faults and tlbies */
|
struct mutex tlb_lock; /* serialize page faults and tlbies */
|
||||||
struct kvm_nested_guest *next;
|
struct kvm_nested_guest *next;
|
||||||
|
|
|
@ -818,6 +818,7 @@ struct kvm_vcpu_arch {
|
||||||
|
|
||||||
/* For support of nested guests */
|
/* For support of nested guests */
|
||||||
struct kvm_nested_guest *nested;
|
struct kvm_nested_guest *nested;
|
||||||
|
u64 nested_hfscr; /* HFSCR that the L1 requested for the nested guest */
|
||||||
u32 nested_vcpu_id;
|
u32 nested_vcpu_id;
|
||||||
gpa_t nested_io_gpr;
|
gpa_t nested_io_gpr;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1816,7 +1816,6 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu,
|
||||||
|
|
||||||
static int kvmppc_handle_nested_exit(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 r;
|
||||||
int srcu_idx;
|
int srcu_idx;
|
||||||
|
|
||||||
|
@ -1922,7 +1921,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
|
||||||
* it into a HEAI.
|
* it into a HEAI.
|
||||||
*/
|
*/
|
||||||
if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) ||
|
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;
|
vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -363,7 +363,7 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
|
||||||
/* set L1 state to L2 state */
|
/* set L1 state to L2 state */
|
||||||
vcpu->arch.nested = l2;
|
vcpu->arch.nested = l2;
|
||||||
vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token;
|
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;
|
vcpu->arch.regs = l2_regs;
|
||||||
|
|
||||||
/* Guest must always run with ME enabled, HV disabled. */
|
/* Guest must always run with ME enabled, HV disabled. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче