To be used by next patches. Also make install_pte take an argument indicating physical location of pagetable. Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> Index: qemu-kvm/kvm/user/test/x86/vm.c =================================================================== --- qemu-kvm.orig/kvm/user/test/x86/vm.c +++ qemu-kvm/kvm/user/test/x86/vm.c @@ -3,22 +3,9 @@ void print(const char *s); -#define PAGE_SIZE 4096ul -#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) - static void *free = 0; static void *vfree_top = 0; -static unsigned long virt_to_phys(const void *virt) -{ - return (unsigned long)virt; -} - -static void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - void *memset(void *data, int c, unsigned long len) { char *s = data; @@ -61,15 +48,11 @@ void free_page(void *page) extern char edata; static unsigned long end_of_memory; -#define PTE_PRESENT (1ull << 0) -#define PTE_PSE (1ull << 7) -#define PTE_WRITE (1ull << 1) -#define PTE_ADDR (0xffffffffff000ull) - -static void install_pte(unsigned long *cr3, - int pte_level, +void install_pte(unsigned long *cr3, + int pte_level, void *virt, - unsigned long pte) + unsigned long pte, + unsigned long *pt_page) { int level; unsigned long *pt = cr3; @@ -78,7 +61,11 @@ static void install_pte(unsigned long *c for (level = 4; level > pte_level; --level) { offset = ((unsigned long)virt >> ((level-1) * 9 + 12)) & 511; if (!(pt[offset] & PTE_PRESENT)) { - unsigned long *new_pt = alloc_page(); + unsigned long *new_pt = pt_page; + if (!new_pt) + new_pt = alloc_page(); + else + pt_page = 0; memset(new_pt, 0, PAGE_SIZE); pt[offset] = virt_to_phys(new_pt) | PTE_PRESENT | PTE_WRITE; } @@ -108,58 +95,20 @@ static unsigned long get_pte(unsigned lo return pte; } -static void install_large_page(unsigned long *cr3, - unsigned long phys, - void *virt) +void install_large_page(unsigned long *cr3, + unsigned long phys, + void *virt) { - install_pte(cr3, 2, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_PSE); + install_pte(cr3, 2, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_PSE, 0); } -static void install_page(unsigned long *cr3, - unsigned long phys, - void *virt) +void install_page(unsigned long *cr3, + unsigned long phys, + void *virt) { - install_pte(cr3, 1, virt, phys | PTE_PRESENT | PTE_WRITE); -} - -static inline void load_cr3(unsigned long cr3) -{ - asm ( "mov %0, %%cr3" : : "r"(cr3) ); -} - -static inline unsigned long read_cr3() -{ - unsigned long cr3; - - asm volatile ( "mov %%cr3, %0" : "=r"(cr3) ); - return cr3; + install_pte(cr3, 1, virt, phys | PTE_PRESENT | PTE_WRITE, 0); } -static inline void load_cr0(unsigned long cr0) -{ - asm volatile ( "mov %0, %%cr0" : : "r"(cr0) ); -} - -static inline unsigned long read_cr0() -{ - unsigned long cr0; - - asm volatile ( "mov %%cr0, %0" : "=r"(cr0) ); - return cr0; -} - -static inline void load_cr4(unsigned long cr4) -{ - asm volatile ( "mov %0, %%cr4" : : "r"(cr4) ); -} - -static inline unsigned long read_cr4() -{ - unsigned long cr4; - - asm volatile ( "mov %%cr4, %0" : "=r"(cr4) ); - return cr4; -} struct gdt_table_descr { Index: qemu-kvm/kvm/user/test/x86/vm.h =================================================================== --- qemu-kvm.orig/kvm/user/test/x86/vm.h +++ qemu-kvm/kvm/user/test/x86/vm.h @@ -1,10 +1,72 @@ #ifndef VM_H #define VM_H +#define PAGE_SIZE 4096ul +#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) + +#define PTE_PRESENT (1ull << 0) +#define PTE_PSE (1ull << 7) +#define PTE_WRITE (1ull << 1) +#define PTE_ADDR (0xffffffffff000ull) + void setup_vm(); void *vmalloc(unsigned long size); void vfree(void *mem); void *vmap(unsigned long long phys, unsigned long size); +void install_pte(unsigned long *cr3, + int pte_level, + void *virt, + unsigned long pte, + unsigned long *pt_page); + +void *alloc_page(); + +void install_large_page(unsigned long *cr3,unsigned long phys, + void *virt); +void install_page(unsigned long *cr3, unsigned long phys, void *virt); + +static inline unsigned long virt_to_phys(const void *virt) +{ + return (unsigned long)virt; +} + +static inline void *phys_to_virt(unsigned long phys) +{ + return (void *)phys; +} + + +static inline void load_cr3(unsigned long cr3) +{ + asm ( "mov %0, %%cr3" : : "r"(cr3) ); +} + +static inline unsigned long read_cr3() +{ + unsigned long cr3; + + asm volatile ( "mov %%cr3, %0" : "=r"(cr3) ); + return cr3; +} + +static inline void load_cr0(unsigned long cr0) +{ + asm volatile ( "mov %0, %%cr0" : : "r"(cr0) ); +} + +static inline void load_cr4(unsigned long cr4) +{ + asm volatile ( "mov %0, %%cr4" : : "r"(cr4) ); +} + +static inline unsigned long read_cr4() +{ + unsigned long cr4; + + asm volatile ( "mov %%cr4, %0" : "=r"(cr4) ); + return cr4; +} + #endif -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html