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.
