Add R/W accessors for CR3, CR4, XCR0 and implement CPUID.

And use these acessors where it's already possible.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 inmates/lib/x86/include/asm/regs.h | 77 ++++++++++++++++++++++++++++++
 inmates/lib/x86/mem.c              |  3 +-
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/inmates/lib/x86/include/asm/regs.h 
b/inmates/lib/x86/include/asm/regs.h
index a004fdd2..25fb697d 100644
--- a/inmates/lib/x86/include/asm/regs.h
+++ b/inmates/lib/x86/include/asm/regs.h
@@ -48,3 +48,80 @@
 
 #define MSR_MTRR_DEF_TYPE      0x000002ff
 #define MTRR_ENABLE            0x00000800
+
+#ifndef __ASSEMBLY__
+
+#include <string.h>
+
+#define READ_CR(n)                                             \
+       static inline unsigned long read_cr##n(void)            \
+       {                                                       \
+               unsigned long cr;                               \
+               asm volatile("mov %%cr" __stringify(n) ", %0"   \
+                       : "=r" (cr));   \
+                                                               \
+               return cr;                                      \
+       }
+
+READ_CR(3)
+READ_CR(4)
+
+static inline void write_cr4(unsigned long val)
+{
+       asm volatile("mov %0, %%cr4" : : "r" (val));
+}
+
+static inline u64 read_xcr0(void)
+{
+       register u32 eax, edx;
+
+       asm volatile("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
+
+       return ((u64)(edx) << 32) + ((u64)(eax));
+}
+
+static inline void write_xcr0(u64 xcr0)
+{
+       unsigned int eax = xcr0;
+       unsigned int edx = xcr0 >> 32;
+
+       asm volatile("xsetbv" : : "a" (eax), "d" (edx), "c" (0));
+}
+
+static inline void cpuid(unsigned int *eax, unsigned int *ebx,
+                         unsigned int *ecx, unsigned int *edx)
+{
+        /* ecx is often an input as well as an output. */
+        asm volatile("cpuid"
+            : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+            : "0" (*eax), "2" (*ecx)
+            : "memory");
+}
+
+static inline u64 cpuid_edax(unsigned int op, unsigned int sub)
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       eax = op;
+       ecx = sub;
+       cpuid(&eax, &ebx, &ecx, &edx);
+       return ((u64)edx << 32) + (u64)eax;
+}
+
+#define CPUID_REG(reg)                                                   \
+static inline unsigned int cpuid_##reg(unsigned int op, unsigned int sub) \
+{                                                                        \
+       unsigned int eax, ebx, ecx, edx;                                  \
+                                                                         \
+       eax = op;                                                         \
+       ecx = sub;                                                        \
+       cpuid(&eax, &ebx, &ecx, &edx);                                    \
+       return reg;                                                       \
+}
+
+CPUID_REG(eax)
+CPUID_REG(ebx)
+CPUID_REG(ecx)
+CPUID_REG(edx)
+
+#endif /* __ASSEMBLY__ */
diff --git a/inmates/lib/x86/mem.c b/inmates/lib/x86/mem.c
index c6903897..e391f2b0 100644
--- a/inmates/lib/x86/mem.c
+++ b/inmates/lib/x86/mem.c
@@ -37,6 +37,7 @@
  */
 
 #include <inmate.h>
+#include <asm/regs.h>
 
 #define PG_PRESENT     0x01
 #define PG_RW          0x02
@@ -48,7 +49,7 @@ void map_range(void *start, unsigned long size, enum map_type 
map_type)
        unsigned long pt_addr, *pt_entry, *pt;
        unsigned long vaddr = (unsigned long)start;
 
-       asm volatile("mov %%cr3,%0" : "=r" (pt_addr));
+       pt_addr = read_cr3();
 
        size += (vaddr & ~HUGE_PAGE_MASK) + HUGE_PAGE_SIZE - 1;
        size &= HUGE_PAGE_MASK;
-- 
2.22.0

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20190613200442.18984-6-ralf.ramsauer%40oth-regensburg.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to