[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v1 6/9] Add CPUID enumeration for RDT
From: |
Jonathan Cameron |
Subject: |
Re: [PATCH v1 6/9] Add CPUID enumeration for RDT |
Date: |
Fri, 26 Jul 2024 13:09:19 +0100 |
On Fri, 19 Jul 2024 16:29:26 +0000
Hendrik Wuethrich <whendrik@google.com> wrote:
> From: Hendrik Wüthrich <whendrik@google.com>
>
> Add CPUID enumeration for intel RDT monitoring and allocation, as well
> as the flags used in the enumeration code.
>
> Signed-off-by: Hendrik Wüthrich <whendrik@google.com>
> ---
> hw/i386/rdt.c | 29 ++++++++++++++
> include/hw/i386/rdt.h | 29 ++++++++++++++
> target/i386/cpu.c | 91 +++++++++++++++++++++++++++++++++++++++++++
> target/i386/cpu.h | 5 +++
> 4 files changed, 154 insertions(+)
>
> diff --git a/hw/i386/rdt.c b/hw/i386/rdt.c
> index 0d0e5751fc..5ad05f996a 100644
> --- a/hw/i386/rdt.c
> +++ b/hw/i386/rdt.c
> @@ -17,8 +17,18 @@
> #define MAX_L2_MASK_COUNT 48
> #define MAX_MBA_THRTL_COUNT 31
>
> +/* RDT L3 Allocation features */
> +#define CPUID_10_1_EAX_CBM_LENGTH 0xf
> +#define CPUID_10_1_EBX_CBM 0x0
> +#define CPUID_10_1_ECX_CDP 0x0 // to enable, it would be (1U <<
> 2)
> #define CPUID_10_1_EDX_COS_MAX MAX_L3_MASK_COUNT
> +/* RDT L2 Allocation features*/
> +#define CPUID_10_2_EAX_CBM_LENGTH 0xf
> +#define CPUID_10_2_EBX_CBM 0x0
> #define CPUID_10_2_EDX_COS_MAX MAX_L2_MASK_COUNT
> +/* RDT MBA features */
> +#define CPUID_10_3_EAX_THRTL_MAX 89
> +#define CPUID_10_3_ECX_LINEAR_RESPONSE (1U << 2)
> #define CPUID_10_3_EDX_COS_MAX MAX_MBA_THRTL_COUNT
>
> #define TYPE_RDT "rdt"
> @@ -61,8 +71,27 @@ struct RDTState {
>
> struct RDTStateClass { };
>
> +uint32_t rdt_get_cpuid_15_0_edx_l3(void) { return
> CPUID_15_1_EDX_L3_OCCUPANCY | CPUID_15_1_EDX_L3_TOTAL_BW |
> CPUID_15_1_EDX_L3_LOCAL_BW; }
> +
> +uint32_t rdt_cpuid_15_1_edx_l3_total_bw_enabled(void) { return
> CPUID_15_1_EDX_L3_TOTAL_BW; }
> +uint32_t rdt_cpuid_15_1_edx_l3_local_bw_enabled(void) { return
> CPUID_15_1_EDX_L3_LOCAL_BW; }
> +uint32_t rdt_cpuid_15_1_edx_l3_occupancy_enabled(void) { return
> CPUID_15_1_EDX_L3_OCCUPANCY; }
> +
> +uint32_t rdt_cpuid_10_0_ebx_l3_cat_enabled(void) { return
> CPUID_10_0_EBX_L3_CAT; }
> +uint32_t rdt_cpuid_10_0_ebx_l2_cat_enabled(void) { return
> CPUID_10_0_EBX_L2_CAT; }
> +uint32_t rdt_cpuid_10_0_ebx_l2_mba_enabled(void) { return
> CPUID_10_0_EBX_MBA; }
> +
> +uint32_t rdt_get_cpuid_10_1_eax_cbm_length(void) { return
> CPUID_10_1_EAX_CBM_LENGTH; }
> +uint32_t rdt_cpuid_10_1_ebx_cbm_enabled(void) { return CPUID_10_1_EBX_CBM; }
> +uint32_t rdt_cpuid_10_1_ecx_cdp_enabled(void) { return CPUID_10_1_ECX_CDP; }
> uint32_t rdt_get_cpuid_10_1_edx_cos_max(void) { return
> CPUID_10_1_EDX_COS_MAX; }
> +
> +uint32_t rdt_get_cpuid_10_2_eax_cbm_length(void) { return
> CPUID_10_2_EAX_CBM_LENGTH; }
> +uint32_t rdt_cpuid_10_2_ebx_cbm_enabled(void) { return CPUID_10_2_EBX_CBM; }
> uint32_t rdt_get_cpuid_10_2_edx_cos_max(void) { return
> CPUID_10_2_EDX_COS_MAX; }
> +
> +uint32_t rdt_get_cpuid_10_3_eax_thrtl_max(void) { return
> CPUID_10_3_EAX_THRTL_MAX; }
> +uint32_t rdt_cpuid_10_3_eax_linear_response_enabled(void) { return
> CPUID_10_3_ECX_LINEAR_RESPONSE; }
> uint32_t rdt_get_cpuid_10_3_edx_cos_max(void) { return
> CPUID_10_3_EDX_COS_MAX; }
>
> bool rdt_associate_rmid_cos(uint64_t msr_ia32_pqr_assoc) {
> diff --git a/include/hw/i386/rdt.h b/include/hw/i386/rdt.h
> index 51d36822f0..74aba33995 100644
> --- a/include/hw/i386/rdt.h
> +++ b/include/hw/i386/rdt.h
> @@ -4,15 +4,44 @@
> #include <stdbool.h>
> #include <stdint.h>
>
> +/* RDT L3 Cache Monitoring Technology */
> +#define CPUID_15_0_EDX_L3 (1U << 1)
> +#define CPUID_15_1_EDX_L3_OCCUPANCY (1U << 0)
> +#define CPUID_15_1_EDX_L3_TOTAL_BW (1U << 1)
> +#define CPUID_15_1_EDX_L3_LOCAL_BW (1U << 2)
> +
> +/* RDT Cache Allocation Technology */
> +#define CPUID_10_0_EBX_L3_CAT (1U << 1)
> +#define CPUID_10_0_EBX_L2_CAT (1U << 2)
> +#define CPUID_10_0_EBX_MBA (1U << 3)
> +#define CPUID_10_0_EDX CPUID_10_0_EBX_L3_CAT | CPUID_10_0_EBX_L2_CAT |
> CPUID_10_0_EBX_MBA
> +
> typedef struct RDTState RDTState;
> typedef struct RDTStateInstance RDTStateInstance;
> typedef struct RDTMonitor RDTMonitor;
> typedef struct RDTAllocation RDTAllocation;
>
> +uint32_t rdt_get_cpuid_15_0_edx_l3(void);
> +
> +uint32_t rdt_cpuid_15_1_edx_l3_total_bw_enabled(void);
> +uint32_t rdt_cpuid_15_1_edx_l3_local_bw_enabled(void);
> +uint32_t rdt_cpuid_15_1_edx_l3_occupancy_enabled(void);
> +
> +uint32_t rdt_cpuid_10_0_ebx_l3_cat_enabled(void);
> +uint32_t rdt_cpuid_10_0_ebx_l2_cat_enabled(void);
> +uint32_t rdt_cpuid_10_0_ebx_l2_mba_enabled(void);
> +
> +uint32_t rdt_get_cpuid_10_1_eax_cbm_length(void);
> +uint32_t rdt_cpuid_10_1_ebx_cbm_enabled(void);
> +uint32_t rdt_cpuid_10_1_ecx_cdp_enabled(void);
> uint32_t rdt_get_cpuid_10_1_edx_cos_max(void);
>
> +uint32_t rdt_get_cpuid_10_2_eax_cbm_length(void);
> +uint32_t rdt_cpuid_10_2_ebx_cbm_enabled(void);
> uint32_t rdt_get_cpuid_10_2_edx_cos_max(void);
>
> +uint32_t rdt_get_cpuid_10_3_eax_thrtl_max(void);
> +uint32_t rdt_cpuid_10_3_eax_linear_response_enabled(void);
> uint32_t rdt_get_cpuid_10_3_edx_cos_max(void);
>
> bool rdt_associate_rmid_cos(uint64_t msr_ia32_pqr_assoc);
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 4688d140c2..c61981bf82 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -42,6 +42,7 @@
> #include "hw/boards.h"
> #include "hw/i386/sgx-epc.h"
> #endif
> +#include "hw/i386/rdt.h"
>
> #include "disas/capstone.h"
> #include "cpu-internal.h"
> @@ -6629,6 +6630,96 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
> uint32_t count,
> assert(!(*eax & ~0x1f));
> *ebx &= 0xffff; /* The count doesn't need to be reliable. */
> break;
> +#ifndef CONFIG_USER_ONLY
> + case 0xF:
> + /* Shared Resource Monitoring Enumeration Leaf */
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_PQM))
> + break;
> + assert(cpu->rdt);
> + /* Non-zero count is ResId */
> + switch (count) {
> + /* Monitoring Resource Type Enumeration */
> + case 0:
> + *edx = env->features[FEAT_RDT_15_0_EDX];
> + *ebx = rdt_max_rmid(cpu->rdt);
> + break;
> + /* L3 Cache Monitoring Capability Enumeration Data */
> + case 1:
> + /* Upscaling Factor */
> + *ebx = 1;
> + /* MaxRMID */
> + *ecx = rdt_max_rmid(cpu->rdt);
> + /* Set L3 Total BW */
comments fairly obvious from naming of functions so I'd be tempted
to drop them all and have
*ecx = rdt_max_rmid(cpu->rdt);
*edx = rdt_cpuid_15_1_edx_l3_total_bw_enabled() |
rdt_cpuid_15_1_edx_l3_local_bw_enabled() |
rdt_cpuid_15_1_edx_l3_occupancy_enabled();
Same for the rest of the cases
> + *edx |= rdt_cpuid_15_1_edx_l3_total_bw_enabled();
> + /* Set L3 Local BW */
> + *edx |= rdt_cpuid_15_1_edx_l3_local_bw_enabled();
> + /* Set L3 Occupancy */
> + *edx |= rdt_cpuid_15_1_edx_l3_occupancy_enabled();
> + break;
> + default:
> + break;
> + }
> + break;
> + case 0x10:
> + /* Shared Resource Director Technology Allocation Enumeration Leaf */
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_PQE))
> + break;
> + assert(cpu->rdt);
> + /* Non-zero count is ResId */
> + switch (count) {
> + /* Cache Allocation Technology Available Resource Types */
> + case 0:
> + /* Set L3 CAT */
> + *ebx |= rdt_cpuid_10_0_ebx_l3_cat_enabled();
> + /* Set L2 CAT */
> + *ebx |= rdt_cpuid_10_0_ebx_l2_cat_enabled();
> + /* Set MBA */
> + *ebx |= rdt_cpuid_10_0_ebx_l2_mba_enabled();
> + // *edx = env->features[FEAT_RDT_10_0_EBX];
Make sure to clean up any commented out code for v2.
> + break;
> + case 1:
> + /* Length of capacity bitmask in -1 notation */
> + *eax = rdt_get_cpuid_10_1_eax_cbm_length();
> + /* Capability bit mask */
> + *ebx = rdt_cpuid_10_1_ebx_cbm_enabled();
> + /* Code and Data priotitization */
> + *ecx |= rdt_cpuid_10_1_ecx_cdp_enabled();
> + /* Support for n COS masks (zero-referenced)*/
> + *edx = rdt_get_cpuid_10_1_edx_cos_max();
> + break;
> + case 2:
> + /* Length of capacity bitmask in -1 notation */
> + *eax = rdt_get_cpuid_10_2_eax_cbm_length();
> + /* Capability bit mask */
> + *ebx = rdt_cpuid_10_2_ebx_cbm_enabled();
> + /* Support for n COS masks (zero-referenced)*/
> + *edx = rdt_get_cpuid_10_2_edx_cos_max();
> + break;
> + case 3:
> + /* Max throttling value -1 (89 means 90) */
> + *eax = rdt_get_cpuid_10_3_eax_thrtl_max();
> + /* Linear response of delay values */
> + *ecx = rdt_cpuid_10_3_eax_linear_response_enabled();
> + /* Max number of CLOS -1 (15 means 16) */
> + *edx = rdt_get_cpuid_10_3_edx_cos_max();
> + break;
> + default:
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
already done above.
> + break;
> + }
> + break;
> +#endif
> case 0x1C:
> if (cpu->enable_pmu && (env->features[FEAT_7_0_EDX] &
> CPUID_7_0_EDX_ARCH_LBR)) {
> x86_cpu_get_supported_cpuid(0x1C, 0, eax, ebx, ecx, edx);
- Re: [PATCH v1 5/9] Add RDT device interface through MSRs, (continued)
- [PATCH v1 2/9] Add state for RDT device., Hendrik Wuethrich, 2024/07/19
- [PATCH v1 9/9] Adjust level for RDT on full_cpuid_auto_level, Hendrik Wuethrich, 2024/07/19
- [PATCH v1 4/9] Add RDT functionality, Hendrik Wuethrich, 2024/07/19
- [PATCH v1 8/9] Adjust CPUID level for RDT features, Hendrik Wuethrich, 2024/07/19
- [PATCH v1 1/9] Add Intel RDT device to config., Hendrik Wuethrich, 2024/07/19
- [PATCH v1 6/9] Add CPUID enumeration for RDT, Hendrik Wuethrich, 2024/07/19
- Re: [PATCH v1 6/9] Add CPUID enumeration for RDT,
Jonathan Cameron <=
- [PATCH v1 3/9] Add init and realize funciontality for RDT device., Hendrik Wuethrich, 2024/07/19
- [PATCH v1 7/9] Add RDT feature flags., Hendrik Wuethrich, 2024/07/19