Skip to content

Commit 20c8c4d

Browse files
Amit Machhiwalmpe
authored andcommitted
KVM: PPC: Book3S HV: Fix L2 guest reboot failure due to empty 'arch_compat'
Currently, rebooting a pseries nested qemu-kvm guest (L2) results in below error as L1 qemu sends PVR value 'arch_compat' == 0 via ppc_set_compat ioctl. This triggers a condition failure in kvmppc_set_arch_compat() resulting in an EINVAL. qemu-system-ppc64: Unable to set CPU compatibility mode in KVM: Invalid argument Also, a value of 0 for arch_compat generally refers the default compatibility of the host. But, arch_compat, being a Guest Wide Element in nested API v2, cannot be set to 0 in GSB as PowerVM (L0) expects a non-zero value. A value of 0 triggers a kernel trap during a reboot and consequently causes it to fail: [ 22.106360] reboot: Restarting system KVM: unknown exit, hardware reason ffffffffffffffea NIP 0000000000000100 LR 000000000000fe44 CTR 0000000000000000 XER 0000000020040092 CPU#0 MSR 0000000000001000 HID0 0000000000000000 HF 6c000000 iidx 3 didx 3 TB 00000000 00000000 DECR 0 GPR00 0000000000000000 0000000000000000 c000000002a8c300 000000007fe00000 GPR04 0000000000000000 0000000000000000 0000000000001002 8000000002803033 GPR08 000000000a000000 0000000000000000 0000000000000004 000000002fff0000 GPR12 0000000000000000 c000000002e10000 0000000105639200 0000000000000004 GPR16 0000000000000000 000000010563a090 0000000000000000 0000000000000000 GPR20 0000000105639e20 00000001056399c8 00007fffe54abab0 0000000105639288 GPR24 0000000000000000 0000000000000001 0000000000000001 0000000000000000 GPR28 0000000000000000 0000000000000000 c000000002b30840 0000000000000000 CR 00000000 [ - - - - - - - - ] RES 000@ffffffffffffffff SRR0 0000000000000000 SRR1 0000000000000000 PVR 0000000000800200 VRSAVE 0000000000000000 SPRG0 0000000000000000 SPRG1 0000000000000000 SPRG2 0000000000000000 SPRG3 0000000000000000 SPRG4 0000000000000000 SPRG5 0000000000000000 SPRG6 0000000000000000 SPRG7 0000000000000000 HSRR0 0000000000000000 HSRR1 0000000000000000 CFAR 0000000000000000 LPCR 0000000000020400 PTCR 0000000000000000 DAR 0000000000000000 DSISR 0000000000000000 kernel:trap=0xffffffea | pc=0x100 | msr=0x1000 This patch updates kvmppc_set_arch_compat() to use the host PVR value if 'compat_pvr' == 0 indicating that qemu doesn't want to enforce any specific PVR compat mode. The relevant part of the code might need a rework if PowerVM implements a support for `arch_compat == 0` in nestedv2 API. Fixes: 19d31c5 ("KVM: PPC: Add support for nestedv2 guests") Reviewed-by: "Aneesh Kumar K.V (IBM)" <aneesh.kumar@kernel.org> Reviewed-by: Vaibhav Jain <vaibhav@linux.ibm.com> Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20240207054526.3720087-1-amachhiw@linux.ibm.com
1 parent a5c57fd commit 20c8c4d

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

arch/powerpc/kvm/book3s_hv.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,24 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
391391
/* Dummy value used in computing PCR value below */
392392
#define PCR_ARCH_31 (PCR_ARCH_300 << 1)
393393

394+
static inline unsigned long map_pcr_to_cap(unsigned long pcr)
395+
{
396+
unsigned long cap = 0;
397+
398+
switch (pcr) {
399+
case PCR_ARCH_300:
400+
cap = H_GUEST_CAP_POWER9;
401+
break;
402+
case PCR_ARCH_31:
403+
cap = H_GUEST_CAP_POWER10;
404+
break;
405+
default:
406+
break;
407+
}
408+
409+
return cap;
410+
}
411+
394412
static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
395413
{
396414
unsigned long host_pcr_bit = 0, guest_pcr_bit = 0, cap = 0;
@@ -424,11 +442,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
424442
break;
425443
case PVR_ARCH_300:
426444
guest_pcr_bit = PCR_ARCH_300;
427-
cap = H_GUEST_CAP_POWER9;
428445
break;
429446
case PVR_ARCH_31:
430447
guest_pcr_bit = PCR_ARCH_31;
431-
cap = H_GUEST_CAP_POWER10;
432448
break;
433449
default:
434450
return -EINVAL;
@@ -440,6 +456,12 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
440456
return -EINVAL;
441457

442458
if (kvmhv_on_pseries() && kvmhv_is_nestedv2()) {
459+
/*
460+
* 'arch_compat == 0' would mean the guest should default to
461+
* L1's compatibility. In this case, the guest would pick
462+
* host's PCR and evaluate the corresponding capabilities.
463+
*/
464+
cap = map_pcr_to_cap(guest_pcr_bit);
443465
if (!(cap & nested_capabilities))
444466
return -EINVAL;
445467
}

arch/powerpc/kvm/book3s_hv_nestedv2.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
138138
vector128 v;
139139
int rc, i;
140140
u16 iden;
141+
u32 arch_compat = 0;
141142

142143
vcpu = gsm->data;
143144

@@ -347,8 +348,23 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
347348
break;
348349
}
349350
case KVMPPC_GSID_LOGICAL_PVR:
350-
rc = kvmppc_gse_put_u32(gsb, iden,
351-
vcpu->arch.vcore->arch_compat);
351+
/*
352+
* Though 'arch_compat == 0' would mean the default
353+
* compatibility, arch_compat, being a Guest Wide
354+
* Element, cannot be filled with a value of 0 in GSB
355+
* as this would result into a kernel trap.
356+
* Hence, when `arch_compat == 0`, arch_compat should
357+
* default to L1's PVR.
358+
*/
359+
if (!vcpu->arch.vcore->arch_compat) {
360+
if (cpu_has_feature(CPU_FTR_ARCH_31))
361+
arch_compat = PVR_ARCH_31;
362+
else if (cpu_has_feature(CPU_FTR_ARCH_300))
363+
arch_compat = PVR_ARCH_300;
364+
} else {
365+
arch_compat = vcpu->arch.vcore->arch_compat;
366+
}
367+
rc = kvmppc_gse_put_u32(gsb, iden, arch_compat);
352368
break;
353369
}
354370

0 commit comments

Comments
 (0)