diff options
Diffstat (limited to 'include/asm-generic/pgtable.h')
| -rw-r--r-- | include/asm-generic/pgtable.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 44ef329531c3..ef87f889ef62 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -195,6 +195,63 @@ static inline int pmd_none_or_clear_bad(pmd_t *pmd) | |||
| 195 | } | 195 | } |
| 196 | return 0; | 196 | return 0; |
| 197 | } | 197 | } |
| 198 | |||
| 199 | static inline pte_t __ptep_modify_prot_start(struct mm_struct *mm, | ||
| 200 | unsigned long addr, | ||
| 201 | pte_t *ptep) | ||
| 202 | { | ||
| 203 | /* | ||
| 204 | * Get the current pte state, but zero it out to make it | ||
| 205 | * non-present, preventing the hardware from asynchronously | ||
| 206 | * updating it. | ||
| 207 | */ | ||
| 208 | return ptep_get_and_clear(mm, addr, ptep); | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline void __ptep_modify_prot_commit(struct mm_struct *mm, | ||
| 212 | unsigned long addr, | ||
| 213 | pte_t *ptep, pte_t pte) | ||
| 214 | { | ||
| 215 | /* | ||
| 216 | * The pte is non-present, so there's no hardware state to | ||
| 217 | * preserve. | ||
| 218 | */ | ||
| 219 | set_pte_at(mm, addr, ptep, pte); | ||
| 220 | } | ||
| 221 | |||
| 222 | #ifndef __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION | ||
| 223 | /* | ||
| 224 | * Start a pte protection read-modify-write transaction, which | ||
| 225 | * protects against asynchronous hardware modifications to the pte. | ||
| 226 | * The intention is not to prevent the hardware from making pte | ||
| 227 | * updates, but to prevent any updates it may make from being lost. | ||
| 228 | * | ||
| 229 | * This does not protect against other software modifications of the | ||
| 230 | * pte; the appropriate pte lock must be held over the transation. | ||
| 231 | * | ||
| 232 | * Note that this interface is intended to be batchable, meaning that | ||
| 233 | * ptep_modify_prot_commit may not actually update the pte, but merely | ||
| 234 | * queue the update to be done at some later time. The update must be | ||
| 235 | * actually committed before the pte lock is released, however. | ||
| 236 | */ | ||
| 237 | static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, | ||
| 238 | unsigned long addr, | ||
| 239 | pte_t *ptep) | ||
| 240 | { | ||
| 241 | return __ptep_modify_prot_start(mm, addr, ptep); | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Commit an update to a pte, leaving any hardware-controlled bits in | ||
| 246 | * the PTE unmodified. | ||
| 247 | */ | ||
| 248 | static inline void ptep_modify_prot_commit(struct mm_struct *mm, | ||
| 249 | unsigned long addr, | ||
| 250 | pte_t *ptep, pte_t pte) | ||
| 251 | { | ||
| 252 | __ptep_modify_prot_commit(mm, addr, ptep, pte); | ||
| 253 | } | ||
| 254 | #endif /* __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION */ | ||
| 198 | #endif /* CONFIG_MMU */ | 255 | #endif /* CONFIG_MMU */ |
| 199 | 256 | ||
| 200 | /* | 257 | /* |
