[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] x86/cpuid: Alter the policy logic for leaf 0xb to be multi-invocation
The new data lives in the .topo union, rather than being treated as a single leaf in the basic union. Host data is scanned when filling in the raw policy, but Xen still discards any toolstack settings for now. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- tools/libxc/xc_cpuid_x86.c | 11 ++++++++++- xen/arch/x86/cpuid.c | 41 +++++++++++++++++++++++++++++++++++++++-- xen/arch/x86/domctl.c | 8 ++++++++ xen/include/asm-x86/cpuid.h | 18 +++++++++++++++++- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c index 21537f0..96c6c95 100644 --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -764,13 +764,22 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, if ( (regs[0] & 0x1f) != 0 ) continue; } + /* Extended Topology leaves. */ + else if ( input[0] == 0xb ) + { + uint8_t level_type = regs[2] >> 8; + + input[1]++; + if ( level_type >= 1 && level_type <= 2 ) + continue; + } input[0]++; if ( !(input[0] & 0x80000000u) && (input[0] > base_max ) ) input[0] = 0x80000000u; input[1] = XEN_CPUID_INPUT_UNUSED; - if ( (input[0] == 4) || (input[0] == 7) ) + if ( (input[0] == 4) || (input[0] == 7) || (input[0] == 0xb) ) input[1] = 0; else if ( input[0] == 0xd ) input[1] = 1; /* Xen automatically calculates almost everything. */ diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index eca1a9a..a6f7bc6 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -205,7 +205,10 @@ static void recalculate_misc(struct cpuid_policy *p) p->basic.raw[0x6] = EMPTY_LEAF; /* Therm/Power not exposed to guests. */ p->basic.raw[0x8] = EMPTY_LEAF; - p->basic.raw[0xb] = EMPTY_LEAF; /* TODO: Rework topology logic. */ + + /* TODO: Rework topology logic. */ + memset(p->topo.raw, 0, sizeof(p->topo.raw)); + p->basic.raw[0xc] = EMPTY_LEAF; p->extd.e1d &= ~CPUID_COMMON_1D_FEATURES; @@ -273,7 +276,7 @@ static void __init calculate_raw_policy(void) { switch ( i ) { - case 0x4: case 0x7: case 0xd: + case 0x4: case 0x7: case 0xb: case 0xd: /* Multi-invocation leaves. Deferred. */ continue; } @@ -316,6 +319,33 @@ static void __init calculate_raw_policy(void) cpuid_count_leaf(7, i, &p->feat.raw[i]); } + if ( p->basic.max_leaf >= 0xb ) + { + union { + struct cpuid_leaf l; + struct cpuid_topo_leaf t; + } u; + + for ( i = 0; i < ARRAY_SIZE(p->topo.raw); ++i ) + { + cpuid_count_leaf(0xb, i, &u.l); + + if ( u.t.type == 0 ) + break; + + p->topo.subleaf[i] = u.t; + } + + /* + * The choice of CPUID_GUEST_NR_TOPO is per the manual. It may need + * to grow for future harware. + */ + if ( i == ARRAY_SIZE(p->topo.raw) && + (cpuid_count_leaf(0xb, i, &u.l), u.t.type != 0) ) + printk(XENLOG_WARNING + "CPUID: Insufficient Leaf 0xb space for this hardware\n"); + } + if ( p->basic.max_leaf >= XSTATE_CPUID ) { uint64_t xstates; @@ -730,6 +760,13 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, *res = p->feat.raw[subleaf]; break; + case 0xb: + if ( subleaf >= ARRAY_SIZE(p->topo.raw) ) + return; + + *res = p->topo.raw[subleaf]; + break; + case XSTATE_CPUID: if ( !p->basic.xsave || subleaf >= ARRAY_SIZE(p->xstate.raw) ) return; diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 105a576..3e9580b 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -70,6 +70,10 @@ static int update_domain_cpuid_info(struct domain *d, ctl->input[1] >= ARRAY_SIZE(p->feat.raw) ) return 0; + if ( ctl->input[0] == 0xb && + ctl->input[1] >= ARRAY_SIZE(p->topo.raw) ) + return 0; + BUILD_BUG_ON(ARRAY_SIZE(p->xstate.raw) < 2); if ( ctl->input[0] == XSTATE_CPUID && ctl->input[1] != 1 ) /* Everything else automatically calculated. */ @@ -100,6 +104,10 @@ static int update_domain_cpuid_info(struct domain *d, p->feat.raw[ctl->input[1]] = leaf; break; + case 0xb: + p->topo.raw[ctl->input[1]] = leaf; + break; + case XSTATE_CPUID: p->xstate.raw[ctl->input[1]] = leaf; break; diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h index 4cce268..4113a5e 100644 --- a/xen/include/asm-x86/cpuid.h +++ b/xen/include/asm-x86/cpuid.h @@ -61,6 +61,7 @@ extern struct cpuidmasks cpuidmask_defaults; #define CPUID_GUEST_NR_BASIC (0xdu + 1) #define CPUID_GUEST_NR_FEAT (0u + 1) #define CPUID_GUEST_NR_CACHE (5u + 1) +#define CPUID_GUEST_NR_TOPO (1u + 1) #define CPUID_GUEST_NR_XSTATE (62u + 1) #define CPUID_GUEST_NR_EXTD_INTEL (0x8u + 1) #define CPUID_GUEST_NR_EXTD_AMD (0x1cu + 1) @@ -108,7 +109,11 @@ struct cpuid_policy uint64_t :64, :64; /* Leaf 0x9 - DCA */ /* Leaf 0xa - Intel PMU. */ - uint8_t pmu_version; + uint8_t pmu_version, _pmu[15]; + + uint64_t :64, :64; /* Leaf 0xb - Topology. */ + uint64_t :64, :64; /* Leaf 0xc - rsvd */ + uint64_t :64, :64; /* Leaf 0xd - XSTATE. */ }; } basic; @@ -142,6 +147,17 @@ struct cpuid_policy }; } feat; + /* Extended topology enumeration: 0x0000000B[xx] */ + union { + struct cpuid_leaf raw[CPUID_GUEST_NR_TOPO]; + struct cpuid_topo_leaf { + uint32_t id_shift:5, :27; + uint16_t nr_logical, :16; + uint8_t level, type, :8, :8; + uint32_t x2apic_id; + } subleaf[CPUID_GUEST_NR_TOPO]; + } topo; + /* Xstate feature leaf: 0x0000000D[xx] */ union { struct cpuid_leaf raw[CPUID_GUEST_NR_XSTATE]; -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |