1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <errno.h> 4 #include <stddef.h> 5 #include <stdio.h> 6 #include <string.h> 7 8 #include "dexcr.h" 9 #include "utils.h" 10 11 static unsigned int dexcr; 12 static unsigned int hdexcr; 13 static unsigned int effective; 14 15 struct dexcr_aspect { 16 const char *name; 17 const char *desc; 18 unsigned int index; 19 }; 20 21 static const struct dexcr_aspect aspects[] = { 22 { 23 .name = "SBHE", 24 .desc = "Speculative branch hint enable", 25 .index = 0, 26 }, 27 { 28 .name = "IBRTPD", 29 .desc = "Indirect branch recurrent target prediction disable", 30 .index = 3, 31 }, 32 { 33 .name = "SRAPD", 34 .desc = "Subroutine return address prediction disable", 35 .index = 4, 36 }, 37 { 38 .name = "NPHIE", 39 .desc = "Non-privileged hash instruction enable", 40 .index = 5, 41 }, 42 { 43 .name = "PHIE", 44 .desc = "Privileged hash instruction enable", 45 .index = 6, 46 }, 47 }; 48 49 static void print_list(const char *list[], size_t len) 50 { 51 for (size_t i = 0; i < len; i++) { 52 printf("%s", list[i]); 53 if (i + 1 < len) 54 printf(", "); 55 } 56 } 57 58 static void print_dexcr(char *name, unsigned int bits) 59 { 60 const char *enabled_aspects[ARRAY_SIZE(aspects) + 1] = {NULL}; 61 size_t j = 0; 62 63 printf("%s: %08x", name, bits); 64 65 if (bits == 0) { 66 printf("\n"); 67 return; 68 } 69 70 for (size_t i = 0; i < ARRAY_SIZE(aspects); i++) { 71 unsigned int mask = DEXCR_PR_BIT(aspects[i].index); 72 73 if (bits & mask) { 74 enabled_aspects[j++] = aspects[i].name; 75 bits &= ~mask; 76 } 77 } 78 79 if (bits) 80 enabled_aspects[j++] = "unknown"; 81 82 printf(" ("); 83 print_list(enabled_aspects, j); 84 printf(")\n"); 85 } 86 87 static void print_aspect(const struct dexcr_aspect *aspect) 88 { 89 const char *attributes[8] = {NULL}; 90 size_t j = 0; 91 unsigned long mask; 92 93 mask = DEXCR_PR_BIT(aspect->index); 94 if (dexcr & mask) 95 attributes[j++] = "set"; 96 if (hdexcr & mask) 97 attributes[j++] = "set (hypervisor)"; 98 if (!(effective & mask)) 99 attributes[j++] = "clear"; 100 101 printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index); 102 print_list(attributes, j); 103 printf(" \t(%s)\n", aspect->desc); 104 } 105 106 int main(int argc, char *argv[]) 107 { 108 if (!dexcr_exists()) { 109 printf("DEXCR not detected on this hardware\n"); 110 return 1; 111 } 112 113 dexcr = get_dexcr(DEXCR); 114 hdexcr = get_dexcr(HDEXCR); 115 effective = dexcr | hdexcr; 116 117 print_dexcr(" DEXCR", dexcr); 118 print_dexcr(" HDEXCR", hdexcr); 119 print_dexcr("Effective", effective); 120 printf("\n"); 121 122 for (size_t i = 0; i < ARRAY_SIZE(aspects); i++) 123 print_aspect(&aspects[i]); 124 printf("\n"); 125 126 if (effective & DEXCR_PR_NPHIE) { 127 printf("DEXCR[NPHIE] enabled: hashst/hashchk "); 128 if (hashchk_triggers()) 129 printf("working\n"); 130 else 131 printf("failed to trigger\n"); 132 } else { 133 printf("DEXCR[NPHIE] disabled: hashst/hashchk "); 134 if (hashchk_triggers()) 135 printf("unexpectedly triggered\n"); 136 else 137 printf("ignored\n"); 138 } 139 140 return 0; 141 } 142