Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86_64: local APIC page is already mapped by bootloader when running in KVM #506

Open
hawkw opened this issue Jan 5, 2025 · 0 comments
Open
Labels
kind/bug Something isn't working

Comments

@hawkw
Copy link
Owner

hawkw commented Jan 5, 2025

after updating bootloader to v0.11.9 in 7301300, it seems that running the kernel in KVM results in the local APIC page already having been mapped by the bootloader to...some other thing.

running with

$ cargo run-x64 --serial  -- -machine accel=kvm -cpu host,migratable=no,+invtsc

gets a crash like this:

[     ?.??????][?] ├hal_x86_64::interrupt::apic::local: mapping local APIC MMIO page... virt=Page {
                   │     base: VAddr(0xffff8180fee00000),
                   │     size: 4KB,
                   │ },
                   │ phys=Page {
                   │     base: PAddr(0xfee00000),
                   │     size: 4KB,
                   │ }
[     ?.??????][?] │┌map_page: virt=Page { base: VAddr(0xffff8180fee00000), size: 4KB }, phys=Page 
                   ││ { base: PAddr(0xfee00000), size: 4KB }
[     ?.??????][*] │├hal_x86_64::mm: vaddr=VAddr(0xffff8180fee00000)
[     ?.??????][*] ││┌create_next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   │││  self.level=PML4, next.level=PDPT
[     ?.??????][?] │││┌next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB }, 
                   ││││ self.level=PML4, next.level=PDPT, self.addr=0xffff808000014558
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PML4,
                   ││││     addr: PAddr(0x134000),
                   ││││     flags: PRESENT | WRITABLE | ACCESSED,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ fffffffffff03000)
[     ?.??????][*] ││├hal_x86_64::mm: next table already exists
[     ?.??????][?] │││┌next_table_mut: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   ││││  self.level=PML4, next.level=PDPT, self.addr=0xffff8080000142b0
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PML4,
                   ││││     addr: PAddr(0x134000),
                   ││││     flags: PRESENT | WRITABLE | ACCESSED,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ fffffffffff03000)
[     ?.??????][*] ││┌create_next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   │││  self.level=PDPT, next.level=PD
[     ?.??????][?] │││┌next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB }, 
                   ││││ self.level=PDPT, next.level=PD, self.addr=0xffff808000014558
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PDPT,
                   ││││     addr: PAddr(0x138000),
                   ││││     flags: PRESENT | WRITABLE | ACCESSED,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259, 
                   ││││ pdpt_idx=3
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ ffffffffe0603000)
[     ?.??????][*] ││├hal_x86_64::mm: next table already exists
[     ?.??????][?] │││┌next_table_mut: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   ││││  self.level=PDPT, next.level=PD, self.addr=0xffff8080000142b0
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PDPT,
                   ││││     addr: PAddr(0x138000),
                   ││││     flags: PRESENT | WRITABLE | ACCESSED,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259, 
                   ││││ pdpt_idx=3
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ ffffffffe0603000)
[     ?.??????][*] ││┌create_next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   │││  self.level=PD, next.level=PT
[     ?.??????][?] │││┌next_table: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB }, 
                   ││││ self.level=PD, next.level=PT, self.addr=0xffff808000014558
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PD,
                   ││││     addr: PAddr(0xfee00000),
                   ││││     flags: PRESENT | WRITABLE | HUGE,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259, 
                   ││││ pdpt_idx=3, pd_idx=503
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ ffffffc0c07f7000)
[     ?.??????][*] ││├hal_x86_64::mm: next table already exists
[     ?.??????][?] │││┌next_table_mut: idx=Page { base: VAddr(0xffff8180fee00000), size: 4KB },
                   ││││  self.level=PD, next.level=PT, self.addr=0xffff8080000142b0
[     ?.??????][*] │││├hal_x86_64::mm: entry=Entry {
                   ││││     level: PD,
                   ││││     addr: PAddr(0xfee00000),
                   ││││     flags: PRESENT | WRITABLE | HUGE,
                   ││││ }
[     ?.??????][*] │││├hal_x86_64::mm::level: v=VAddr(0xffff8180fee00000), pml4_idx=259, 
                   ││││ pdpt_idx=3, pd_idx=503
[     ?.??????][*] │││├hal_x86_64::mm: found next table virtual address, next.addr=VAddr(0x
                   ││││ ffffffc0c07f7000)
[     ?.??????][?] │├hal_x86_64::mm: page_table=PageTable {
                   ││     level: PT,
                   ││     addr: 0xffffffc0c07f7000,
                   ││ }
[     ?.??????][*] │├hal_x86_64::mm: entry=Entry {
                   ││     level: PT,
                   ││     addr: PAddr(0x170000),
                   ││     flags: PRESENT | CACHE_DISABLE,
                   ││ }
[     ?.??????][?] │├oops: Oops {
                   ││     already_panicked: false,
                   ││     already_faulted: false,
                   ││     alloc: State {
                   ││         allocating: 0,
                   ││         deallocating: 0,
                   ││         heap_size: 100544512,
                   ││         allocated: 137792,
                   ││         min_size: 64,
                   ││         bump_mode: false,
                   ││         bump_allocated: 0,
                   ││         bump_size: 1024,
                   ││     },
                   ││     situation: OopsSituation::Panic(
                   ││         PanicInfo {
                   ││             message: mapped page table entry already in use,
                   ││             location: Location {
                   ││                 file: "/home/eliza/Code/mycelium/hal-x86_64/src/mm.rs",
                   ││                 line: 170,
                   ││                 col: 9,
                   ││             },
                   ││             can_unwind: true,
                   ││             force_no_backtrace: false,
                   ││         },
                   ││     ),
                   ││ }
qemu: terminating on signal 2

(this is the assertion that the PTE found by walking the page table doesn't have the present bit set).

so it seems that somehow PT@0xffffffc0c07f7000[503] is pointed at 0x17000, when we would like to point it at the LAPIC MMIO page at 0xfee00000. We'd really like to identity map that address (vaddr 0xffff8180fee00000), but the bootloader seems to have already mapped the VAddr to...some other thing. which is weird.

@hawkw hawkw added the kind/bug Something isn't working label Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant