1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _MPX_HW_H 3 #define _MPX_HW_H 4 5 #include <assert.h> 6 7 /* Describe the MPX Hardware Layout in here */ 8 9 #define NR_MPX_BOUNDS_REGISTERS 4 10 11 #ifdef __i386__ 12 13 #define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 16 /* 4 * 32-bits */ 14 #define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 14) /* 16k */ 15 #define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 4 16 #define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 22) /* 4MB */ 17 18 #define MPX_BOUNDS_TABLE_BOTTOM_BIT 2 19 #define MPX_BOUNDS_TABLE_TOP_BIT 11 20 #define MPX_BOUNDS_DIR_BOTTOM_BIT 12 21 #define MPX_BOUNDS_DIR_TOP_BIT 31 22 23 #else 24 25 /* 26 * Linear Address of "pointer" (LAp) 27 * 0 -> 2: ignored 28 * 3 -> 19: index in to bounds table 29 * 20 -> 47: index in to bounds directory 30 * 48 -> 63: ignored 31 */ 32 33 #define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 32 34 #define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 22) /* 4MB */ 35 #define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 8 36 #define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 31) /* 2GB */ 37 38 #define MPX_BOUNDS_TABLE_BOTTOM_BIT 3 39 #define MPX_BOUNDS_TABLE_TOP_BIT 19 40 #define MPX_BOUNDS_DIR_BOTTOM_BIT 20 41 #define MPX_BOUNDS_DIR_TOP_BIT 47 42 43 #endif 44 45 #define MPX_BOUNDS_DIR_NR_ENTRIES \ 46 (MPX_BOUNDS_DIR_SIZE_BYTES/MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES) 47 #define MPX_BOUNDS_TABLE_NR_ENTRIES \ 48 (MPX_BOUNDS_TABLE_SIZE_BYTES/MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES) 49 50 #define MPX_BOUNDS_TABLE_ENTRY_VALID_BIT 0x1 51 52 struct mpx_bd_entry { 53 union { 54 char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; 55 void *contents[0]; 56 }; 57 } __attribute__((packed)); 58 59 struct mpx_bt_entry { 60 union { 61 char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; 62 unsigned long contents[0]; 63 }; 64 } __attribute__((packed)); 65 66 struct mpx_bounds_dir { 67 struct mpx_bd_entry entries[MPX_BOUNDS_DIR_NR_ENTRIES]; 68 } __attribute__((packed)); 69 70 struct mpx_bounds_table { 71 struct mpx_bt_entry entries[MPX_BOUNDS_TABLE_NR_ENTRIES]; 72 } __attribute__((packed)); 73 74 static inline unsigned long GET_BITS(unsigned long val, int bottombit, int topbit) 75 { 76 int total_nr_bits = topbit - bottombit; 77 unsigned long mask = (1UL << total_nr_bits)-1; 78 return (val >> bottombit) & mask; 79 } 80 81 static inline unsigned long __vaddr_bounds_table_index(void *vaddr) 82 { 83 return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_TABLE_BOTTOM_BIT, 84 MPX_BOUNDS_TABLE_TOP_BIT); 85 } 86 87 static inline unsigned long __vaddr_bounds_directory_index(void *vaddr) 88 { 89 return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_DIR_BOTTOM_BIT, 90 MPX_BOUNDS_DIR_TOP_BIT); 91 } 92 93 static inline struct mpx_bd_entry *mpx_vaddr_to_bd_entry(void *vaddr, 94 struct mpx_bounds_dir *bounds_dir) 95 { 96 unsigned long index = __vaddr_bounds_directory_index(vaddr); 97 return &bounds_dir->entries[index]; 98 } 99 100 static inline int bd_entry_valid(struct mpx_bd_entry *bounds_dir_entry) 101 { 102 unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents; 103 return (__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT); 104 } 105 106 static inline struct mpx_bounds_table * 107 __bd_entry_to_bounds_table(struct mpx_bd_entry *bounds_dir_entry) 108 { 109 unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents; 110 assert(__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT); 111 __bd_entry &= ~MPX_BOUNDS_TABLE_ENTRY_VALID_BIT; 112 return (struct mpx_bounds_table *)__bd_entry; 113 } 114 115 static inline struct mpx_bt_entry * 116 mpx_vaddr_to_bt_entry(void *vaddr, struct mpx_bounds_dir *bounds_dir) 117 { 118 struct mpx_bd_entry *bde = mpx_vaddr_to_bd_entry(vaddr, bounds_dir); 119 struct mpx_bounds_table *bt = __bd_entry_to_bounds_table(bde); 120 unsigned long index = __vaddr_bounds_table_index(vaddr); 121 return &bt->entries[index]; 122 } 123 124 #endif /* _MPX_HW_H */ 125