Skip to content

Commit

Permalink
Eliminate the separate types for user space and kernel addresses (#116)
Browse files Browse the repository at this point in the history
There are currently two types in the kernel for physical addresses:
* `kern_paddr_t` for addresses to memory used by the kernel.
* `user_paddr_t` for addresses to memory used by the kernel.

The original rationale was that the kernel only uses memory under the
4GB, so `kern_paddr_t` could be 32 bits instead of 64 bits. While this
is true, the kernel might still need to map things above this mark like
ACPI table.

This PR replaces both types with a single `paddr_t` type.
  • Loading branch information
phaubertin authored Jan 26, 2025
1 parent 2f222b1 commit 4b6ea58
Show file tree
Hide file tree
Showing 18 changed files with 48 additions and 66 deletions.
6 changes: 3 additions & 3 deletions include/kernel/domain/alloc/page_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@

#include <kernel/types.h>

#define PFNULL ((kern_paddr_t)-1)
#define PFNULL ((paddr_t)-1)

void *page_alloc(void);

void page_free(void *page);

unsigned int get_page_count(void);

bool add_page_frame(kern_paddr_t paddr);
bool add_page_frame(paddr_t paddr);

kern_paddr_t remove_page_frame(void);
paddr_t remove_page_frame(void);

void clear_page(void *page);

Expand Down
2 changes: 1 addition & 1 deletion include/kernel/domain/services/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include <kernel/machine/types.h>
#include <stddef.h>

void *map_in_kernel(kern_paddr_t paddr, size_t size, int prot);
void *map_in_kernel(paddr_t paddr, size_t size, int prot);

void resize_map_in_kernel(size_t size);

Expand Down
3 changes: 2 additions & 1 deletion include/kernel/infrastructure/acpi/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
#include <kernel/machine/types.h>
#include <kernel/infrastructure/acpi/tables.h>
#include <kernel/infrastructure/acpi/types.h>
#include <kernel/machine/types.h>
#include <stdbool.h>
#include <stddef.h>

bool verify_acpi_checksum(const void *buffer, size_t buflen);

bool validate_acpi_rsdp(const acpi_rsdp_t *rsdp);

void map_acpi_tables(kern_paddr_t rsdp_paddr, const acpi_table_def_t *table_defs);
void map_acpi_tables(paddr_t rsdp_paddr, const acpi_table_def_t *table_defs);

void report_acpi_tables(const acpi_table_def_t *table_defs);

Expand Down
11 changes: 3 additions & 8 deletions include/kernel/infrastructure/i686/exports/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,10 @@
/* This file contains the machine-specific definitions that need to be visible
* outside the machine-specific parts of the code. */

/** Physical memory address for use by the kernel */
typedef uint32_t kern_paddr_t;
/** Physical memory address */
typedef uint64_t paddr_t;

/** Physical memory address for use by user space */
typedef uint64_t user_paddr_t;

#define PRIxKPADDR PRIx32

#define PRIxUPADDR PRIx64
#define PRIxPADDR PRIx64

/** incomplete structure declaration for a page table entry
*
Expand Down
2 changes: 1 addition & 1 deletion include/kernel/infrastructure/i686/firmware/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ void init_acpi(void);

void report_acpi(void);

kern_paddr_t acpi_get_rsdp_paddr(void);
uint32_t acpi_get_rsdp_paddr(void);

#endif
23 changes: 4 additions & 19 deletions include/kernel/infrastructure/i686/pmap/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@
#define VIRT_TO_PHYS_AT_1MB(x) (((uintptr_t)(x)) - BOOT_OFFSET_FROM_1MB)

/** convert pointer to physical address for kernel loaded at 0x100000 (1MB) */
#define PTR_TO_PHYS_ADDR_AT_1MB(x) ((kern_paddr_t)VIRT_TO_PHYS_AT_1MB(x))
#define PTR_TO_PHYS_ADDR_AT_1MB(x) ((paddr_t)VIRT_TO_PHYS_AT_1MB(x))

/** convert physical to virtual address for kernel loaded at 0x1000000 (16MB) */
#define PHYS_TO_VIRT_AT_16MB(x) (((uintptr_t)(x)) + BOOT_OFFSET_FROM_16MB)
#define PHYS_TO_VIRT_AT_16MB(x) (((uintptr_t)(x)) + BOOT_OFFSET_FROM_16MB)

/** convert virtual to physical address for kernel loaded at 0x1000000 (16MB) */
#define VIRT_TO_PHYS_AT_16MB(x) (((uintptr_t)(x)) - BOOT_OFFSET_FROM_16MB)
#define VIRT_TO_PHYS_AT_16MB(x) (((uintptr_t)(x)) - BOOT_OFFSET_FROM_16MB)

/** convert pointer to physical address for kernel loaded at 0x1000000 (16MB) */
#define PTR_TO_PHYS_ADDR_AT_16MB(x) ((kern_paddr_t)VIRT_TO_PHYS_AT_16MB(x))
#define PTR_TO_PHYS_ADDR_AT_16MB(x) ((paddr_t)VIRT_TO_PHYS_AT_16MB(x))

#define ADDR_4GB UINT64_C(0x100000000)

Expand All @@ -77,19 +77,4 @@ void pmap_destroy_addr_space(addr_space_t *addr_space);

void pmap_switch_addr_space(addr_space_t *addr_space);

void pmap_map_kernel_page(void *vaddr, kern_paddr_t paddr, int flags);

void pmap_unmap_kernel_page(void *addr);

void pmap_unmap_userspace(addr_space_t *addr_space, void *addr);

bool pmap_clone_range(
addr_space_t *dest_addr_space,
addr_space_t *src_addr_space,
addr_t dest_addr,
addr_t src_addr,
size_t length,
int prot);

#endif

4 changes: 2 additions & 2 deletions include/kernel/interface/i686/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ typedef struct {
size_t loader_size;
void *image_start;
void *image_top;
kern_paddr_t ramdisk_start;
size_t ramdisk_size;
uint32_t ramdisk_start;
size_t ramdisk_size;
const acpi_addr_range_t *acpi_addr_map;
uint32_t addr_map_entries;
void *cmdline;
Expand Down
6 changes: 3 additions & 3 deletions include/kernel/machine/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@

#include <kernel/types.h>

void machine_map_kernel_page(void *vaddr, kern_paddr_t paddr, int prot);
void machine_map_kernel_page(void *vaddr, paddr_t paddr, int prot);

void machine_unmap_kernel_page(void *addr);

bool machine_map_userspace(
process_t *process,
void *vaddr,
size_t length,
user_paddr_t paddr,
paddr_t paddr,
int prot);

bool machine_clone_userspace_mapping(
Expand All @@ -53,6 +53,6 @@ bool machine_clone_userspace_mapping(
size_t length,
int prot) ;

kern_paddr_t machine_lookup_kernel_paddr(const void *addr);
paddr_t machine_lookup_kernel_paddr(const void *addr);

#endif
4 changes: 2 additions & 2 deletions include/kernel/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ typedef struct {
} exec_file_t;

typedef struct {
kern_paddr_t start;
size_t size;
paddr_t start;
size_t size;
} kern_mem_block_t;

typedef struct {
Expand Down
2 changes: 1 addition & 1 deletion kernel/application/kmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void kmain(const char *cmdline) {
machine_get_ramdisk(&ramdisk);

info(
"Found RAM disk with size %zu bytes at address %#" PRIxKPADDR ".",
"Found RAM disk with size %zu bytes at address %#" PRIxPADDR ".",
ramdisk.size,
ramdisk.start
);
Expand Down
6 changes: 3 additions & 3 deletions kernel/domain/alloc/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ unsigned int get_page_count(void) {
* @return true if the function succeeded
*
* */
bool add_page_frame(kern_paddr_t paddr) {
bool add_page_frame(paddr_t paddr) {
void *page = vmalloc();

if(page == NULL) {
Expand Down Expand Up @@ -149,7 +149,7 @@ bool add_page_frame(kern_paddr_t paddr) {
* @return physical address of the freed page frame, or PFNULL if none is available
*
* */
kern_paddr_t remove_page_frame(void) {
paddr_t remove_page_frame(void) {
void *page = page_alloc();

if(page == NULL) {
Expand All @@ -161,7 +161,7 @@ kern_paddr_t remove_page_frame(void) {
* for exploiting vulnerabilities. */
clear_page(page);

kern_paddr_t paddr = machine_lookup_kernel_paddr(page);
paddr_t paddr = machine_lookup_kernel_paddr(page);

machine_unmap_kernel_page(page);

Expand Down
7 changes: 4 additions & 3 deletions kernel/domain/services/mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static struct {
* @param size size of memory to map
* @param prot mapping protection flags
*/
void *map_in_kernel(kern_paddr_t paddr, size_t size, int prot) {
void *map_in_kernel(paddr_t paddr, size_t size, int prot) {
size_t offset = paddr % PAGE_SIZE;

size += offset;
Expand All @@ -76,7 +76,7 @@ void *map_in_kernel(kern_paddr_t paddr, size_t size, int prot) {
alloc_state.latest_prot = prot;

addr_t map_addr = start;
kern_paddr_t map_paddr = paddr - offset;
paddr_t map_paddr = paddr - offset;

while(true) {
machine_map_kernel_page(map_addr, map_paddr, prot);
Expand Down Expand Up @@ -114,10 +114,11 @@ void resize_map_in_kernel(size_t size) {

/* Map additional pages if the mapping is grown. */

kern_paddr_t paddr = machine_lookup_kernel_paddr(start) + (new_end - old_end);
paddr_t paddr = machine_lookup_kernel_paddr(start) + (new_end - old_end);

for(addr_t page_addr = old_end; page_addr < (addr_t)new_end; page_addr += PAGE_SIZE) {
machine_map_kernel_page(page_addr, paddr, prot);
/* TODO recheck this */
++paddr;
}

Expand Down
7 changes: 4 additions & 3 deletions kernel/infrastructure/acpi/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static bool verify_table_signature(const acpi_table_header_t *header, const char
* @return pointer to mapped RSDP on success, NULL on error
*
* */
static const acpi_rsdp_t *map_rsdp(uint64_t paddr) {
static const acpi_rsdp_t *map_rsdp(paddr_t paddr) {
return map_in_kernel(paddr, sizeof(acpi_rsdp_t), JINUE_PROT_READ);
}

Expand Down Expand Up @@ -142,7 +142,7 @@ static const void *map_table(const acpi_table_header_t *header) {
* @return pointer to mapped header on success, NULL on error
*
* */
static const acpi_table_header_t *map_header(kern_paddr_t paddr) {
static const acpi_table_header_t *map_header(paddr_t paddr) {
return map_in_kernel(paddr, sizeof(acpi_table_header_t), JINUE_PROT_READ);
}

Expand Down Expand Up @@ -225,6 +225,7 @@ static void process_rsdt(const acpi_rsdt_t *rsdt, bool is_xsdt, const acpi_table

for(int idx = 0; idx < entries; ++idx) {
/* x86 is little endian */
/* TODO this part is not portable across architectures */
uint64_t paddr = rsdt->entries[idx];

if(is_xsdt) {
Expand All @@ -247,7 +248,7 @@ static void process_rsdt(const acpi_rsdt_t *rsdt, bool is_xsdt, const acpi_table
* @param rsdp_paddr physical memory address of the RSDP
* @param table_defs table definitions array terminated by a NULL signature
*/
void map_acpi_tables(kern_paddr_t rsdp_paddr, const acpi_table_def_t *table_defs) {
void map_acpi_tables(paddr_t rsdp_paddr, const acpi_table_def_t *table_defs) {
const acpi_rsdp_t *rsdp = map_rsdp(rsdp_paddr);

uint64_t rsdt_paddr;
Expand Down
2 changes: 1 addition & 1 deletion kernel/infrastructure/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ bool elf_check(Elf32_Ehdr *ehdr) {
static void checked_map_userspace_page(
process_t *process,
void *vaddr,
user_paddr_t paddr,
paddr_t paddr,
int flags) {

/* TODO check user space pointers
Expand Down
4 changes: 2 additions & 2 deletions kernel/infrastructure/i686/boot_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* This function sets up the allocator to allocate pages after the kernel loaded
* at 0x100000 (1MB). Once the kernel has been moved to 0x1000000 (16MB), the
* boot_alloc_reinit_at_16mb() function has to be called to start allocating pages
* there.
* there instead.
*
* @param boot_alloc the allocator state initialized by this function
* @param bootinfo boot information structure
Expand All @@ -58,7 +58,7 @@ void boot_alloc_init(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) {
boot_alloc->heap_ptr = bootinfo->boot_heap;
/* TODO handle heap limit. */

boot_alloc->current_page = (void *)PTR_TO_PHYS_ADDR_AT_1MB(bootinfo->boot_end);
boot_alloc->current_page = (void *)VIRT_TO_PHYS_AT_1MB(bootinfo->boot_end);
boot_alloc->page_limit = (char *)MEMORY_ADDR_1MB + BOOT_SIZE_AT_1MB;
boot_alloc->first_page_at_16mb = (char *)bootinfo->page_table_1mb + 15 * MB;
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/infrastructure/i686/firmware/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,6 @@ void report_acpi(void) {
*
* @return physical address of RSDP if found, zero otherwise
*/
kern_paddr_t acpi_get_rsdp_paddr(void) {
uint32_t acpi_get_rsdp_paddr(void) {
return rsdp_paddr;
}
4 changes: 2 additions & 2 deletions kernel/infrastructure/i686/pmap/pae.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,10 +375,10 @@ bool pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_directory
}

/* Lookup the physical address of the page where the PDPT resides. */
kern_paddr_t pdpt_page_paddr = machine_lookup_kernel_paddr((addr_t)page_address_of(pdpt));
paddr_t pdpt_page_paddr = machine_lookup_kernel_paddr((addr_t)page_address_of(pdpt));

/* physical address of PDPT */
kern_paddr_t pdpt_paddr = pdpt_page_paddr | page_offset_of(pdpt);
paddr_t pdpt_paddr = pdpt_page_paddr | page_offset_of(pdpt);

addr_space->top_level.pdpt = pdpt;
addr_space->cr3 = pdpt_paddr;
Expand Down
19 changes: 9 additions & 10 deletions kernel/infrastructure/i686/pmap/pmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void copy_ptes(pte_t *dest, const pte_t *src, int n) {
* @param paddr physical address of page frame
* @param flags flags
*/
static void set_pte(pte_t *pte, user_paddr_t paddr, uint64_t flags) {
static void set_pte(pte_t *pte, paddr_t paddr, uint64_t flags) {
if(pgtable_format_pae) {
pae_set_pte(pte, paddr, flags);
}
Expand Down Expand Up @@ -256,7 +256,7 @@ void clear_ptes(pte_t *pte, int n) {
* @param pte page table or page directory entry array
* @return physical address
*/
static user_paddr_t get_pte_paddr(const pte_t *pte) {
static paddr_t get_pte_paddr(const pte_t *pte) {
if(pgtable_format_pae) {
return pae_get_pte_paddr(pte);
}
Expand Down Expand Up @@ -743,7 +743,7 @@ static uint64_t map_page_access_flags(int prot) {
static bool map_page(
addr_space_t *addr_space,
void *vaddr,
user_paddr_t paddr,
paddr_t paddr,
uint64_t flags) {

/** ASSERTION: we assume vaddr is aligned on a page boundary */
Expand Down Expand Up @@ -778,8 +778,7 @@ static bool map_page(
* @param paddr address of page frame
* @param prot protections flags
*/
void machine_map_kernel_page(void *vaddr, kern_paddr_t paddr, int prot) {
/* TODO the kern_paddr_t type prevents this function from supporting addresses above 4GB. */
void machine_map_kernel_page(void *vaddr, paddr_t paddr, int prot) {
assert(is_kernel_pointer(vaddr));
map_page(NULL, vaddr, paddr, map_page_access_flags(prot) | X86_PTE_GLOBAL);
}
Expand All @@ -799,7 +798,7 @@ void machine_map_kernel_page(void *vaddr, kern_paddr_t paddr, int prot) {
static bool map_userspace_page(
addr_space_t *addr_space,
void *vaddr,
user_paddr_t paddr,
paddr_t paddr,
int prot) {

assert(is_userspace_pointer(vaddr));
Expand All @@ -823,7 +822,7 @@ bool machine_map_userspace(
process_t *process,
void *vaddr,
size_t length,
user_paddr_t paddr,
paddr_t paddr,
int prot) {

addr_t addr = vaddr;
Expand Down Expand Up @@ -917,7 +916,7 @@ bool machine_clone_userspace_mapping(
unmap_page(dest_addr_space, dest_addr);
}
else {
user_paddr_t paddr = get_pte_paddr(src_pte);
paddr_t paddr = get_pte_paddr(src_pte);

if(!map_userspace_page(dest_addr_space, dest_addr, paddr, prot)) {
return false;
Expand All @@ -937,12 +936,12 @@ bool machine_clone_userspace_mapping(
* @param addr virtual address of kernel page
* @return physical address of page frame
*/
kern_paddr_t machine_lookup_kernel_paddr(const void *addr) {
paddr_t machine_lookup_kernel_paddr(const void *addr) {
assert( is_kernel_pointer(addr) );

pte_t *pte = lookup_page_table_entry(NULL, addr, false, NULL);

assert(pte != NULL && pte_is_present(pte));

return (kern_paddr_t)get_pte_paddr(pte);
return get_pte_paddr(pte);
}

0 comments on commit 4b6ea58

Please sign in to comment.