mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
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@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
291dcb4dd0
commit
e34bc403c3
4 files changed
+23
-31
No files matched your search
+13
-14
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
+2
-13
@@ -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) )
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||