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

Partly copied over from the hypervisor and added cpuid_edax helper,
which combines edx:eax to a 64 bit uint.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 inmates/lib/x86/include/asm/regs.h | 72 ++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/inmates/lib/x86/include/asm/regs.h 
b/inmates/lib/x86/include/asm/regs.h
index a004fdd2..85da043b 100644
--- a/inmates/lib/x86/include/asm/regs.h
+++ b/inmates/lib/x86/include/asm/regs.h
@@ -48,3 +48,75 @@
 
 #define MSR_MTRR_DEF_TYPE      0x000002ff
 #define MTRR_ENABLE            0x00000800
+
+#ifndef __ASSEMBLY__
+
+static unsigned long __force_order;
+
+static inline unsigned long read_cr4(void)
+{
+       unsigned long cr4;
+       asm volatile("mov %%cr4,%0" : "=r" (cr4), "=m" (__force_order));
+
+       return cr4;
+}
+
+static inline void write_cr4(unsigned long val)
+{
+       asm volatile("mov %0,%%cr4" : : "r" (val), "m" (__force_order));
+}
+
+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__ */
-- 
2.21.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/20190521143423.17734-4-ralf.ramsauer%40oth-regensburg.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to