Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * tools/testing/selftests/kvm/lib/x86_64/processor.c
0004  *
0005  * Copyright (C) 2021, Google LLC.
0006  */
0007 
0008 #include "apic.h"
0009 
0010 void apic_disable(void)
0011 {
0012     wrmsr(MSR_IA32_APICBASE,
0013           rdmsr(MSR_IA32_APICBASE) &
0014         ~(MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD));
0015 }
0016 
0017 void xapic_enable(void)
0018 {
0019     uint64_t val = rdmsr(MSR_IA32_APICBASE);
0020 
0021     /* Per SDM: to enable xAPIC when in x2APIC must first disable APIC */
0022     if (val & MSR_IA32_APICBASE_EXTD) {
0023         apic_disable();
0024         wrmsr(MSR_IA32_APICBASE,
0025               rdmsr(MSR_IA32_APICBASE) | MSR_IA32_APICBASE_ENABLE);
0026     } else if (!(val & MSR_IA32_APICBASE_ENABLE)) {
0027         wrmsr(MSR_IA32_APICBASE, val | MSR_IA32_APICBASE_ENABLE);
0028     }
0029 
0030     /*
0031      * Per SDM: reset value of spurious interrupt vector register has the
0032      * APIC software enabled bit=0. It must be enabled in addition to the
0033      * enable bit in the MSR.
0034      */
0035     val = xapic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED;
0036     xapic_write_reg(APIC_SPIV, val);
0037 }
0038 
0039 void x2apic_enable(void)
0040 {
0041     wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) |
0042           MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD);
0043     x2apic_write_reg(APIC_SPIV,
0044              x2apic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED);
0045 }