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)


Reply via email to