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 52struct mpx_bd_entry { 53 union { 54 char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; 55 void *contents[0]; 56 }; 57} __attribute__((packed)); 58 59struct mpx_bt_entry { 60 union { 61 char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; 62 unsigned long contents[0]; 63 }; 64} __attribute__((packed)); 65 66struct mpx_bounds_dir { 67 struct mpx_bd_entry entries[MPX_BOUNDS_DIR_NR_ENTRIES]; 68} __attribute__((packed)); 69 70struct mpx_bounds_table { 71 struct mpx_bt_entry entries[MPX_BOUNDS_TABLE_NR_ENTRIES]; 72} __attribute__((packed)); 73 74static 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 81static 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 87static 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 93static 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 100static 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 106static 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 115static inline struct mpx_bt_entry * 116mpx_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