rust-osdev / x86_64

Library to program x86_64 hardware.
https://docs.rs/x86_64
Apache License 2.0
797 stars 132 forks source link

OffsetPageTable does not use offset for creating a new mapping #391

Closed 0x6D70 closed 2 years ago

0x6D70 commented 2 years ago

When a OffsetPageTable is created with an offset, the offset is not used for accessing the page table when mapping a page.

Example

For example:

let mut pt = OffsetPageTable::new(page_table, VirtAddr::new(0xffff800000000000));
pt.map_to(...); // here the page tables are accessed without an offset even tough an OffsetPageTable with an offset is used

Problem

As far as I can see the problem occurs in map_to_4kib (Note: the same function for other sizes are also affected) calls self.page_table_walker.create_next_table with the page table entry. The create_next_table function accesses the page for checking if the entry is unused.

The problem is that nowhere the conversion function frame_to_pointer from the PageTableFrameMapping is used.

Freax13 commented 2 years ago

In your example, does page_table point to a page table that has already been offset? create_next_table only prepares the table entry for the next level table, does actual translation happens in next_table_mut: https://github.com/rust-osdev/x86_64/blob/922c5576a2f967de388a933b0644e095cc800ef7/src/structures/paging/mapper/mapped_page_table.rs#L705-L707

0x6D70 commented 2 years ago

No, page_table is the physical address of the level 4 page table

Freax13 commented 2 years ago

Try passing the page table with the offset added. We should mention that in the documentation.

0x6D70 commented 2 years ago

image When adding the offset, the map_to function panics. I don't know if this panic has anything to do with the other problem.

0x6D70 commented 2 years ago

Oh, I forgot to set the Present bit for the mapping. Is there a reason why the present bit is not automatically set?

@Freax13 as you said, the documentation should mention that the offset should be added to the level 4 table

Freax13 commented 2 years ago

Oh, I forgot to set the Present bit for the mapping. Is there a reason why the present bit is not automatically set?

I suppose it's possible to want to map a page without the present bit, but in that case we should still set the present flag on the page tables. This still won't let you access the mapped page, but prevents the crash.

0x6D70 commented 2 years ago

👍 , thanks for your help