On Tue Feb 20, 2024 at 6:36 PM AEST, Harsh Prateek Bora wrote: > From: Amit Machhiwal <amach...@linux.vnet.ibm.com> > > In APIv1, KVM L0 sets the PCR, while in the nested papr APIv2, this > doesn't work as the PCR can't be set via the guest state buffer; the > logical PVR is set via the GSB though. > > This change sets the PCR whenever the logical PVR is set via the GSB. > Also, unlike the other registers, the value 1 in a defined bit in the > PCR makes the affected resources unavailable and the value 0 makes > them available. Hence, the PCR is set accordingly.
Should this be squashed in as a fix? Thanks, Nick > > Signed-off-by: Amit Machhiwal <amach...@linux.vnet.ibm.com> > Signed-off-by: Harsh Prateek Bora <hars...@linux.ibm.com> > --- > include/hw/ppc/spapr_nested.h | 9 +++++++++ > hw/ppc/spapr_nested.c | 24 ++++++++++++++++++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h > index da918d2dd0..f67c721f53 100644 > --- a/include/hw/ppc/spapr_nested.h > +++ b/include/hw/ppc/spapr_nested.h > @@ -229,6 +229,15 @@ typedef struct SpaprMachineStateNestedGuest { > #define GUEST_STATE_REQUEST_GUEST_WIDE 0x1 > #define GUEST_STATE_REQUEST_SET 0x2 > > +/* As per ISA v3.1B, following bits are reserved: > + * 0:2 > + * 4:57 (ISA mentions bit 58 as well but it should be used for P10) > + * 61:63 (hence, haven't included PCR bits for v2.06 and v2.05 > + * in LOW BITS) > + */ > +#define PCR_LOW_BITS (PCR_COMPAT_3_10 | PCR_COMPAT_3_00) > +#define HVMASK_PCR ~PCR_LOW_BITS > + > #define GUEST_STATE_ELEMENT(i, sz, s, f, ptr, c) { \ > .id = (i), \ > .size = (sz), \ > diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c > index 6e6a90616e..af8a482337 100644 > --- a/hw/ppc/spapr_nested.c > +++ b/hw/ppc/spapr_nested.c > @@ -740,9 +740,11 @@ static void out_buf_min_size(void *a, void *b, bool set) > > static void copy_logical_pvr(void *a, void *b, bool set) > { > + SpaprMachineStateNestedGuest *guest; > uint32_t *buf; /* 1 word */ > uint32_t *pvr_logical_ptr; > uint32_t pvr_logical; > + target_ulong pcr = 0; > > pvr_logical_ptr = a; > buf = b; > @@ -755,6 +757,28 @@ static void copy_logical_pvr(void *a, void *b, bool set) > pvr_logical = be32_to_cpu(buf[0]); > > *pvr_logical_ptr = pvr_logical; > + > + if (*pvr_logical_ptr) { > + switch (*pvr_logical_ptr) { > + case CPU_POWERPC_LOGICAL_3_10: > + pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00; > + break; > + case CPU_POWERPC_LOGICAL_3_00: > + pcr = PCR_COMPAT_3_00; > + break; > + default: > + qemu_log_mask(LOG_GUEST_ERROR, > + "Could not set PCR for LPVR=0x%08x\n", *pvr_logical_ptr); > + return; > + } > + } > + > + guest = container_of(pvr_logical_ptr, > + struct SpaprMachineStateNestedGuest, > + pvr_logical); > + for (int i = 0; i < guest->vcpus; i++) { > + guest->vcpu[i].state.pcr = ~pcr | HVMASK_PCR; > + } > } > > static void copy_tb_offset(void *a, void *b, bool set)