diff --git a/Cargo.lock b/Cargo.lock index 7098b7c922..9e27adda9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,7 +486,7 @@ dependencies = [ "tock-registers", "x2apic", "x86", - "x86_64 0.15.2", + "x86_64", "x86_rtc", "x86_vcpu", ] @@ -1262,7 +1262,7 @@ dependencies = [ "aarch64-cpu", "bitflags 2.6.0", "memory_addr", - "x86_64 0.15.2", + "x86_64", ] [[package]] @@ -1905,15 +1905,14 @@ dependencies = [ [[package]] name = "x2apic" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcd582541cbb8ef1dfc24a3c849a64ff074b1b512af723ad90056558d424602" +version = "0.5.0" +source = "git+https://github.com/arceos-hypervisor/x2apic-rs.git?branch=manual_apic_mod_selection#8cce5571e60132f51382370851fda0af23fe71fd" dependencies = [ "bit", "bitflags 1.3.2", "paste", "raw-cpuid 10.7.0", - "x86_64 0.14.13", + "x86_64", ] [[package]] @@ -1927,18 +1926,6 @@ dependencies = [ "raw-cpuid 10.7.0", ] -[[package]] -name = "x86_64" -version = "0.14.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c101112411baafbb4bf8d33e4c4a80ab5b02d74d2612331c61e8192fc9710491" -dependencies = [ - "bit_field", - "bitflags 2.6.0", - "rustversion", - "volatile 0.4.6", -] - [[package]] name = "x86_64" version = "0.15.2" @@ -1958,7 +1945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1a42420da20c01d82e5d42231570efa3b9e16a5515eaaf9ee4e964f49cc1313" dependencies = [ "cfg-if", - "x86_64 0.15.2", + "x86_64", ] [[package]] @@ -1979,7 +1966,7 @@ dependencies = [ "page_table_entry", "raw-cpuid 11.1.0", "x86", - "x86_64 0.15.2", + "x86_64", ] [[package]] diff --git a/modules/axhal/Cargo.toml b/modules/axhal/Cargo.toml index 65a4783265..6c55a04e70 100644 --- a/modules/axhal/Cargo.toml +++ b/modules/axhal/Cargo.toml @@ -52,7 +52,7 @@ spin = "0.9" [target.'cfg(target_arch = "x86_64")'.dependencies] x86 = "0.52" x86_64 = "0.15" -x2apic = "0.4" +x2apic = { git = "https://github.com/arceos-hypervisor/x2apic-rs.git", branch = "manual_apic_mod_selection" } raw-cpuid = "11.1" x86_rtc = { version = "0.1", optional = true } x86_vcpu = { git = "https://github.com/arceos-hypervisor/x86_vcpu.git", optional = true } diff --git a/modules/axhal/src/platform/x86_linux/apic.rs b/modules/axhal/src/platform/x86_linux/apic.rs index 1440249b30..385d8161a0 100644 --- a/modules/axhal/src/platform/x86_linux/apic.rs +++ b/modules/axhal/src/platform/x86_linux/apic.rs @@ -6,8 +6,9 @@ use kspin::SpinNoIrq; use lazyinit::LazyInit; use memory_addr::PhysAddr; use x2apic::ioapic::IoApic; -use x2apic::lapic::{LocalApic, LocalApicBuilder, xapic_base}; +use x2apic::lapic::{cpu_has_x2apic, xapic_base, LocalApic, LocalApicBuilder, LocalApicMode}; use x86_64::instructions::port::Port; +use x86_64::registers::model_specific::Msr; use self::vectors::*; use crate::mem::phys_to_virt; @@ -84,11 +85,13 @@ pub(super) fn raw_apic_id(id_u8: u8) -> u32 { } } -fn cpu_has_x2apic() -> bool { - match raw_cpuid::CpuId::new().get_feature_info() { - Some(finfo) => finfo.has_x2apic(), - None => false, - } +fn x2apic_enabled() -> bool { + const XAPIC_ENABLE: u64 = 1 << 11; + const X2APIC_ENABLE: u64 = 1 << 10; + const IA32_APIC_BASE: u32 = 0x1B; + + let ia32_apic_base = unsafe { Msr::new(IA32_APIC_BASE).read() }; + ia32_apic_base & XAPIC_ENABLE != 0 && ia32_apic_base & X2APIC_ENABLE != 0 } pub(super) fn init_primary(enabled: bool, core_id: usize) { @@ -108,13 +111,19 @@ pub(super) fn init_primary(enabled: bool, core_id: usize) { .error_vector(APIC_ERROR_VECTOR as _) .spurious_vector(APIC_SPURIOUS_VECTOR as _); - if cpu_has_x2apic() { + let use_x2apic = if enabled { + cpu_has_x2apic() + } else { + x2apic_enabled() + }; + + if use_x2apic { info!("Using x2APIC."); unsafe { IS_X2APIC = true }; } else { info!("Using xAPIC."); let base_vaddr = phys_to_virt(PhysAddr::from(unsafe { xapic_base() } as usize)); - builder.set_xapic_base(base_vaddr.as_usize() as u64); + builder.apic_mode(LocalApicMode::XApic { xapic_base: base_vaddr.as_usize() as _ }); } let mut lapic = builder.build().unwrap();