diff --git a/arch/x86/pagetables.c b/arch/x86/pagetables.c index f388c1a4..8c48ca31 100644 --- a/arch/x86/pagetables.c +++ b/arch/x86/pagetables.c @@ -92,6 +92,11 @@ static inline void dump_pte(void *entry, mfn_t table, int level, int index) { level, index, paddr, flags); } +static inline int canonical_va(void *va) { + unsigned long sign = (_ul(va) >> (VA_BITS - 1)) & 1; + return sign * (_ul(1) << (sizeof(va) - VA_BITS)) - 1 == _ul(va) >> VA_BITS; +} + static void dump_pagetable(mfn_t table, int level) { pte_t *pt; @@ -262,7 +267,7 @@ static void *_vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order, mfn_t l1t_mfn, l2t_mfn, l3t_mfn; pgentry_t *tab, *entry; - if (!va || (_ul(va) & ~PAGE_ORDER_TO_MASK(order))) + if (!va || (_ul(va) & ~PAGE_ORDER_TO_MASK(order)) || !canonical_va(va)) return NULL; dprintk("%s: va: 0x%p mfn: 0x%lx (order: %u)\n", __func__, va, mfn, order); diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index 0844baa2..06532eb2 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -150,6 +150,14 @@ typedef enum pat_memory_type pat_memory_type_t; typedef unsigned long paddr_t; typedef unsigned long mfn_t; +#if defined(__x86_64__) +#define la57_enabled() 0 // TODO: 5 level paging unsupported for now +#define VA_BITS (la57_enabled() ? 57 : 48) /* Number of canonical address bits */ +#else +#define la57_enabled() 0 +#define VA_BITS 32 +#endif + #define _paddr(addr) ((paddr_t) _ul(addr)) #define PADDR_INVALID (0UL)