[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/cpu: Improvements to get_cpu_vendor()
commit e34bc403c3c7dc0075111fa9cd29e2a385bc66ed Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Fri Dec 16 17:36:22 2016 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Tue Jan 3 13:33:16 2017 +0000 x86/cpu: Improvements to get_cpu_vendor() Comparing 3 integers is more efficient than using strcmp(), and is more useful to the gcv_guest case than having to fabricate a suitable string to pass. The gcv_host cases have both options easily to hand, and experimentally, the resulting code is more efficient. Update the cpu_dev structure to be more efficient. c_vendor[] only needs to be 8 bytes long to cover all the CPU drivers Xen has, which avoids storing an 8-byte pointer to 8 bytes of data. Drop c_ident[1] as we have no CPU drivers with a second ident string, and turn it into an anonymous union to allow access to the integer values directly. This avoids all need for the vendor_id union in update_domain_cpuid_info(). Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/cpu/common.c | 27 +++++++++++++-------------- xen/arch/x86/cpu/cpu.h | 10 +++++++--- xen/arch/x86/domctl.c | 15 ++------------- xen/include/asm-x86/processor.h | 2 +- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 537ad35..d17a2ee 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -156,16 +156,15 @@ void display_cacheinfo(struct cpuinfo_x86 *c) l2size, ecx & 0xFF); } -int get_cpu_vendor(const char v[], enum get_cpu_vendor mode) +int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor mode) { int i; static int printed; for (i = 0; i < X86_VENDOR_NUM; i++) { if (cpu_devs[i]) { - if (!strcmp(v,cpu_devs[i]->c_ident[0]) || - (cpu_devs[i]->c_ident[1] && - !strcmp(v,cpu_devs[i]->c_ident[1]))) { + if (cpu_devs[i]->b == b && cpu_devs[i]->c == c && + cpu_devs[i]->d == d) { if (mode == gcv_host) this_cpu = cpu_devs[i]; return i; @@ -234,12 +233,12 @@ static void __init early_cpu_detect(void) c->x86_cache_alignment = 32; /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, - (int *)&c->x86_vendor_id[0], - (int *)&c->x86_vendor_id[8], - (int *)&c->x86_vendor_id[4]); + cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx); + *(u32 *)&c->x86_vendor_id[0] = ebx; + *(u32 *)&c->x86_vendor_id[8] = ecx; + *(u32 *)&c->x86_vendor_id[4] = edx; - c->x86_vendor = get_cpu_vendor(c->x86_vendor_id, gcv_host); + c->x86_vendor = get_cpu_vendor(ebx, ecx, edx, gcv_host); cpuid(0x00000001, &eax, &ebx, &ecx, &edx); c->x86 = get_cpu_family(eax, &c->x86_model, &c->x86_mask); @@ -277,12 +276,12 @@ static void generic_identify(struct cpuinfo_x86 *c) u32 eax, ebx, ecx, edx, tmp; /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, - (int *)&c->x86_vendor_id[0], - (int *)&c->x86_vendor_id[8], - (int *)&c->x86_vendor_id[4]); + cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx); + *(u32 *)&c->x86_vendor_id[0] = ebx; + *(u32 *)&c->x86_vendor_id[8] = ecx; + *(u32 *)&c->x86_vendor_id[4] = edx; - c->x86_vendor = get_cpu_vendor(c->x86_vendor_id, gcv_host); + c->x86_vendor = get_cpu_vendor(ebx, ecx, edx, gcv_host); /* Initialize the standard set of capabilities */ /* Note that the vendor-specific code below might override */ diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h index 1877e7d..5a7905c 100644 --- a/xen/arch/x86/cpu/cpu.h +++ b/xen/arch/x86/cpu/cpu.h @@ -1,9 +1,13 @@ /* attempt to consolidate cpu attributes */ struct cpu_dev { - char * c_vendor; + char c_vendor[8]; - /* some have two possibilities for cpuid string */ - char * c_ident[2]; + union { + char c_ident[13]; + struct { + uint32_t b, d, c; + }; + }; void (*c_early_init)(struct cpuinfo_x86 *c); void (*c_init)(struct cpuinfo_x86 * c); diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index ab9ad39..eb71c9e 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -54,21 +54,10 @@ static void update_domain_cpuid_info(struct domain *d, switch ( ctl->input[0] ) { case 0: { - union { - typeof(boot_cpu_data.x86_vendor_id) str; - struct { - uint32_t ebx, edx, ecx; - } reg; - } vendor_id = { - .reg = { - .ebx = ctl->ebx, - .edx = ctl->edx, - .ecx = ctl->ecx - } - }; int old_vendor = d->arch.x86_vendor; - d->arch.x86_vendor = get_cpu_vendor(vendor_id.str, gcv_guest); + d->arch.x86_vendor = get_cpu_vendor( + ctl->ebx, ctl->ecx, ctl->edx, gcv_guest); if ( is_hvm_domain(d) && (d->arch.x86_vendor != old_vendor) ) { diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index be31586..aff115b 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -624,7 +624,7 @@ enum get_cpu_vendor { gcv_guest, }; -int get_cpu_vendor(const char vendor_id[], enum get_cpu_vendor); +int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor mode); uint8_t get_cpu_family(uint32_t raw, uint8_t *model, uint8_t *stepping); void pv_cpuid(struct cpu_user_regs *regs); -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |