Home | History | Annotate | Download | only in x86
      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