1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tools/testing/selftests/kvm/lib/x86_64/processor.c 4 * 5 * Copyright (C) 2021, Google LLC. 6 */ 7 8 #include "apic.h" 9 10 void apic_disable(void) 11 { 12 wrmsr(MSR_IA32_APICBASE, 13 rdmsr(MSR_IA32_APICBASE) & 14 ~(MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD)); 15 } 16 17 void xapic_enable(void) 18 { 19 uint64_t val = rdmsr(MSR_IA32_APICBASE); 20 21 /* Per SDM: to enable xAPIC when in x2APIC must first disable APIC */ 22 if (val & MSR_IA32_APICBASE_EXTD) { 23 apic_disable(); 24 wrmsr(MSR_IA32_APICBASE, 25 rdmsr(MSR_IA32_APICBASE) | MSR_IA32_APICBASE_ENABLE); 26 } else if (!(val & MSR_IA32_APICBASE_ENABLE)) { 27 wrmsr(MSR_IA32_APICBASE, val | MSR_IA32_APICBASE_ENABLE); 28 } 29 30 /* 31 * Per SDM: reset value of spurious interrupt vector register has the 32 * APIC software enabled bit=0. It must be enabled in addition to the 33 * enable bit in the MSR. 34 */ 35 val = xapic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED; 36 xapic_write_reg(APIC_SPIV, val); 37 } 38 39 void x2apic_enable(void) 40 { 41 wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) | 42 MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD); 43 x2apic_write_reg(APIC_SPIV, 44 x2apic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED); 45 } 46