x86: add support for 64-bit thread ptables
Slightly different layout since the top-lebel PML4 is page-sized and must be page-aligned. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
fc589d7279
commit
7c293831c6
1 changed files with 95 additions and 29 deletions
|
@ -783,6 +783,35 @@ int arch_buffer_validate(void *addr, size_t size, int write)
|
|||
size, write != 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static uintptr_t thread_pdpt_create(uintptr_t pages,
|
||||
struct x86_page_tables *thread_ptables,
|
||||
struct x86_page_tables *master_ptables)
|
||||
{
|
||||
uintptr_t pos = pages, phys_addr = Z_X86_PDPT_START;
|
||||
|
||||
for (int i = 0; i < Z_X86_NUM_PDPT; i++, phys_addr += Z_X86_PDPT_AREA) {
|
||||
u64_t *pml4e;
|
||||
struct x86_mmu_pdpt *master_pdpt, *dest_pdpt;
|
||||
|
||||
/* obtain master PDPT tables for the address range and copy
|
||||
* into per-thread PDPT for this range
|
||||
*/
|
||||
master_pdpt = z_x86_get_pdpt(master_ptables, phys_addr);
|
||||
dest_pdpt = (struct x86_mmu_pdpt *)pos;
|
||||
(void)memcpy(dest_pdpt, master_pdpt,
|
||||
sizeof(struct x86_mmu_pdpt));
|
||||
|
||||
/* And then wire this up to the relevant per-thread PML4E */
|
||||
pml4e = z_x86_get_pml4e(thread_ptables, phys_addr);
|
||||
pml4e_update_pdpt(pml4e, dest_pdpt);
|
||||
pos += MMU_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
static uintptr_t thread_pd_create(uintptr_t pages,
|
||||
struct x86_page_tables *thread_ptables,
|
||||
struct x86_page_tables *master_ptables)
|
||||
|
@ -845,6 +874,65 @@ static uintptr_t thread_pt_create(uintptr_t pages,
|
|||
/* Initialize the page tables for a thread. This will contain, once done,
|
||||
* the boot-time configuration for a user thread page tables. There are
|
||||
* no pre-conditions on the existing state of the per-thread tables.
|
||||
*
|
||||
* pos represents the page we are working with in the reserved area
|
||||
* in the stack buffer for per-thread tables. As we create tables in
|
||||
* this area, pos is incremented to the next free page.
|
||||
*
|
||||
* The layout of the stack object, when this is done:
|
||||
*
|
||||
* For 32-bit:
|
||||
*
|
||||
* +---------------------------+ <- thread->stack_obj
|
||||
* | PDE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PDE(Z_X86_NUM_PD - 1) |
|
||||
* +---------------------------+
|
||||
* | PTE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PTE(Z_X86_NUM_PT - 1) |
|
||||
* +---------------------------+ <- pos once this logic completes
|
||||
* | Stack guard |
|
||||
* +---------------------------+
|
||||
* | Privilege elevation stack |
|
||||
* | PDPT |
|
||||
* +---------------------------+ <- thread->stack_info.start
|
||||
* | Thread stack |
|
||||
* | ... |
|
||||
*
|
||||
* For 64-bit:
|
||||
*
|
||||
* +---------------------------+ <- thread->stack_obj
|
||||
* | PML4 |
|
||||
* +---------------------------|
|
||||
* | PDPT(0) |
|
||||
* +---------------------------|
|
||||
* | ... |
|
||||
* +---------------------------|
|
||||
* | PDPT(Z_X86_NUM_PDPT - 1) |
|
||||
* +---------------------------+
|
||||
* | PDE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PDE(Z_X86_NUM_PD - 1) |
|
||||
* +---------------------------+
|
||||
* | PTE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PTE(Z_X86_NUM_PT - 1) |
|
||||
* +---------------------------+ <- pos once this logic completes
|
||||
* | Stack guard |
|
||||
* +---------------------------+
|
||||
* | Privilege elevation stack |
|
||||
* +---------------------------+ <- thread->stack_info.start
|
||||
* | Thread stack |
|
||||
* | ... |
|
||||
*/
|
||||
static void copy_page_tables(struct k_thread *thread,
|
||||
struct x86_page_tables *master_ptables)
|
||||
|
@ -864,36 +952,14 @@ static void copy_page_tables(struct k_thread *thread,
|
|||
(void)memcpy(thread_ptables, master_ptables,
|
||||
sizeof(struct x86_page_tables));
|
||||
|
||||
/* pos represents the page we are working with in the reserved area
|
||||
* in the stack buffer for per-thread tables. As we create tables in
|
||||
* this area, pos is incremented to the next free page.
|
||||
*
|
||||
* The layout of the stack object, when this is done:
|
||||
*
|
||||
* +---------------------------+ <- thread->stack_obj
|
||||
* | PDE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PDE(Z_X86_NUM_PD - 1) |
|
||||
* +---------------------------+
|
||||
* | PTE(0) |
|
||||
* +---------------------------+
|
||||
* | ... |
|
||||
* +---------------------------+
|
||||
* | PTE(Z_X86_NUM_PT - 1) |
|
||||
* +---------------------------+ <- pos once this logic completes
|
||||
* | Stack guard |
|
||||
* +---------------------------+
|
||||
* | Privilege elevation stack |
|
||||
* | PDPT |
|
||||
* +---------------------------+ <- thread->stack_info.start
|
||||
* | Thread stack |
|
||||
* | ... |
|
||||
*
|
||||
*/
|
||||
start = (uintptr_t)(&header->page_tables);
|
||||
pos = thread_pd_create(start, thread_ptables, master_ptables);
|
||||
#ifdef CONFIG_X86_64
|
||||
pos = start + sizeof(struct x86_mmu_pml4);
|
||||
pos = thread_pdpt_create(pos, thread_ptables, master_ptables);
|
||||
#else
|
||||
pos = start;
|
||||
#endif
|
||||
pos = thread_pd_create(pos, thread_ptables, master_ptables);
|
||||
pos = thread_pt_create(pos, thread_ptables, master_ptables);
|
||||
|
||||
__ASSERT(pos == (start + Z_X86_THREAD_PT_AREA),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue