From: Andrew Cooper Date: Wed, 11 Jan 2017 11:59:02 +0000 (+0000) Subject: x86/cpuid: Allocate a CPUID policy for every domain X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~3020 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=9457eaa6f833f9868092ce91f385df51b2c101df;p=xen.git x86/cpuid: Allocate a CPUID policy for every domain Introduce init_domain_cpuid_policy() to allocate an appropriate cpuid policy for the domain (currently the domains maximum applicable policy), and call it during domain construction. init_guest_cpuid() now needs calling before dom0 is constructed. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index fa73fc1377..fcd9acc14d 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -262,6 +262,18 @@ const uint32_t * __init lookup_deep_deps(uint32_t feature) return NULL; } +int init_domain_cpuid_policy(struct domain *d) +{ + d->arch.cpuid = xmalloc(struct cpuid_policy); + + if ( !d->arch.cpuid ) + return -ENOMEM; + + *d->arch.cpuid = is_pv_domain(d) ? pv_max_policy : hvm_max_policy; + + return 0; +} + void guest_cpuid(const struct vcpu *v, uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res) { diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 939318718f..c1f95ccaff 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -532,6 +532,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, if ( is_idle_domain(d) ) { d->arch.emulation_flags = 0; + d->arch.cpuid = ZERO_BLOCK_PTR; /* Catch stray misuses. */ } else { @@ -601,6 +602,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, goto fail; paging_initialised = 1; + if ( (rc = init_domain_cpuid_policy(d)) ) + goto fail; + d->arch.cpuids = xmalloc_array(cpuid_input_t, MAX_CPUID_INPUT); rc = -ENOMEM; if ( d->arch.cpuids == NULL ) @@ -674,6 +678,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, cleanup_domain_irq_mapping(d); free_xenheap_page(d->shared_info); xfree(d->arch.cpuids); + xfree(d->arch.cpuid); if ( paging_initialised ) paging_final_teardown(d); free_perdomain_mappings(d); @@ -692,6 +697,7 @@ void arch_domain_destroy(struct domain *d) xfree(d->arch.e820); xfree(d->arch.cpuids); + xfree(d->arch.cpuid); free_domain_pirqs(d); if ( !is_idle_domain(d) ) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 94db5142ec..0ccef1dcd7 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1540,6 +1540,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) if ( !tboot_protect_mem_regions() ) panic("Could not protect TXT memory regions"); + init_guest_cpuid(); + if ( opt_dom0pvh ) domcr_flags |= DOMCRF_pvh | DOMCRF_hap; @@ -1590,8 +1592,6 @@ void __init noreturn __start_xen(unsigned long mbi_p) "Multiple initrd candidates, picking module #%u\n", initrdidx); - init_guest_cpuid(); - /* * Temporarily clear SMAP in CR4 to allow user-accesses in construct_dom0(). * This saves a large number of corner cases interactions with diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h index 0d0ac5297e..77a467a6e8 100644 --- a/xen/include/asm-x86/cpuid.h +++ b/xen/include/asm-x86/cpuid.h @@ -84,6 +84,16 @@ struct cpuid_policy * - Guest accurate: * - All FEATURESET_* words * + * Per-domain objects: + * + * - Host accurate: + * - max_{,sub}leaf + * - {xcr0,xss}_{high,low} + * - All FEATURESET_* words + * + * - Guest accurate: + * - Nothing + * * Everything else should be considered inaccurate, and not necesserily 0. */ @@ -189,6 +199,9 @@ extern struct cpuid_policy raw_policy, host_policy, pv_max_policy, #define pv_featureset pv_max_policy.fs #define hvm_featureset hvm_max_policy.fs +/* Allocate and initialise a CPUID policy suitable for the domain. */ +int init_domain_cpuid_policy(struct domain *d); + void guest_cpuid(const struct vcpu *v, uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 95762cf6a7..780f31164b 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -362,6 +362,9 @@ struct arch_domain cpuid_input_t *cpuids; + /* CPUID Policy. */ + struct cpuid_policy *cpuid; + struct PITState vpit; /* TSC management (emulation, pv, scaling, stats) */