Loading kernel/kcsan/encoding.h +11 −9 Original line number Diff line number Diff line Loading @@ -37,18 +37,20 @@ */ #define WATCHPOINT_ADDR_BITS (BITS_PER_LONG-1 - WATCHPOINT_SIZE_BITS) /* * Masks to set/retrieve the encoded data. */ /* Bitmasks for the encoded watchpoint access information. */ #define WATCHPOINT_WRITE_MASK BIT(BITS_PER_LONG-1) #define WATCHPOINT_SIZE_MASK \ GENMASK(BITS_PER_LONG-2, BITS_PER_LONG-2 - WATCHPOINT_SIZE_BITS) #define WATCHPOINT_ADDR_MASK \ GENMASK(BITS_PER_LONG-3 - WATCHPOINT_SIZE_BITS, 0) #define WATCHPOINT_SIZE_MASK GENMASK(BITS_PER_LONG-2, WATCHPOINT_ADDR_BITS) #define WATCHPOINT_ADDR_MASK GENMASK(WATCHPOINT_ADDR_BITS-1, 0) static_assert(WATCHPOINT_ADDR_MASK == (1UL << WATCHPOINT_ADDR_BITS) - 1); static_assert((WATCHPOINT_WRITE_MASK ^ WATCHPOINT_SIZE_MASK ^ WATCHPOINT_ADDR_MASK) == ~0UL); static inline bool check_encodable(unsigned long addr, size_t size) { return size <= MAX_ENCODABLE_SIZE; /* * While we can encode addrs<PAGE_SIZE, avoid crashing with a NULL * pointer deref inside KCSAN. */ return addr >= PAGE_SIZE && size <= MAX_ENCODABLE_SIZE; } static inline long Loading kernel/kcsan/selftest.c +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ static bool test_encode_decode(void) unsigned long addr; prandom_bytes(&addr, sizeof(addr)); if (addr < PAGE_SIZE) addr = PAGE_SIZE; if (WARN_ON(!check_encodable(addr, size))) return false; Loading Loading
kernel/kcsan/encoding.h +11 −9 Original line number Diff line number Diff line Loading @@ -37,18 +37,20 @@ */ #define WATCHPOINT_ADDR_BITS (BITS_PER_LONG-1 - WATCHPOINT_SIZE_BITS) /* * Masks to set/retrieve the encoded data. */ /* Bitmasks for the encoded watchpoint access information. */ #define WATCHPOINT_WRITE_MASK BIT(BITS_PER_LONG-1) #define WATCHPOINT_SIZE_MASK \ GENMASK(BITS_PER_LONG-2, BITS_PER_LONG-2 - WATCHPOINT_SIZE_BITS) #define WATCHPOINT_ADDR_MASK \ GENMASK(BITS_PER_LONG-3 - WATCHPOINT_SIZE_BITS, 0) #define WATCHPOINT_SIZE_MASK GENMASK(BITS_PER_LONG-2, WATCHPOINT_ADDR_BITS) #define WATCHPOINT_ADDR_MASK GENMASK(WATCHPOINT_ADDR_BITS-1, 0) static_assert(WATCHPOINT_ADDR_MASK == (1UL << WATCHPOINT_ADDR_BITS) - 1); static_assert((WATCHPOINT_WRITE_MASK ^ WATCHPOINT_SIZE_MASK ^ WATCHPOINT_ADDR_MASK) == ~0UL); static inline bool check_encodable(unsigned long addr, size_t size) { return size <= MAX_ENCODABLE_SIZE; /* * While we can encode addrs<PAGE_SIZE, avoid crashing with a NULL * pointer deref inside KCSAN. */ return addr >= PAGE_SIZE && size <= MAX_ENCODABLE_SIZE; } static inline long Loading
kernel/kcsan/selftest.c +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ static bool test_encode_decode(void) unsigned long addr; prandom_bytes(&addr, sizeof(addr)); if (addr < PAGE_SIZE) addr = PAGE_SIZE; if (WARN_ON(!check_encodable(addr, size))) return false; Loading