diff options
| -rw-r--r-- | arch/i386/kernel/paravirt.c | 2 | ||||
| -rw-r--r-- | arch/i386/kernel/vmi.c | 19 | ||||
| -rw-r--r-- | include/asm-i386/paravirt.h | 4 | ||||
| -rw-r--r-- | include/asm-i386/pgtable.h | 23 |
4 files changed, 44 insertions, 4 deletions
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 8352394d5efb..12e3bc49b83b 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c | |||
| @@ -553,6 +553,8 @@ struct paravirt_ops paravirt_ops = { | |||
| 553 | .flush_tlb_kernel = native_flush_tlb_global, | 553 | .flush_tlb_kernel = native_flush_tlb_global, |
| 554 | .flush_tlb_single = native_flush_tlb_single, | 554 | .flush_tlb_single = native_flush_tlb_single, |
| 555 | 555 | ||
| 556 | .map_pt_hook = (void *)native_nop, | ||
| 557 | |||
| 556 | .alloc_pt = (void *)native_nop, | 558 | .alloc_pt = (void *)native_nop, |
| 557 | .alloc_pd = (void *)native_nop, | 559 | .alloc_pd = (void *)native_nop, |
| 558 | .alloc_pd_clone = (void *)native_nop, | 560 | .alloc_pd_clone = (void *)native_nop, |
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index acdfe69fb7ad..bd1037bd124b 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
| @@ -370,6 +370,24 @@ static void vmi_check_page_type(u32 pfn, int type) | |||
| 370 | #define vmi_check_page_type(p,t) do { } while (0) | 370 | #define vmi_check_page_type(p,t) do { } while (0) |
| 371 | #endif | 371 | #endif |
| 372 | 372 | ||
| 373 | static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) | ||
| 374 | { | ||
| 375 | /* | ||
| 376 | * Internally, the VMI ROM must map virtual addresses to physical | ||
| 377 | * addresses for processing MMU updates. By the time MMU updates | ||
| 378 | * are issued, this information is typically already lost. | ||
| 379 | * Fortunately, the VMI provides a cache of mapping slots for active | ||
| 380 | * page tables. | ||
| 381 | * | ||
| 382 | * We use slot zero for the linear mapping of physical memory, and | ||
| 383 | * in HIGHPTE kernels, slot 1 and 2 for KM_PTE0 and KM_PTE1. | ||
| 384 | * | ||
| 385 | * args: SLOT VA COUNT PFN | ||
| 386 | */ | ||
| 387 | BUG_ON(type != KM_PTE0 && type != KM_PTE1); | ||
| 388 | vmi_ops.set_linear_mapping((type - KM_PTE0)+1, (u32)va, 1, pfn); | ||
| 389 | } | ||
| 390 | |||
| 373 | static void vmi_allocate_pt(u32 pfn) | 391 | static void vmi_allocate_pt(u32 pfn) |
| 374 | { | 392 | { |
| 375 | vmi_set_page_type(pfn, VMI_PAGE_L1); | 393 | vmi_set_page_type(pfn, VMI_PAGE_L1); |
| @@ -813,6 +831,7 @@ static inline int __init activate_vmi(void) | |||
| 813 | vmi_ops.allocate_page = vmi_get_function(VMI_CALL_AllocatePage); | 831 | vmi_ops.allocate_page = vmi_get_function(VMI_CALL_AllocatePage); |
| 814 | vmi_ops.release_page = vmi_get_function(VMI_CALL_ReleasePage); | 832 | vmi_ops.release_page = vmi_get_function(VMI_CALL_ReleasePage); |
| 815 | 833 | ||
| 834 | paravirt_ops.map_pt_hook = vmi_map_pt_hook; | ||
| 816 | paravirt_ops.alloc_pt = vmi_allocate_pt; | 835 | paravirt_ops.alloc_pt = vmi_allocate_pt; |
| 817 | paravirt_ops.alloc_pd = vmi_allocate_pd; | 836 | paravirt_ops.alloc_pd = vmi_allocate_pd; |
| 818 | paravirt_ops.alloc_pd_clone = vmi_allocate_pd_clone; | 837 | paravirt_ops.alloc_pd_clone = vmi_allocate_pd_clone; |
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index a35c81480654..e01d895d7379 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h | |||
| @@ -131,6 +131,8 @@ struct paravirt_ops | |||
| 131 | void (*flush_tlb_kernel)(void); | 131 | void (*flush_tlb_kernel)(void); |
| 132 | void (*flush_tlb_single)(u32 addr); | 132 | void (*flush_tlb_single)(u32 addr); |
| 133 | 133 | ||
| 134 | void (fastcall *map_pt_hook)(int type, pte_t *va, u32 pfn); | ||
| 135 | |||
| 134 | void (*alloc_pt)(u32 pfn); | 136 | void (*alloc_pt)(u32 pfn); |
| 135 | void (*alloc_pd)(u32 pfn); | 137 | void (*alloc_pd)(u32 pfn); |
| 136 | void (*alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); | 138 | void (*alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); |
| @@ -354,6 +356,8 @@ static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, | |||
| 354 | #define __flush_tlb_global() paravirt_ops.flush_tlb_kernel() | 356 | #define __flush_tlb_global() paravirt_ops.flush_tlb_kernel() |
| 355 | #define __flush_tlb_single(addr) paravirt_ops.flush_tlb_single(addr) | 357 | #define __flush_tlb_single(addr) paravirt_ops.flush_tlb_single(addr) |
| 356 | 358 | ||
| 359 | #define paravirt_map_pt_hook(type, va, pfn) paravirt_ops.map_pt_hook(type, va, pfn) | ||
| 360 | |||
| 357 | #define paravirt_alloc_pt(pfn) paravirt_ops.alloc_pt(pfn) | 361 | #define paravirt_alloc_pt(pfn) paravirt_ops.alloc_pt(pfn) |
| 358 | #define paravirt_release_pt(pfn) paravirt_ops.release_pt(pfn) | 362 | #define paravirt_release_pt(pfn) paravirt_ops.release_pt(pfn) |
| 359 | 363 | ||
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index e6a4723f0eb1..c3b58d473a55 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h | |||
| @@ -263,6 +263,7 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p | |||
| 263 | */ | 263 | */ |
| 264 | #define pte_update(mm, addr, ptep) do { } while (0) | 264 | #define pte_update(mm, addr, ptep) do { } while (0) |
| 265 | #define pte_update_defer(mm, addr, ptep) do { } while (0) | 265 | #define pte_update_defer(mm, addr, ptep) do { } while (0) |
| 266 | #define paravirt_map_pt_hook(slot, va, pfn) do { } while (0) | ||
| 266 | #endif | 267 | #endif |
| 267 | 268 | ||
| 268 | /* | 269 | /* |
| @@ -469,10 +470,24 @@ extern pte_t *lookup_address(unsigned long address); | |||
| 469 | #endif | 470 | #endif |
| 470 | 471 | ||
| 471 | #if defined(CONFIG_HIGHPTE) | 472 | #if defined(CONFIG_HIGHPTE) |
| 472 | #define pte_offset_map(dir, address) \ | 473 | #define pte_offset_map(dir, address) \ |
| 473 | ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) | 474 | ({ \ |
| 474 | #define pte_offset_map_nested(dir, address) \ | 475 | pte_t *__ptep; \ |
| 475 | ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) | 476 | unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ |
| 477 | __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE0);\ | ||
| 478 | paravirt_map_pt_hook(KM_PTE0,__ptep, pfn); \ | ||
| 479 | __ptep = __ptep + pte_index(address); \ | ||
| 480 | __ptep; \ | ||
| 481 | }) | ||
| 482 | #define pte_offset_map_nested(dir, address) \ | ||
| 483 | ({ \ | ||
| 484 | pte_t *__ptep; \ | ||
| 485 | unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ | ||
| 486 | __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE1);\ | ||
| 487 | paravirt_map_pt_hook(KM_PTE1,__ptep, pfn); \ | ||
| 488 | __ptep = __ptep + pte_index(address); \ | ||
| 489 | __ptep; \ | ||
| 490 | }) | ||
| 476 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) | 491 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) |
| 477 | #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) | 492 | #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) |
| 478 | #else | 493 | #else |
