mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 07:38:10 +00:00
riscv: Add pte bit to distinguish swap from invalid
Previously, invalid PTEs and swap PTEs had the same binary representation, causing errors when attempting to unmap PROT_NONE mappings, including implicit unmap on exit. Typical error: swap_info_get: Bad swap file entry 40000000007a9879 BUG: Bad page map in process a.out pte:3d4c3cc0 pmd:3e521401 Cc: stable@vger.kernel.org Signed-off-by: Stefan O'Rear <sorear2@gmail.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
d13937116f
commit
e3613bb8af
2 changed files with 10 additions and 4 deletions
|
@ -35,6 +35,12 @@
|
||||||
#define _PAGE_SPECIAL _PAGE_SOFT
|
#define _PAGE_SPECIAL _PAGE_SOFT
|
||||||
#define _PAGE_TABLE _PAGE_PRESENT
|
#define _PAGE_TABLE _PAGE_PRESENT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _PAGE_PROT_NONE is set on not-present pages (and ignored by the hardware) to
|
||||||
|
* distinguish them from swapped out pages
|
||||||
|
*/
|
||||||
|
#define _PAGE_PROT_NONE _PAGE_READ
|
||||||
|
|
||||||
#define _PAGE_PFN_SHIFT 10
|
#define _PAGE_PFN_SHIFT 10
|
||||||
|
|
||||||
/* Set of bits to preserve across pte_modify() */
|
/* Set of bits to preserve across pte_modify() */
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
/* Page protection bits */
|
/* Page protection bits */
|
||||||
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER)
|
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER)
|
||||||
|
|
||||||
#define PAGE_NONE __pgprot(0)
|
#define PAGE_NONE __pgprot(_PAGE_PROT_NONE)
|
||||||
#define PAGE_READ __pgprot(_PAGE_BASE | _PAGE_READ)
|
#define PAGE_READ __pgprot(_PAGE_BASE | _PAGE_READ)
|
||||||
#define PAGE_WRITE __pgprot(_PAGE_BASE | _PAGE_READ | _PAGE_WRITE)
|
#define PAGE_WRITE __pgprot(_PAGE_BASE | _PAGE_READ | _PAGE_WRITE)
|
||||||
#define PAGE_EXEC __pgprot(_PAGE_BASE | _PAGE_EXEC)
|
#define PAGE_EXEC __pgprot(_PAGE_BASE | _PAGE_EXEC)
|
||||||
|
@ -98,7 +98,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||||
|
|
||||||
static inline int pmd_present(pmd_t pmd)
|
static inline int pmd_present(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return (pmd_val(pmd) & _PAGE_PRESENT);
|
return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pmd_none(pmd_t pmd)
|
static inline int pmd_none(pmd_t pmd)
|
||||||
|
@ -178,7 +178,7 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long addr)
|
||||||
|
|
||||||
static inline int pte_present(pte_t pte)
|
static inline int pte_present(pte_t pte)
|
||||||
{
|
{
|
||||||
return (pte_val(pte) & _PAGE_PRESENT);
|
return (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pte_none(pte_t pte)
|
static inline int pte_none(pte_t pte)
|
||||||
|
@ -380,7 +380,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
|
||||||
*
|
*
|
||||||
* Format of swap PTE:
|
* Format of swap PTE:
|
||||||
* bit 0: _PAGE_PRESENT (zero)
|
* bit 0: _PAGE_PRESENT (zero)
|
||||||
* bit 1: reserved for future use (zero)
|
* bit 1: _PAGE_PROT_NONE (zero)
|
||||||
* bits 2 to 6: swap type
|
* bits 2 to 6: swap type
|
||||||
* bits 7 to XLEN-1: swap offset
|
* bits 7 to XLEN-1: swap offset
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue