8/8 Create MMU 2/3 level accessors in the sub-arch layer (i386)
PATCH 1/1 8/8 Create MMU 2/3 level accessors in the sub-arch layer (i386)
i386 Transparent paravirtualization sub-arch patch #8.
Transparent paravirtualization support for MMU operations.
All operations which update live page table entries have been moved to the sub-architecture layer. Unfortunately, this required yet another parallel set of pgtable-Nlevel-ops.h files, but this avoids the ugliness of having to use #ifdef's all of the code.
This is pure code motion. Anything else would be a bug.
include/asm-i386/pgtable-2level.h +0 -11
@@ -8,17 +8,6 @@#define pgd_ERROR (e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -/* -* Certain architectures need to do special things when PTEs -* within a page table are directly modified. Thus, the following -* hook is made available. -*/ -#define set_pte (pteptr, pteval) (*(pteptr) = pteval) -#define set_pte_at (mm,addr,ptep,pteval) set_pte(ptep,pteval) -#define set_pte_atomic (pteptr, pteval) set_pte(pteptr,pteval) -#define set_pmd (pmdptr, pmdval) (*(pmdptr) = (pmdval)) - -#define ptep_get_and_clear (mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0))#define pte_same (a, b) ((a).pte_low == (b).pte_low)#define pte_page (x) pfn_to_page(pte_pfn(x))#define pte_none (x) (!(x).pte_low)
include/asm-i386/pgtable-3level.h +0 -34
@@ -44,28 +44,6 @@return pte_x (pte); } -/* Rules for using set_pte: the pte being assigned *must* be -* either not present or in a state where the hardware will -* not attempt to update the pte. In places where this is -* not possible, use pte_get_and_clear to obtain the old pte -* value and then use set_pte to update it. -ben -*/ -static inline void set_pte (pte_t *ptep,pte_t pte) -{ - ptep->pte_high = pte.pte_high; -smp_wmb (); - ptep->pte_low = pte.pte_low; -} -#define set_pte_at (mm,addr,ptep,pteval) set_pte(ptep,pteval) - -#define __HAVE_ARCH_SET_PTE_ATOMIC -#define set_pte_atomic (pteptr,pteval) \ - set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) -#define set_pmd (pmdptr,pmdval) \ - set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval)) -#define set_pud (pudptr,pudval) \ - (*(pudptr) = (pudval)) -/* * Pentium-II erratum A13: in PAE mode we explicitly have to flush * the TLB via cr3 if the top-level pgd is changed...
@@ -90,18 +68,6 @@#define pmd_offset (pud, address) ((pmd_t *) pud_page(*(pud)) + \ pmd_index(address)) -static inline pte_t ptep_get_and_clear (struct mm_struct *mm,unsigned long addr,pte_t *ptep) -{ -pte_t res; - -/* xchg acts as a barrier before the setting of the high bits */ - res.pte_low =xchg (&ptep->pte_low,0 ); - res.pte_high = ptep->pte_high; - ptep->pte_high =0 ; - -return res; -} -static inline int pte_same (pte_t a,pte_t b) {return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
include/asm-i386/pgtable.h +5 -43
76 lines not on this page · raw message
include/asm-i386/mach-default/pgtable-2level-ops.h +15 -0
@@ -0,0 +1,15 @@ +#ifndef _MACH_PGTABLE_LEVEL_OPS_H +#define _MACH_PGTABLE_LEVEL_OPS_H + +/* +* Certain architectures need to do special things when PTEs +* within a page table are directly modified. Thus, the following +* hook is made available. +*/ +#define set_pte (pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_atomic (pteptr, pteval) set_pte(pteptr,pteval) +#define set_pmd (pmdptr, pmdval) (*(pmdptr) = (pmdval)) + +#define ptep_get_and_clear (mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) + +#endif /* _PGTABLE_OPS_H */
include/asm-i386/mach-default/pgtable-3level-ops.h +37 -0
@@ -0,0 +1,37 @@ +#ifndef _MACH_PGTABLE_LEVEL_OPS_H +#define _MACH_PGTABLE_LEVEL_OPS_H + +/* Rules for using set_pte: the pte being assigned *must* be +* either not present or in a state where the hardware will +* not attempt to update the pte. In places where this is +* not possible, use pte_get_and_clear to obtain the old pte +* value and then use set_pte to update it. -ben +*/ +static inline void set_pte (pte_t *ptep,pte_t pte) +{ + ptep->pte_high = pte.pte_high; +smp_wmb (); + ptep->pte_low = pte.pte_low; +} + +#define __HAVE_ARCH_SET_PTE_ATOMIC +#define set_pte_atomic (pteptr,pteval) \ + set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) +#define set_pmd (pmdptr,pmdval) \ + set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval)) +#define set_pud (pudptr,pudval) \ + (*(pudptr) = (pudval)) + +static inline pte_t ptep_get_and_clear (struct mm_struct *mm,unsigned long addr,pte_t *ptep) +{ +pte_t res; + +/* xchg acts as a barrier before the setting of the high bits */ + res.pte_low =xchg (&ptep->pte_low,0 ); + res.pte_high = ptep->pte_high; + ptep->pte_high =0 ; + +return res; +} + +#endif
include/asm-i386/mach-default/pgtable-ops.h +77 -0
77 lines not on this page · raw message
Quoted 4 lines · * Zachary Amsden ([email protected]) wrote:
All operations which update live page table entries have been moved to the sub-architecture layer. Unfortunately, this required yet another parallel set of
pgtable-Nlevel-ops.hfiles, but this avoids the ugliness of having to use #ifdef's all of the code.
I hit similar issue...
include/asm-i386/pgtable.h +16 -17
@@ -200,15 +200,6 @@ extern unsigned long long __PAGE_KERNEL,/* The boot page tables (all created as a single array) */ extern unsigned long pg0[]; -#define pte_present (x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear (mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) - -#define pmd_none (x) (!pmd_val(x)) -#define pmd_present (x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_clear (xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad (x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) - -#define pages_to_mb (x) ((x) >> (20-PAGE_SHIFT))/*
@@ -237,6 +228,17 @@ static inline pte_t pte_mkdirty(pte_t ptstatic inline pte_t pte_mkyoung (pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED;return pte; }static inline pte_t pte_mkwrite (pte_t pte) { (pte).pte_low |= _PAGE_RW;return pte; } +#include <mach_pgtable.h> + +#define pte_present (x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pte_clear (mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) + +#define pmd_none (x) (!pmd_val(x)) +#define pmd_present (x) (pmd_val(x) & _PAGE_PRESENT) +#define pmd_clear (xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad (x) mach_pmd_bad(x) + +#ifdef CONFIG_X86_PAE # include <asm/pgtable-3level.h> #else
@@ -257,10 +259,7 @@ static inline int ptep_test_and_clear_yoreturn test_and_clear_bit (_PAGE_BIT_ACCESSED, &ptep->pte_low); } -static inline void ptep_set_wrprotect (struct mm_struct *mm,unsigned long addr,pte_t *ptep) -{ -clear_bit (_PAGE_BIT_RW, &ptep->pte_low); -} +#define ptep_set_wrprotect (mm,addr,ptep) mach_ptep_set_wrprotect(mm,addr,ptep)/* * Macro to mark a page protection value as "uncacheable". On processors which do not support
@@ -363,9 +362,9 @@ extern void noexec_setup(const char *str#if defined(CONFIG_HIGHPTE )#define pte_offset_map (dir, address) \ - ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) + ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address))#define pte_offset_map_nested (dir, address) \ - ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) + ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE1) + pte_index(address))#define pte_unmap (pte) kunmap_atomic(pte, KM_PTE0)#define pte_unmap_nested (pte) kunmap_atomic(pte, KM_PTE1)#else
@@ -403,10 +402,10 @@ extern void noexec_setup(const char *str#endif /* !CONFIG_DISCONTIGMEM */ #define io_remap_page_range (vma, vaddr, paddr, size, prot) \ - remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + mach_io_remap_page_range(vma, vaddr, paddr, size, prot)#define io_remap_pfn_range (vma, vaddr, pfn, size, prot) \ - remap_pfn_range(vma, vaddr, pfn, size, prot) + mach_io_remap_pfn_range(vma, vaddr, pfn, size, prot)#define MK_IOSPACE_PFN (space, pfn) (pfn)#define GET_IOSPACE (pfn) 0
include/asm-i386/pgtable-2level.h +5 -4
@@ -2,6 +2,7 @@#define _I386_PGTABLE_2LEVEL_H#include <asm-generic/pgtable-nopmd.h> +#include <mach_pgtable-2level.h> #define pte_ERROR (e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
@@ -16,13 +17,13 @@#define set_pte (pteptr, pteval) (*(pteptr) = pteval)#define set_pte_at (mm,addr,ptep,pteval) set_pte(ptep,pteval)#define set_pte_atomic (pteptr, pteval) set_pte(pteptr,pteval) -#define set_pmd (pmdptr, pmdval) (*(pmdptr) = (pmdval)) +#define set_pmd (pmdptr, pmdval) mach_set_pmd(pmdptr, pmdval) -#define ptep_get_and_clear (mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) +#define ptep_get_and_clear (mm,addr,xp) mach_ptep_get_and_clear(mm,addr,xp)#define pte_same (a, b) ((a).pte_low == (b).pte_low) -#define pte_page (x) pfn_to_page(pte_pfn(x)) +#define pte_page (x) mach_pte_page(x)#define pte_none (x) (!(x).pte_low) -#define pte_pfn (x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) +#define pte_pfn (x) mach_pte_pfn(x)#define pfn_pte (pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))#define pfn_pmd (pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
include/asm-i386/pgtable-3level-defs.h +1 -1
@@ -1,7 +1,7 @@#ifndef _I386_PGTABLE_3LEVEL_DEFS_H#define _I386_PGTABLE_3LEVEL_DEFS_H -#define HAVE_SHARED_KERNEL_PMD 1 +#include <mach_pgtable-3level-defs.h> /* * PGDIR_SHIFT determines what a top-level page table entry can map
include/asm-i386/mach-default/mach_pgtable.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef __ASM_MACH_PGTABLE_H +#define __ASM_MACH_PGTABLE_H + +#define mach_pmd_present (x) (pmd_val(x) & _PAGE_PRESENT) +#define mach_pmd_bad (x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) + +static inline void mach_ptep_set_wrprotect (struct mm_struct *mm,unsigned long addr,pte_t *ptep) +{ +clear_bit (_PAGE_BIT_RW, &ptep->pte_low); +} + +#define mach_io_remap_page_range (vma, vaddr, paddr, size, prot) \ + remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + +#define mach_io_remap_pfn_range (vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#endif
include/asm-i386/mach-default/mach_pgtable-2level.h new file +10 -0
@@ -0,0 +1,10 @@ +#ifndef _ASM_MACH_PGTABLE_2LEVEL_H +#define _ASM_MACH_PGTABLE_2LEVEL_H + +#define mach_set_pmd (pmdptr, pmdval) (*(pmdptr) = (pmdval)) + +#define mach_ptep_get_and_clear (mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) +#define mach_pte_page (x) pfn_to_page(pte_pfn(x)) +#define mach_pte_pfn (x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) + +#endif
include/asm-i386/mach-default/mach_pgtable-3level-defs.h new file +6 -0
@@ -0,0 +1,6 @@ +#ifndef _ASM_MACH_PGTABLE_3LEVEL_DEFS_H +#define _ASM_MACH_PGTABLE_3LEVEL_DEFS_H + +#define HAVE_SHARED_KERNEL_PMD 1 + +#endif