From 71752e276ccff6b7b830abc1c4ff96a70990ad98 Mon Sep 17 00:00:00 2001 From: Johannes Wikner Date: Thu, 9 Nov 2023 16:20:37 +0100 Subject: [PATCH] vmm: don't vmap non-canonical addresses Moving over the BITS_PER_LONG from bitmap.h to compiler.h. Shifting the sign bit to the highest position turns the pointer into a negative number that will remain sign extended when shifting it back down. Signed-off-by: Johannes Wikner --- arch/x86/pagetables.c | 7 ++++++- include/arch/x86/page.h | 8 ++++++++ include/bitmap.h | 2 +- include/compiler.h | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/x86/pagetables.c b/arch/x86/pagetables.c index 7f25f886..9a0e9c5e 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 bool is_canon_va(const void *va) { + const unsigned int sign_bits = BITS_PER_LONG - VA_BITS; + return _ptr(((long) va << sign_bits) >> sign_bits) == va; +} + 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)) || !is_canon_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) diff --git a/include/bitmap.h b/include/bitmap.h index bf4f2f52..6faadbf5 100644 --- a/include/bitmap.h +++ b/include/bitmap.h @@ -25,9 +25,9 @@ #ifndef KTF_BITMAP_H #define KTF_BITMAP_H +#include #include -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8) #define BITS_TO_LONGS(nbits) div_round_up(nbits, BITS_PER_LONG) typedef struct { diff --git a/include/compiler.h b/include/compiler.h index 176c86c1..656c2a61 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -27,6 +27,7 @@ #define KTF_COMPILER_H #define BITS_PER_BYTE 8 +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8) #define _STR(x) #x #define STR(x) _STR(x)