diff options
Diffstat (limited to 'i386/intel/pmap.c')
-rw-r--r-- | i386/intel/pmap.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c index 2cdd20a..490c1d9 100644 --- a/i386/intel/pmap.c +++ b/i386/intel/pmap.c @@ -1046,34 +1046,44 @@ pmap_page_table_page_alloc() } #ifdef MACH_XEN -#ifdef MACH_PV_PAGETABLES void pmap_map_mfn(void *_addr, unsigned long mfn) { vm_offset_t addr = (vm_offset_t) _addr; pt_entry_t *pte, *pdp; vm_offset_t ptp; pt_entry_t ma = ((pt_entry_t) mfn) << PAGE_SHIFT; + + /* Add a ptp if none exist yet for this pte */ if ((pte = pmap_pte(kernel_pmap, addr)) == PT_ENTRY_NULL) { ptp = phystokv(pmap_page_table_page_alloc()); +#ifdef MACH_PV_PAGETABLES pmap_set_page_readonly((void*) ptp); if (!hyp_mmuext_op_mfn (MMUEXT_PIN_L1_TABLE, pa_to_mfn(ptp))) panic("couldn't pin page %p(%p)\n",ptp,(vm_offset_t) kv_to_ma(ptp)); +#endif /* MACH_PV_PAGETABLES */ pdp = pmap_pde(kernel_pmap, addr); + +#ifdef MACH_PV_PAGETABLES if (!hyp_mmu_update_pte(kv_to_ma(pdp), pa_to_pte(kv_to_ma(ptp)) | INTEL_PTE_VALID | INTEL_PTE_USER | INTEL_PTE_WRITE)) panic("%s:%d could not set pde %p(%p) to %p(%p)\n",__FILE__,__LINE__,kvtophys((vm_offset_t)pdp),(vm_offset_t) kv_to_ma(pdp), ptp, (vm_offset_t) pa_to_ma(ptp)); +#else /* MACH_PV_PAGETABLES */ + *pdp = pa_to_pte(kvtophys(ptp)) | INTEL_PTE_VALID + | INTEL_PTE_USER + | INTEL_PTE_WRITE; +#endif /* MACH_PV_PAGETABLES */ pte = pmap_pte(kernel_pmap, addr); } + +#ifdef MACH_PV_PAGETABLES if (!hyp_mmu_update_pte(kv_to_ma(pte), ma | INTEL_PTE_VALID | INTEL_PTE_WRITE)) panic("%s:%d could not set pte %p(%p) to %p(%p)\n",__FILE__,__LINE__,pte,(vm_offset_t) kv_to_ma(pte), ma, ma_to_pa(ma)); -} #else /* MACH_PV_PAGETABLES */ -void pmap_map_mfn(void *_addr, unsigned long mfn) { /* Note: in this case, mfn is actually a pfn. */ - panic("TODO %s:%d\n",__FILE__,__LINE__); -} + WRITE_PTE(pte, ma | INTEL_PTE_VALID | INTEL_PTE_WRITE); #endif /* MACH_PV_PAGETABLES */ +} #endif /* MACH_XEN */ /* |