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 23, 2023
1 parent c20748c commit 1f2950b
Show file tree
Hide file tree
Showing 12 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion arch/x86/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,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_kern_4k(apic_get_base(apic_base), apic_base.base, L1_PROT_NOCACHE);
vmap_kern_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 @@ -430,7 +430,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 */
vmap_kern_4k(mfn_to_virt_kern(l1e->mfn), l1e->mfn, L1_PROT);
vmap_kern_4k(mfn_to_virt_kern(l1e->mfn), 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 @@ -1122,5 +1122,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
2 changes: 1 addition & 1 deletion drivers/fb/fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static uint64_t line_width;
static void (*put_pixel)(uint32_t x, uint32_t y, uint32_t color);

static void map_fb_area(paddr_t start, size_t size) {
vmap_range(start, size, L1_PROT_NOCACHE, VMAP_KERNEL | VMAP_IDENT);
vmap_range(start, size, L1_PROT_NOCACHE_GLOB, VMAP_KERNEL | VMAP_IDENT);
}

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

hpet_base_mfn = paddr_to_mfn(address);
vmap_kern_4k(_ptr(address), hpet_base_mfn, L1_PROT_NOCACHE);
vmap_kern_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
2 changes: 1 addition & 1 deletion drivers/vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ void vga_write(void *vga_memory, const char *buf, size_t len, vga_color_t color)
}

void map_vga_area(void) {
vmap_range(VGA_START_ADDR, VGA_END_ADDR - VGA_START_ADDR, L1_PROT_NOCACHE,
vmap_range(VGA_START_ADDR, VGA_END_ADDR - VGA_START_ADDR, L1_PROT_NOCACHE_GLOB,
VMAP_IDENT | VMAP_KERNEL);
}
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 @@ -381,6 +381,11 @@ static inline void *vmap_user_4k(void *va, mfn_t mfn, unsigned long l1_flags) {
return vmap_4k(&user_cr3, va, mfn, l1_flags, true);
}

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));
}

#endif /* __ASSEMBLY__ */

#endif /* KTF_PAGETABLE_H */
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 1f2950b

Please sign in to comment.