summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-06-14 09:25:32 -0700
committerAndy Lutomirski <luto@amacapital.net>2014-06-14 09:25:32 -0700
commit2a3443b531b30cd4aab424d3b2002208ff957474 (patch)
treeaed2fa662567922d6ddd1b088e3ff057f1900ef7
parente64b42b0a1d39c154941329284c7ff3f47c32cd7 (diff)
downloadmisc-tests-2a3443b531b30cd4aab424d3b2002208ff957474.tar.gz
user_visible_state: Add LAR support
-rw-r--r--user_visible_state.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/user_visible_state.c b/user_visible_state.c
index 055de34..bf289e5 100644
--- a/user_visible_state.c
+++ b/user_visible_state.c
@@ -61,18 +61,43 @@ static void show_rdtscp(void)
printf("RDTSCP: cpu %d\n", cpu);
}
-static void show_seglimit(uint16_t index)
+static void show_segment(uint16_t index)
{
- uint32_t okay = 0, limit;
+ uint32_t has_limit = 0, has_ar = 0, limit, ar;
asm ("lsl %[index], %[limit]\n\t"
"jnz 1f\n\t"
- "mov $1, %[okay]\n\t"
+ "mov $1, %[has_limit]\n\t"
"1:"
- : [limit] "=r" (limit), [okay] "+rm" (okay)
+ : [limit] "=r" (limit), [has_limit] "+rm" (has_limit)
: [index] "r" ((index << 3) + 3));
- if (okay) {
- printf("GDT entry %02hu limit: 0x%08X\n", index, limit);
+ asm ("larl %[index], %[ar]\n\t"
+ "jnz 1f\n\t"
+ "mov $1, %[has_ar]\n\t"
+ "1:"
+ : [ar] "=r" (ar), [has_ar] "+rm" (has_ar)
+ : [index] "r" ((index << 3) + 3));
+
+ if (!has_limit && !has_ar)
+ return;
+
+ printf("GDT entry %02hu", index);
+
+ if (has_limit)
+ printf(" limit: 0x%08X", limit);
+
+ if (has_ar) {
+#define ARBITS(low, high) ((ar >> low) & ((1 << (high - low + 1)) - 1))
+#define ARSTR(bit, str) (ARBITS(bit,bit) ? " " str : "")
+ printf(" access rights: 0x%08X (type=%d DPL=%d%s%s%s%s%s%s)",
+ ar, ARBITS(8,11), ARBITS(13,14),
+ ARSTR(12, "S"), ARSTR(15, "P"),
+ ARSTR(20, "software-available"),
+ ARSTR(21, "L"), ARSTR(22, "D/B"), ARSTR(23, "G"));
+#undef ARSTR
+#undef ARBITS
}
+
+ printf("\n");
}
int main()
@@ -84,5 +109,5 @@ int main()
show_flags();
show_rdtscp();
for (int i = 0; i <= gdtlimit; i++)
- show_seglimit(i);
+ show_segment(i);
}