Skip to content

Commit 4cca6ea

Browse files
Alok N KatariaIngo Molnar
authored andcommitted
x86/apic: Allow x2apic without IR on VMware platform
This patch updates x2apic initializaition code to allow x2apic on VMware platform even without interrupt remapping support. The hypervisor_x2apic_available hook was added in x2apic initialization code and used by KVM and XEN, before this. I have also cleaned up that code to export this hook through the hypervisor_x86 structure. Compile tested for KVM and XEN configs, this patch doesn't have any functional effect on those two platforms. On VMware platform, verified that x2apic is used in physical mode on products that support this. Signed-off-by: Alok N Kataria <akataria@vmware.com> Reviewed-by: Doug Covelli <dcovelli@vmware.com> Reviewed-by: Dan Hecht <dhecht@vmware.com> Acked-by: H. Peter Anvin <hpa@zytor.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Jeremy Fitzhardinge <jeremy@goop.org> Cc: Avi Kivity <avi@redhat.com> Link: http://lkml.kernel.org/r/1358466282.423.60.camel@akataria-dtop.eng.vmware.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent e3f0f36 commit 4cca6ea

File tree

5 files changed

+26
-9
lines changed

5 files changed

+26
-9
lines changed

arch/x86/include/asm/hypervisor.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
extern void init_hypervisor(struct cpuinfo_x86 *c);
2727
extern void init_hypervisor_platform(void);
28+
extern bool hypervisor_x2apic_available(void);
2829

2930
/*
3031
* x86 hypervisor information
@@ -41,6 +42,9 @@ struct hypervisor_x86 {
4142

4243
/* Platform setup (run once per boot) */
4344
void (*init_platform)(void);
45+
46+
/* X2APIC detection (run once per boot) */
47+
bool (*x2apic_available)(void);
4448
};
4549

4650
extern const struct hypervisor_x86 *x86_hyper;
@@ -51,13 +55,4 @@ extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
5155
extern const struct hypervisor_x86 x86_hyper_xen_hvm;
5256
extern const struct hypervisor_x86 x86_hyper_kvm;
5357

54-
static inline bool hypervisor_x2apic_available(void)
55-
{
56-
if (kvm_para_available())
57-
return true;
58-
if (xen_x2apic_para_available())
59-
return true;
60-
return false;
61-
}
62-
6358
#endif

arch/x86/kernel/cpu/hypervisor.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,10 @@ void __init init_hypervisor_platform(void)
7979
if (x86_hyper->init_platform)
8080
x86_hyper->init_platform();
8181
}
82+
83+
bool __init hypervisor_x2apic_available(void)
84+
{
85+
return x86_hyper &&
86+
x86_hyper->x2apic_available &&
87+
x86_hyper->x2apic_available();
88+
}

arch/x86/kernel/cpu/vmware.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333

3434
#define VMWARE_PORT_CMD_GETVERSION 10
3535
#define VMWARE_PORT_CMD_GETHZ 45
36+
#define VMWARE_PORT_CMD_GETVCPU_INFO 68
37+
#define VMWARE_PORT_CMD_LEGACY_X2APIC 3
38+
#define VMWARE_PORT_CMD_VCPU_RESERVED 31
3639

3740
#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
3841
__asm__("inl (%%dx)" : \
@@ -125,10 +128,20 @@ static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c)
125128
set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
126129
}
127130

131+
/* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */
132+
static bool __init vmware_legacy_x2apic_available(void)
133+
{
134+
uint32_t eax, ebx, ecx, edx;
135+
VMWARE_PORT(GETVCPU_INFO, eax, ebx, ecx, edx);
136+
return (eax & (1 << VMWARE_PORT_CMD_VCPU_RESERVED)) == 0 &&
137+
(eax & (1 << VMWARE_PORT_CMD_LEGACY_X2APIC)) != 0;
138+
}
139+
128140
const __refconst struct hypervisor_x86 x86_hyper_vmware = {
129141
.name = "VMware",
130142
.detect = vmware_platform,
131143
.set_cpu_features = vmware_set_cpu_features,
132144
.init_platform = vmware_platform_setup,
145+
.x2apic_available = vmware_legacy_x2apic_available,
133146
};
134147
EXPORT_SYMBOL(x86_hyper_vmware);

arch/x86/kernel/kvm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ static bool __init kvm_detect(void)
505505
const struct hypervisor_x86 x86_hyper_kvm __refconst = {
506506
.name = "KVM",
507507
.detect = kvm_detect,
508+
.x2apic_available = kvm_para_available,
508509
};
509510
EXPORT_SYMBOL_GPL(x86_hyper_kvm);
510511

arch/x86/xen/enlighten.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,7 @@ const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = {
16681668
.name = "Xen HVM",
16691669
.detect = xen_hvm_platform,
16701670
.init_platform = xen_hvm_guest_init,
1671+
.x2apic_available = xen_x2apic_para_available,
16711672
};
16721673
EXPORT_SYMBOL(x86_hyper_xen_hvm);
16731674
#endif

0 commit comments

Comments
 (0)