[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-API] [PATCH 1 of 9] XCP.PQ: Add a new hypercall and libxc wrapper to get the CPUID feature leaves
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1294742831 0 # Node ID 1d1ae9c19591075dd50f7fb566247adf7945b3b9 # Parent 9b5d121c8805b40a4338248c346303e1e18d0c4e XCP.PQ: Add a new hypercall and libxc wrapper to get the CPUID feature leaves as they were before and after the FlexMigrate/Extended Migration masks. This is not the ideal way to do it - in particular I think probably platform_ops is the wrong hypercall, and it definitely needs to allocate a better cmd number before going upstream. diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xc_misc.c --- a/tools/libxc/xc_misc.c Mon Jan 10 08:45:19 2011 +0000 +++ b/tools/libxc/xc_misc.c Tue Jan 11 10:47:11 2011 +0000 @@ -323,6 +323,31 @@ int xc_getcpuinfo(xc_interface *xch, int } +int xc_get_boot_cpufeatures(xc_interface *xch, + uint32_t *base_ecx, uint32_t *base_edx, + uint32_t *ext_ecx, uint32_t *ext_edx, + uint32_t *masked_base_ecx, + uint32_t *masked_base_edx, + uint32_t *masked_ext_ecx, + uint32_t *masked_ext_edx) +{ + xen_platform_op_t pm = {0}; + int rc; + + pm.cmd = XENPF_get_cpu_features; + rc = do_platform(xch, &pm); + + *base_ecx = pm.u.cpu_features.base_ecx; + *base_edx = pm.u.cpu_features.base_edx; + *ext_ecx = pm.u.cpu_features.ext_ecx; + *ext_edx = pm.u.cpu_features.ext_edx; + *masked_base_ecx = pm.u.cpu_features.masked_base_ecx; + *masked_base_edx = pm.u.cpu_features.masked_base_edx; + *masked_ext_ecx = pm.u.cpu_features.masked_ext_ecx; + *masked_ext_edx = pm.u.cpu_features.masked_ext_edx; + return rc; +} + int xc_hvm_set_pci_intx_level( xc_interface *xch, domid_t dom, uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx, diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Mon Jan 10 08:45:19 2011 +0000 +++ b/tools/libxc/xc_private.h Tue Jan 11 10:47:11 2011 +0000 @@ -262,6 +262,27 @@ static inline int do_sysctl(xc_interface int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len); +static inline int do_platform(xc_interface *xch, struct xen_platform_op *pm) +{ + int ret = -1; + DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BOUNCE(pm, sizeof(*pm), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); + + pm->interface_version = XENPF_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_platform_op; + hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(pm); + if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 ) + { + if ( errno == EACCES ) + DPRINTF("platform operation failed -- need to" + " rebuild the user-space tool set?\n"); + } + + xc_hypercall_bounce_post(xch, pm); + return ret; +} + void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom, size_t size, int prot, size_t chunksize, privcmd_mmap_entry_t entries[], int nentries); diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Jan 10 08:45:19 2011 +0000 +++ b/tools/libxc/xenctrl.h Tue Jan 11 10:47:11 2011 +0000 @@ -38,6 +38,7 @@ #include <xen/domctl.h> #include <xen/physdev.h> #include <xen/sysctl.h> +#include <xen/platform.h> #include <xen/version.h> #include <xen/event_channel.h> #include <xen/sched.h> @@ -1801,4 +1802,15 @@ void xc_elf_set_logfile(xc_interface *xc int verbose); /* Useful for callers who also use libelf. */ + +/* Get the CPUID feature lists before and after any hardware masks + * were applied. Returns the ANDed aggregate of all online CPUs. */ +int xc_get_boot_cpufeatures(xc_interface *xc_handle, + uint32_t *base_ecx, uint32_t *base_edx, + uint32_t *ext_ecx, uint32_t *ext_edx, + uint32_t *masked_base_ecx, + uint32_t *masked_base_edx, + uint32_t *masked_ext_ecx, + uint32_t *masked_ext_edx); + #endif /* XENCTRL_H */ diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/cpu/amd.c --- a/xen/arch/x86/cpu/amd.c Mon Jan 10 08:45:19 2011 +0000 +++ b/xen/arch/x86/cpu/amd.c Tue Jan 11 10:47:11 2011 +0000 @@ -89,12 +89,16 @@ static inline int wrmsr_amd_safe(unsigne */ static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c) { + unsigned int eax, ebx; static unsigned int feat_ecx, feat_edx; static unsigned int extfeat_ecx, extfeat_edx; static enum { not_parsed, no_mask, set_mask } status; + cpuid(0x1, &eax, &ebx, &c->boot_base_ecx, &c->boot_base_edx); + cpuid(0x80000001, &eax, &ebx, &c->boot_ext_ecx, &c->boot_ext_edx); + if (status == no_mask) - return; + goto out; if (status == set_mask) goto setmask; @@ -109,7 +113,7 @@ static void __devinit set_cpuidmask(cons extfeat_ecx = opt_cpuid_mask_ext_ecx; extfeat_edx = opt_cpuid_mask_ext_edx; } else if (*opt_famrev == '\0') { - return; + goto out; } else if (!strcmp(opt_famrev, "fam_0f_rev_c")) { feat_ecx = AMD_FEATURES_K8_REV_C_ECX; feat_edx = AMD_FEATURES_K8_REV_C_EDX; @@ -153,7 +157,7 @@ static void __devinit set_cpuidmask(cons } else { printk("Invalid processor string: %s\n", opt_famrev); printk("CPUID will not be masked\n"); - return; + goto out; } /* Setting bits in the CPUID mask MSR that are not set in the @@ -170,7 +174,7 @@ static void __devinit set_cpuidmask(cons printk("Writing CPUID extended feature mask ECX:EDX -> %08Xh:%08Xh\n", extfeat_ecx, extfeat_edx); - setmask: +setmask: /* FIXME check if processor supports CPUID masking */ /* AMD processors prior to family 10h required a 32-bit password */ if (c->x86 >= 0x10) { @@ -180,6 +184,10 @@ static void __devinit set_cpuidmask(cons wrmsr_amd(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx); wrmsr_amd(MSR_K8_EXT_FEATURE_MASK, extfeat_edx, extfeat_ecx); } + +out: + cpuid(0x1, &eax, &ebx, &c->masked_base_ecx, &c->masked_base_edx); + cpuid(0x80000001, &eax, &ebx, &c->masked_ext_ecx, &c->masked_ext_edx); } /* diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/cpu/intel.c --- a/xen/arch/x86/cpu/intel.c Mon Jan 10 08:45:19 2011 +0000 +++ b/xen/arch/x86/cpu/intel.c Tue Jan 11 10:47:11 2011 +0000 @@ -35,11 +35,15 @@ struct movsl_mask movsl_mask __read_most */ static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c) { + unsigned int eax, ebx; const char *extra = ""; + cpuid(0x1, &eax, &ebx, &c->boot_base_ecx, &c->boot_base_edx); + cpuid(0x80000001, &eax, &ebx, &c->boot_ext_ecx, &c->boot_ext_edx); + if (!~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx & opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) - return; + goto out; /* Only family 6 supports this feature */ switch ((c->x86 == 6) * c->x86_model) { @@ -78,6 +82,9 @@ static void __devinit set_cpuidmask(cons printk(XENLOG_ERR "Cannot set CPU feature mask on CPU#%d\n", smp_processor_id()); +out: + cpuid(0x1, &eax, &ebx, &c->masked_base_ecx, &c->masked_base_edx); + cpuid(0x80000001, &eax, &ebx, &c->masked_ext_ecx, &c->masked_ext_edx); } void __devinit early_intel_workaround(struct cpuinfo_x86 *c) diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Mon Jan 10 08:45:19 2011 +0000 +++ b/xen/arch/x86/platform_hypercall.c Tue Jan 11 10:47:11 2011 +0000 @@ -492,6 +492,35 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe op->u.mem_add.epfn, op->u.mem_add.pxm); break; + + case XENPF_get_cpu_features: + { + uint32_t cpu; + + op->u.cpu_features.base_ecx = 0xffffffff; + op->u.cpu_features.base_edx = 0xffffffff; + op->u.cpu_features.ext_ecx = 0xffffffff; + op->u.cpu_features.ext_edx = 0xffffffff; + op->u.cpu_features.masked_base_ecx = 0xffffffff; + op->u.cpu_features.masked_base_edx = 0xffffffff; + op->u.cpu_features.masked_ext_ecx = 0xffffffff; + op->u.cpu_features.masked_ext_edx = 0xffffffff; + for_each_online_cpu( cpu ) + { + op->u.cpu_features.base_ecx &= cpu_data[cpu].boot_base_ecx; + op->u.cpu_features.base_edx &= cpu_data[cpu].boot_base_edx; + op->u.cpu_features.ext_ecx &= cpu_data[cpu].boot_ext_ecx; + op->u.cpu_features.ext_edx &= cpu_data[cpu].boot_ext_edx; + op->u.cpu_features.masked_base_ecx &= cpu_data[cpu].masked_base_ecx; + op->u.cpu_features.masked_base_edx &= cpu_data[cpu].masked_base_edx; + op->u.cpu_features.masked_ext_ecx &= cpu_data[cpu].masked_ext_ecx; + op->u.cpu_features.masked_ext_edx &= cpu_data[cpu].masked_ext_edx; + } + + ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; + } + break; + default: ret = -ENOSYS; break; diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/include/asm-x86/processor.h --- a/xen/include/asm-x86/processor.h Mon Jan 10 08:45:19 2011 +0000 +++ b/xen/include/asm-x86/processor.h Tue Jan 11 10:47:11 2011 +0000 @@ -166,6 +166,10 @@ struct cpuinfo_x86 { __u8 x86_mask; int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ unsigned int x86_capability[NCAPINTS]; + unsigned int boot_base_ecx, boot_base_edx; + unsigned int boot_ext_ecx, boot_ext_edx; + unsigned int masked_base_ecx, masked_base_edx; + unsigned int masked_ext_ecx, masked_ext_edx; char x86_vendor_id[16]; char x86_model_id[64]; int x86_cache_size; /* in KB - valid for CPUS which support this call */ diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/include/public/platform.h --- a/xen/include/public/platform.h Mon Jan 10 08:45:19 2011 +0000 +++ b/xen/include/public/platform.h Tue Jan 11 10:47:11 2011 +0000 @@ -355,6 +355,24 @@ struct xenpf_mem_hotadd uint32_t flags; }; + +/* Get the CPUID feature lists before and after any hardware masks + * were applied. Returns the ANDed aggregate of all online CPUs. */ +#define XENPF_get_cpu_features 511 +struct xenpf_cpu_features { + uint32_t base_ecx; /* CPUID leaf 0x00000001:ECX */ + uint32_t base_edx; /* CPUID leaf 0x00000001:EDX */ + uint32_t ext_ecx; /* CPUID leaf 0x80000001:ECX */ + uint32_t ext_edx; /* CPUID leaf 0x80000001:EDX */ + uint32_t masked_base_ecx; /* CPUID leaf 0x00000001:ECX */ + uint32_t masked_base_edx; /* CPUID leaf 0x00000001:EDX */ + uint32_t masked_ext_ecx; /* CPUID leaf 0x80000001:ECX */ + uint32_t masked_ext_edx; /* CPUID leaf 0x80000001:EDX */ +}; +typedef struct xenpf_cpu_features xenpf_cpu_features_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_cpu_features_t); + + struct xen_platform_op { uint32_t cmd; uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ @@ -374,6 +392,7 @@ struct xen_platform_op { struct xenpf_cpu_ol cpu_ol; struct xenpf_cpu_hotadd cpu_add; struct xenpf_mem_hotadd mem_add; + struct xenpf_cpu_features cpu_features; uint8_t pad[128]; } u; }; _______________________________________________ xen-api mailing list xen-api@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/mailman/listinfo/xen-api
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |