|
[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 |