On 2026/05/05 03:19 PM, Harsh Prateek Bora wrote:
> 
> 
> On 30/04/26 11:19 am, Amit Machhiwal wrote:
> > Currently, when booting a compatibility-mode KVM guest (L1) on a PowerNV
> > hypervisor (L0), the guest runs with the expected processor
> > compatibility level. However, when booting a nested KVM guest (L2)
> > inside the L1, QEMU derives the CPU model from the raw host PVR and
> > attempts to run the nested guest at that level, instead of honoring the
> > compatibility mode of the L1.
> > 
> > Extend host CPU compatibility capability reporting to support nested
> > virtualization on PowerNV systems (PAPR nested API v1).
> > 
> > For nested API v2 (PowerVM), compatibility capabilities are obtained
> > from the hypervisor via the H_GUEST_GET_CAPABILITIES hcall. This
> > information is not available on PowerNV systems.
> > 
> > For nested API v1, derive the compatibility capabilities from the L1
> > guest by reading the "cpu-version" property from the device tree, which
> > reflects the effective (logical) processor compatibility level. Map this
> > value to the corresponding compatibility capability bitmap.
> > 
> > Introduce a helper to translate CPU version values into compatibility
> > capability bits and integrate it into kvmppc_get_compat_cpu_caps().
> > 
> > This allows userspace to query host CPU compatibility modes on both
> > PowerVM and PowerNV platforms via the KVM_PPC_GET_COMPAT_CAPS ioctl.
> > 
> > Signed-off-by: Amit Machhiwal <[email protected]>
> > ---
> >   arch/powerpc/kvm/book3s_hv.c | 37 +++++++++++++++++++++++++++++++++++-
> >   1 file changed, 36 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> > index d602d90111d1..25d05f1ccb72 100644
> > --- a/arch/powerpc/kvm/book3s_hv.c
> > +++ b/arch/powerpc/kvm/book3s_hv.c
> > @@ -6516,16 +6516,51 @@ static bool kvmppc_hash_v3_possible(void)
> >     return true;
> >   }
> > +static int kvmppc_map_compat_capabilities(const __be32 cpu_version,
> > +                                 unsigned long *capabilities)
> > +{
> > +   switch (cpu_version) {
> > +   case PVR_ARCH_31_P11:
> > +           *capabilities |= H_GUEST_CAP_POWER11;
> 
> Should this be:
> 
> +               *capabilities |= H_GUEST_CAP_POWER11 |
> +                                H_GUEST_CAP_POWER10 |
> +                                H_GUEST_CAP_POWER9;
> 
> Likewise, the remaining as applicable?

Not necessarily. This function will be called only when we are booting a nested
KVM guest (L2) on KVM on PowerNV. So, when the L1 KVM guest is booted in a
compat mode, L2 is supposed to boot with the same PVR version as that of the L1
which is already taken care of with the current changes, unless L2 as well
booted with a max-cpu-compat - which would anyway take a different path for
setting the compat.

> 
> > +           break;
> > +   case PVR_ARCH_31:
> > +           *capabilities |= H_GUEST_CAP_POWER10;
> > +           break;
> > +   case PVR_ARCH_300:
> > +           *capabilities |= H_GUEST_CAP_POWER9;
> > +           break;
> > +   default:
> > +           return -EINVAL;
> > +   }
> > +
> > +   return 0;
> > +}
> >   static int kvmppc_get_compat_cpu_caps(struct kvm_ppc_compat_caps 
> > *host_caps)
> >   {
> > +   struct device_node *np;
> >     unsigned long capabilities = 0;
> > +   const __be32 *prop = NULL;
> >     long rc = -EINVAL;
> > +   u32 cpu_version;
> >     if (kvmhv_on_pseries()) {
> 
> Commit title says PowerNV, but here were are doing only for PowerVM?

Not really. This would take of both the cases. The else part specifically takes
care of the API v1 nested guests on PowerNV platforms.

Thanks,
Amit

> > -           if (kvmhv_is_nestedv2())
> > +           if (kvmhv_is_nestedv2()) {
> >                     rc = plpar_guest_get_capabilities(0, &capabilities);
> > +           } else {
> > +                   for_each_node_by_type(np, "cpu") {
> > +                           prop = of_get_property(np, "cpu-version", NULL);
> > +                           if (prop) {
> > +                                   cpu_version = be32_to_cpup(prop);
> > +                                   break;
> > +                           }
> > +                   }
> > +                   if (!prop)
> > +                           return -EINVAL;
> > +                   rc = kvmppc_map_compat_capabilities(cpu_version,
> > +                                                           &capabilities);
> > +           }
> >             host_caps->compat_capabilities = capabilities;
> >     }
> 

Reply via email to