aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/lapic.c
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@Intel.com>2013-01-24 21:18:50 -0500
committerGleb Natapov <gleb@redhat.com>2013-01-29 03:48:06 -0500
commit8d14695f9542e9e0195d6e41ddaa52c32322adf5 (patch)
tree30d723f19e2c13881f073280d6a3476549d15f83 /arch/x86/kvm/lapic.c
parent83d4c286931c9d28c5be21bac3c73a2332cab681 (diff)
x86, apicv: add virtual x2apic support
basically to benefit from apicv, we need to enable virtualized x2apic mode. Currently, we only enable it when guest is really using x2apic. Also, clear MSR bitmap for corresponding x2apic MSRs when guest enabled x2apic: 0x800 - 0x8ff: no read intercept for apicv register virtualization, except APIC ID and TMCCT which need software's assistance to get right value. Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r--arch/x86/kvm/lapic.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 0664c138e860..f69fc5077a89 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -140,11 +140,6 @@ static inline int apic_enabled(struct kvm_lapic *apic)
140 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ 140 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
141 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) 141 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
142 142
143static inline int apic_x2apic_mode(struct kvm_lapic *apic)
144{
145 return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
146}
147
148static inline int kvm_apic_id(struct kvm_lapic *apic) 143static inline int kvm_apic_id(struct kvm_lapic *apic)
149{ 144{
150 return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; 145 return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
@@ -1303,6 +1298,7 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
1303 1298
1304void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) 1299void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
1305{ 1300{
1301 u64 old_value = vcpu->arch.apic_base;
1306 struct kvm_lapic *apic = vcpu->arch.apic; 1302 struct kvm_lapic *apic = vcpu->arch.apic;
1307 1303
1308 if (!apic) { 1304 if (!apic) {
@@ -1324,11 +1320,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
1324 value &= ~MSR_IA32_APICBASE_BSP; 1320 value &= ~MSR_IA32_APICBASE_BSP;
1325 1321
1326 vcpu->arch.apic_base = value; 1322 vcpu->arch.apic_base = value;
1327 if (apic_x2apic_mode(apic)) { 1323 if ((old_value ^ value) & X2APIC_ENABLE) {
1328 u32 id = kvm_apic_id(apic); 1324 if (value & X2APIC_ENABLE) {
1329 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); 1325 u32 id = kvm_apic_id(apic);
1330 kvm_apic_set_ldr(apic, ldr); 1326 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
1327 kvm_apic_set_ldr(apic, ldr);
1328 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, true);
1329 } else
1330 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, false);
1331 } 1331 }
1332
1332 apic->base_address = apic->vcpu->arch.apic_base & 1333 apic->base_address = apic->vcpu->arch.apic_base &
1333 MSR_IA32_APICBASE_BASE; 1334 MSR_IA32_APICBASE_BASE;
1334 1335