Skip to content

Commit

Permalink
arch,pt: add support for global page table entries
Browse files Browse the repository at this point in the history
Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Nov 21, 2023
1 parent 43b2ae9 commit 56b84a1
Show file tree
Hide file tree
Showing 12 changed files with 36 additions and 22 deletions.
2 changes: 1 addition & 1 deletion arch/x86/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void init_apic(unsigned int cpu_id, apic_mode_t mode) {
* X2APIC uses MSRs for accesses, so no mapping needed.
*/
if (apic_mode == APIC_MODE_XAPIC)
vmap_4k(apic_get_base(apic_base), apic_base.base, L1_PROT_NOCACHE);
vmap_4k(apic_get_base(apic_base), apic_base.base, L1_PROT_NOCACHE_GLOB);

spiv.reg = apic_read(APIC_SPIV);
spiv.vector = APIC_SPI_VECTOR;
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ static void map_tmp_mapping_entry(void) {
pte_t *entry = l1_table_entry(mfn_to_virt(l1e->mfn), _tmp_mapping);

/* Map _tmp_mapping_entry PTE of new page tables */
kmap_4k(l1e->mfn, L1_PROT);
kmap_4k(l1e->mfn, L1_PROT_GLOB);

/* Point _tmp_mapping_entry at new page tables location */
_tmp_mapping_entry = paddr_to_virt_kern(_paddr(entry));
Expand Down Expand Up @@ -812,5 +812,6 @@ void init_pagetables(void) {
map_multiboot_areas();
map_tmp_mapping_entry();

setup_tlb_global();
write_cr3(cr3.paddr);
}
3 changes: 3 additions & 0 deletions common/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ bool_cmd("fb_scroll", opt_fb_scroll);
unsigned long opt_reboot_timeout = 0; /* Disabled by default */
ulong_cmd("reboot_timeout", opt_reboot_timeout);

bool opt_tlb_global = true;
bool_cmd("tlb_global", opt_tlb_global);

const char *kernel_cmdline;

void __text_init cmdline_parse(const char *cmdline) {
Expand Down
8 changes: 4 additions & 4 deletions common/usermode.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,17 @@ static void init_sysenter(percpu_t *percpu) {
}

void init_usermode(percpu_t *percpu) {
vmap_user_4k(&cr3, virt_to_mfn(&cr3), L1_PROT);
vmap_user_4k(&cr3, virt_to_mfn(&cr3), L1_PROT_GLOB);
vmap_user_4k(&user_cr3, virt_to_mfn(&user_cr3), L1_PROT);

BUG_ON(end_exception_handlers - exception_handlers > (long) PAGE_SIZE);
vmap_user_4k(exception_handlers, virt_to_mfn(exception_handlers), L1_PROT);
vmap_user_4k(exception_handlers, virt_to_mfn(exception_handlers), L1_PROT_RO_GLOB);

BUG_ON(end_interrupt_handlers - interrupt_handlers > (long) PAGE_SIZE);
vmap_user_4k(interrupt_handlers, virt_to_mfn(interrupt_handlers), L1_PROT);
vmap_user_4k(interrupt_handlers, virt_to_mfn(interrupt_handlers), L1_PROT_RO_GLOB);

BUG_ON(end_usermode_helpers - usermode_helpers > (long) PAGE_SIZE);
vmap_user_4k(usermode_helpers, virt_to_mfn(usermode_helpers), L1_PROT);
vmap_user_4k(usermode_helpers, virt_to_mfn(usermode_helpers), L1_PROT_RO_GLOB);

init_syscall();
init_sysenter(percpu);
Expand Down
4 changes: 2 additions & 2 deletions drivers/fb/fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ static void (*put_pixel)(uint32_t x, uint32_t y, uint32_t color);
static void map_fb_area(paddr_t start, size_t size) {
for (mfn_t video_mfn = paddr_to_mfn(start); video_mfn < paddr_to_mfn(start + size);
video_mfn++) {
vmap_4k(mfn_to_virt(video_mfn), video_mfn, L1_PROT_NOCACHE);
kmap_4k(video_mfn, L1_PROT_NOCACHE);
vmap_4k(mfn_to_virt(video_mfn), video_mfn, L1_PROT_NOCACHE_GLOB);
kmap_4k(video_mfn, L1_PROT_NOCACHE_GLOB);
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool init_hpet(const cpu_t *cpu) {
#endif

hpet_base_mfn = paddr_to_mfn(address);
vmap_4k(_ptr(address), hpet_base_mfn, L1_PROT_NOCACHE);
vmap_4k(_ptr(address), hpet_base_mfn, L1_PROT_NOCACHE_GLOB);
config = (acpi_hpet_timer_t *) (address + HPET_OFFSET_TIMER_0_CONFIG_CAP_REG);
general = (acpi_hpet_general_t *) (address + HPET_OFFSET_GENERAL_CAP_REG);
main_counter = (uint64_t *) (address + HPET_OFFSET_GENERAL_MAIN_COUNTER_REG);
Expand Down
4 changes: 2 additions & 2 deletions drivers/vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void vga_write(void *vga_memory, const char *buf, size_t len, vga_color_t color)
void map_vga_area(void) {
for (mfn_t vga_mfn = paddr_to_mfn(VGA_START_ADDR);
vga_mfn < paddr_to_mfn(VGA_END_ADDR); vga_mfn++) {
vmap_4k(mfn_to_virt(vga_mfn), vga_mfn, L1_PROT_NOCACHE);
kmap_4k(vga_mfn, L1_PROT_NOCACHE);
vmap_4k(mfn_to_virt(vga_mfn), vga_mfn, L1_PROT_NOCACHE_GLOB);
kmap_4k(vga_mfn, L1_PROT_NOCACHE_GLOB);
}
}
13 changes: 8 additions & 5 deletions include/arch/x86/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,14 @@

#define PT_NO_FLAGS 0

#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
#define L1_PROT_RO (_PAGE_PRESENT | _PAGE_ACCESSED)
#define L1_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
#define L1_PROT_USER (L1_PROT | _PAGE_USER)
#define L1_PROT_USER_RO (L1_PROT_RO | _PAGE_USER)
#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
#define L1_PROT_GLOB (L1_PROT | _PAGE_GLOBAL)
#define L1_PROT_RO (_PAGE_PRESENT | _PAGE_ACCESSED)
#define L1_PROT_RO_GLOB (L1_PROT_RO | _PAGE_GLOBAL)
#define L1_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
#define L1_PROT_NOCACHE_GLOB (L1_PROT_NOCACHE | _PAGE_GLOBAL)
#define L1_PROT_USER (L1_PROT | _PAGE_USER)
#define L1_PROT_USER_RO (L1_PROT_RO | _PAGE_USER)

#define L2_PROT (L1_PROT | _PAGE_DIRTY)
#define L2_PROT_RO (L1_PROT_RO | _PAGE_DIRTY)
Expand Down
5 changes: 5 additions & 0 deletions include/arch/x86/pagetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ static inline bool is_pgentry_present(pgentry_t e) {
return !!(e & _PAGE_PRESENT);
}

static inline void setup_tlb_global(void) {
unsigned long cr4 = read_cr4();
write_cr4(opt_tlb_global ? (cr4 | X86_CR4_PGE) : (cr4 & ~X86_CR4_PGE));
}

/* External declarations */

extern pte_t l1_pt_entries1[L1_PT_ENTRIES];
Expand Down
1 change: 1 addition & 0 deletions include/cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ extern bool opt_qemu_console;
extern bool opt_poweroff;
extern bool opt_fb_scroll;
extern unsigned long opt_reboot_timeout;
extern bool opt_tlb_global;

extern const char *kernel_cmdline;

Expand Down
12 changes: 6 additions & 6 deletions mm/regions.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ addr_range_t addr_ranges[] = {
USER_RANGE( ".data.user", L1_PROT_USER, __start_data_user, __end_data_user ),
USER_RANGE( ".bss.user", L1_PROT_USER, __start_bss_user, __end_bss_user ),

KERNEL_RANGE( ".text", L1_PROT_RO, __start_text, __end_text ),
KERNEL_RANGE( ".data", L1_PROT, __start_data, __end_data ),
KERNEL_RANGE( ".extables", L1_PROT_RO, __start_extables, __end_extables ),
KERNEL_RANGE( ".bss", L1_PROT, __start_bss, __end_bss ),
KERNEL_RANGE( ".rodata", L1_PROT_RO, __start_rodata, __end_rodata ),
KERNEL_RANGE( ".symbols", L1_PROT_RO, __start_symbols, __end_symbols ),
KERNEL_RANGE( ".text", L1_PROT_RO_GLOB, __start_text, __end_text ),
KERNEL_RANGE( ".data", L1_PROT_GLOB, __start_data, __end_data ),
KERNEL_RANGE( ".bss", L1_PROT_GLOB, __start_bss, __end_bss ),
KERNEL_RANGE( ".rodata", L1_PROT_RO, __start_rodata, __end_rodata ),
KERNEL_RANGE( ".extables", L1_PROT_RO_GLOB, __start_extables, __end_extables ),
KERNEL_RANGE( ".symbols", L1_PROT_RO, __start_symbols, __end_symbols ),
/* clang-format on */

{0x0} /* NULL array terminator */
Expand Down
1 change: 1 addition & 0 deletions smp/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ cr3_t __data_init ap_cr3;

void __noreturn ap_startup(void) {
WRITE_SP(ap_new_sp);
setup_tlb_global();

cpu_t *cpu = get_cpu(ap_cpuid);

Expand Down

0 comments on commit 56b84a1

Please sign in to comment.