2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2014
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
15 #define PG_PRESENT 0x01
20 static unsigned long heap_pos = HEAP_BASE;
22 void *alloc(unsigned long size, unsigned long align)
24 unsigned long base = (heap_pos + align - 1) & ~(align - 1);
26 heap_pos = base + size;
30 void map_range(void *start, unsigned long size, enum map_type map_type)
32 unsigned long pt_addr, *pt_entry, *pt;
33 unsigned long vaddr = (unsigned long)start;
35 asm volatile("mov %%cr3,%0" : "=r" (pt_addr));
37 size += HUGE_PAGE_SIZE - 1;
38 size &= HUGE_PAGE_MASK;
42 pt = (unsigned long *)pt_addr;
44 pt_entry = &pt[(vaddr >> 39) & 0x1ff];
45 if (*pt_entry & PG_PRESENT) {
46 pt = (unsigned long *)(*pt_entry & PAGE_MASK);
48 pt = alloc(PAGE_SIZE, PAGE_SIZE);
49 *pt_entry = (unsigned long)pt | PG_RW | PG_PRESENT;
52 pt_entry = &pt[(vaddr >> 30) & 0x1ff];
53 if (*pt_entry & PG_PRESENT) {
54 pt = (unsigned long *)(*pt_entry & PAGE_MASK);
56 pt = alloc(PAGE_SIZE, PAGE_SIZE);
57 *pt_entry = (unsigned long)pt | PG_RW | PG_PRESENT;
60 pt_entry = &pt[(vaddr >> 21) & 0x1ff];
61 *pt_entry = (vaddr & HUGE_PAGE_MASK) |
62 (map_type == MAP_UNCACHED ? PG_PCD : 0) |
63 PG_PS | PG_RW | PG_PRESENT;
65 #error not yet implemented
67 size -= HUGE_PAGE_SIZE;
68 vaddr += HUGE_PAGE_SIZE;