From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Waldemar Kozaczuk <jwkozac...@gmail.com>
Branch: master

Adjust APIC enabling logic to make it work on HyperKit

In order to enable APIC (Advanced Programmable Interrupt Controller)
OSv has to set 0x800 bit (APIC_BASE_GLOBAL_ENABLE) when executing
wrmsr instruction. Currently the xapic::enable() and x2apic::enable()
methods pass value of (_apic_base | APIC_BASE_GLOBAL_ENABLE) which
gets rejected by HyperKit. This happens because _apic_base (4096-bytes
aligned APIC base address) is NOT what rdmsr(msr::IA32_APIC_BASE)
returns for specific CPU and what HyperKit expects to receive back
in wrmsr() when enabling APIC.

In order to properly enable APIC on HyperKit this patch
changes x*apic::enable() methods to read value of APIC base
address and use it instead of _apic_base as input to wrmsr instruction.

This patch follows suggestions by Nadav Har`El.

Fixes #965.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>

---
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -108,7 +108,7 @@ xapic::xapic()

 void xapic::enable()
 {
-    wrmsr(msr::IA32_APIC_BASE, _apic_base | APIC_BASE_GLOBAL_ENABLE);
+ wrmsr(msr::IA32_APIC_BASE, rdmsr(msr::IA32_APIC_BASE) | APIC_BASE_GLOBAL_ENABLE);
     software_enable();
 }

@@ -169,7 +169,7 @@ u32 x2apic::id()

 void x2apic::enable()
 {
- wrmsr(msr::IA32_APIC_BASE, _apic_base | APIC_BASE_GLOBAL_ENABLE | (1 << 10)); + wrmsr(msr::IA32_APIC_BASE, rdmsr(msr::IA32_APIC_BASE) | APIC_BASE_GLOBAL_ENABLE | (1 << 10));
     software_enable();
 }

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to