Skip to content

Commit 54ef48b

Browse files
authored
Merge pull request #1971 from n0toose/uhyve-skip-apic
perf(x86_64): skip APIC probe on uhyve
2 parents 89a5d77 + 08867bb commit 54ef48b

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed

src/arch/x86_64/kernel/apic.rs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ fn detect_from_mp() -> Result<PhysAddr, ()> {
466466
(virtual_address | (u64::from(mp_float.mp_config) & (BasePageSize::SIZE - 1))) as usize;
467467
let mp_config: &ApicConfigTable = unsafe { &*(ptr::with_exposed_provenance(addr)) };
468468
if mp_config.signature != MP_CONFIG_SIGNATURE {
469-
warn!("Invalid MP config table");
469+
warn!("MP config table invalid!");
470470
let range =
471471
PageRange::from_start_len(virtual_address.as_usize(), BasePageSize::SIZE as usize)
472472
.unwrap();
@@ -477,7 +477,7 @@ fn detect_from_mp() -> Result<PhysAddr, ()> {
477477
}
478478

479479
if mp_config.entry_count == 0 {
480-
warn!("No MP table entries! Guess IO-APIC!");
480+
warn!("No MP table entries, guessing IOAPIC...");
481481
let default_address = PhysAddr::new(0xfec0_0000);
482482

483483
init_ioapic_address(default_address);
@@ -499,7 +499,7 @@ fn detect_from_mp() -> Result<PhysAddr, ()> {
499499
2 => {
500500
let io_entry: &ApicIoEntry = unsafe { &*(ptr::with_exposed_provenance(addr)) };
501501
let ioapic = PhysAddr::new(io_entry.addr.into());
502-
info!("Found IOAPIC at 0x{ioapic:p}");
502+
info!("IOAPIC found at {ioapic:p}");
503503

504504
init_ioapic_address(ioapic);
505505

@@ -516,10 +516,10 @@ fn detect_from_mp() -> Result<PhysAddr, ()> {
516516
}
517517

518518
fn default_apic() -> PhysAddr {
519-
warn!("Try to use default APIC address");
520-
521519
let default_address = PhysAddr::new(0xfee0_0000);
522520

521+
warn!("Using default APIC address: {default_address:p}");
522+
523523
// currently, uhyve doesn't support an IO-APIC
524524
if !env::is_uhyve() {
525525
init_ioapic_address(default_address);
@@ -534,33 +534,36 @@ pub fn eoi() {
534534

535535
pub fn init() {
536536
// Detect CPUs and APICs.
537-
let local_apic_physical_address = detect_from_acpi()
538-
.or_else(|()| detect_from_mp())
539-
.unwrap_or_else(|()| default_apic());
537+
let local_apic_physical_address = if env::is_uhyve() {
538+
default_apic()
539+
} else {
540+
detect_from_acpi()
541+
.or_else(|()| detect_from_mp())
542+
.unwrap_or_else(|()| default_apic())
543+
};
540544

541545
// Initialize x2APIC or xAPIC, depending on what's available.
542-
init_x2apic();
543-
if !processor::supports_x2apic() {
546+
if processor::supports_x2apic() {
547+
init_x2apic();
548+
} else if env::is_uefi() {
549+
// already id mapped in UEFI systems, just use the physical address as virtual one
550+
LOCAL_APIC_ADDRESS
551+
.set(VirtAddr::new(local_apic_physical_address.as_u64()))
552+
.unwrap();
553+
} else {
544554
// We use the traditional xAPIC mode available on all x86-64 CPUs.
545555
// It uses a mapped page for communication.
546-
if env::is_uefi() {
547-
//already id mapped in UEFI systems, just use the physical address as virtual one
548-
LOCAL_APIC_ADDRESS
549-
.set(VirtAddr::new(local_apic_physical_address.as_u64()))
550-
.unwrap();
551-
} else {
552-
let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
553-
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
554-
let local_apic_address = VirtAddr::from(page_range.start());
555-
LOCAL_APIC_ADDRESS.set(local_apic_address).unwrap();
556-
debug!(
557-
"Mapping Local APIC at {local_apic_physical_address:p} to virtual address {local_apic_address:p}"
558-
);
556+
let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
557+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
558+
let local_apic_address = VirtAddr::from(page_range.start());
559+
LOCAL_APIC_ADDRESS.set(local_apic_address).unwrap();
560+
debug!(
561+
"Mapping Local APIC at {local_apic_physical_address:p} to virtual address {local_apic_address:p}"
562+
);
559563

560-
let mut flags = PageTableEntryFlags::empty();
561-
flags.device().writable().execute_disable();
562-
paging::map::<BasePageSize>(local_apic_address, local_apic_physical_address, 1, flags);
563-
}
564+
let mut flags = PageTableEntryFlags::empty();
565+
flags.device().writable().execute_disable();
566+
paging::map::<BasePageSize>(local_apic_address, local_apic_physical_address, 1, flags);
564567
}
565568

566569
// Set gates to ISRs for the APIC interrupts we are going to enable.
@@ -732,16 +735,14 @@ pub fn set_oneshot_timer(wakeup_time: Option<u64>) {
732735
}
733736

734737
pub fn init_x2apic() {
735-
if processor::supports_x2apic() {
736-
debug!("Enable x2APIC support");
737-
// The CPU supports the modern x2APIC mode, which uses MSRs for communication.
738-
// Enable it.
739-
let mut msr = IA32_APIC_BASE;
740-
let mut apic_base = unsafe { msr.read() };
741-
apic_base |= X2APIC_ENABLE;
742-
unsafe {
743-
msr.write(apic_base);
744-
}
738+
debug!("Enable x2APIC support");
739+
// The CPU supports the modern x2APIC mode, which uses MSRs for communication.
740+
// Enable it.
741+
let mut msr = IA32_APIC_BASE;
742+
let mut apic_base = unsafe { msr.read() };
743+
apic_base |= X2APIC_ENABLE;
744+
unsafe {
745+
msr.write(apic_base);
745746
}
746747
}
747748

src/arch/x86_64/kernel/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ pub fn application_processor_init() {
136136
processor::configure();
137137
gdt::add_current_core();
138138
interrupts::load_idt();
139-
apic::init_x2apic();
139+
if processor::supports_x2apic() {
140+
apic::init_x2apic();
141+
}
140142
apic::init_local_apic();
141143
debug!("Cr0 = {:?}", Cr0::read());
142144
debug!("Cr4 = {:?}", Cr4::read());

0 commit comments

Comments
 (0)