diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2006-04-29 04:42:26 +0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-04-29 04:42:26 +0400 |
commit | d6754b401a15eaa16492ea5dbaa4826361d3f411 (patch) | |
tree | 032f067d3af458527d903a7653885404ed82431e /include/asm-i386 | |
parent | acc429a517bd11fdcac9bea97d082d26231beb92 (diff) | |
parent | 693f7d362055261882659475d2ef022e32edbff1 (diff) | |
download | linux-d6754b401a15eaa16492ea5dbaa4826361d3f411.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'include/asm-i386')
-rw-r--r-- | include/asm-i386/pgtable-2level.h | 3 | ||||
-rw-r--r-- | include/asm-i386/pgtable-3level.h | 20 | ||||
-rw-r--r-- | include/asm-i386/pgtable.h | 4 | ||||
-rw-r--r-- | include/asm-i386/unistd.h | 3 |
4 files changed, 26 insertions, 4 deletions
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index 27bde973abc7..2756d4b04c27 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -18,6 +18,9 @@ #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) + #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)) diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 36a5aa63cbbf..dccb1b3337ad 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -85,6 +85,26 @@ static inline void pud_clear (pud_t * pud) { } #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ pmd_index(address)) +/* + * For PTEs and PDEs, we must clear the P-bit first when clearing a page table + * entry, so clear the bottom half first and enforce ordering with a compiler + * barrier. + */ +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = 0; +} + +static inline void pmd_clear(pmd_t *pmd) +{ + u32 *tmp = (u32 *)pmd; + *tmp = 0; + smp_wmb(); + *(tmp + 1) = 0; +} + static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t res; diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 248bd80a69c5..09697fec3d2b 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -203,12 +203,10 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; 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) /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)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) @@ -267,7 +265,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long pte_t pte; if (full) { pte = *ptep; - *ptep = __pte(0); + pte_clear(mm, addr, ptep); } else { pte = ptep_get_and_clear(mm, addr, ptep); } diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d81d6cfc1bb4..eb4b152c82fc 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -321,8 +321,9 @@ #define __NR_splice 313 #define __NR_sync_file_range 314 #define __NR_tee 315 +#define __NR_vmsplice 316 -#define NR_syscalls 316 +#define NR_syscalls 317 /* * user-visible error numbers are in the range -1 - -128: see |