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
|
@ -35,6 +35,12 @@
|
|||
#define _PAGE_SPECIAL _PAGE_SOFT
|
||||
#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
|
||||
|
||||
/* Set of bits to preserve across pte_modify() */
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
/* Page protection bits */
|
||||
#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_WRITE __pgprot(_PAGE_BASE | _PAGE_READ | _PAGE_WRITE)
|
||||
#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)
|
||||
{
|
||||
return (pmd_val(pmd) & _PAGE_PRESENT);
|
||||
return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return (pte_val(pte) & _PAGE_PRESENT);
|
||||
return (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
|
||||
}
|
||||
|
||||
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:
|
||||
* 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 7 to XLEN-1: swap offset
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue