support AVX-512 registers
This commit is contained in:
@ -182,6 +182,7 @@ static void init_idt(void)
|
|||||||
|
|
||||||
static int xsave_available = 0;
|
static int xsave_available = 0;
|
||||||
static int xsave_size = 0;
|
static int xsave_size = 0;
|
||||||
|
static uint64_t xsave_mask = 0x0;
|
||||||
|
|
||||||
void init_fpu(void)
|
void init_fpu(void)
|
||||||
{
|
{
|
||||||
@ -232,8 +233,20 @@ void init_fpu(void)
|
|||||||
unsigned long edx;
|
unsigned long edx;
|
||||||
asm volatile("cpuid" : "=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx) : "a" (0x0d), "c" (0x00));
|
asm volatile("cpuid" : "=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx) : "a" (0x0d), "c" (0x00));
|
||||||
xsave_size = ecx;
|
xsave_size = ecx;
|
||||||
|
dkprintf("init_fpu(): xsave_size = %d\n", xsave_size);
|
||||||
|
|
||||||
|
if ((eax & (1 << 5)) && (eax & (1 << 6)) && (eax & (1 << 7))) {
|
||||||
|
/* Set xcr0[7:5] to enable avx-512 ops */
|
||||||
|
reg = xgetbv(0);
|
||||||
|
reg |= 0xe6;
|
||||||
|
xsetbv(0, reg);
|
||||||
|
dkprintf("init_fpu(): AVX-512 init: XCR0 = 0x%016lX\n", reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xsave_mask = xgetbv(0);
|
||||||
|
dkprintf("init_fpu(): xsave_mask = 0x%016lX\n", xsave_mask);
|
||||||
|
|
||||||
/* TODO: set MSR_IA32_XSS to enable xsaves/xrstors */
|
/* TODO: set MSR_IA32_XSS to enable xsaves/xrstors */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -249,6 +262,11 @@ get_xsave_size()
|
|||||||
return xsave_size;
|
return xsave_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t get_xsave_mask()
|
||||||
|
{
|
||||||
|
return xsave_mask;
|
||||||
|
}
|
||||||
|
|
||||||
void reload_gdt(struct x86_desc_ptr *gdt_ptr)
|
void reload_gdt(struct x86_desc_ptr *gdt_ptr)
|
||||||
{
|
{
|
||||||
asm volatile("pushq %1\n"
|
asm volatile("pushq %1\n"
|
||||||
@ -1532,7 +1550,8 @@ release_fp_regs(struct thread *thread)
|
|||||||
if (thread && !thread->fp_regs)
|
if (thread && !thread->fp_regs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pages = (sizeof(fp_regs_struct) + 4095) >> 12;
|
pages = (xsave_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
||||||
|
dkprintf("release_fp_regs: pages=%d\n", pages);
|
||||||
ihk_mc_free_pages(thread->fp_regs, pages);
|
ihk_mc_free_pages(thread->fp_regs, pages);
|
||||||
thread->fp_regs = NULL;
|
thread->fp_regs = NULL;
|
||||||
}
|
}
|
||||||
@ -1546,7 +1565,8 @@ save_fp_regs(struct thread *thread)
|
|||||||
int pages;
|
int pages;
|
||||||
|
|
||||||
if (!thread->fp_regs) {
|
if (!thread->fp_regs) {
|
||||||
pages = (sizeof(fp_regs_struct) + 4095) >> 12;
|
pages = (xsave_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
||||||
|
dkprintf("save_fp_regs: pages=%d\n", pages);
|
||||||
thread->fp_regs = ihk_mc_alloc_pages(pages, IHK_MC_AP_NOWAIT);
|
thread->fp_regs = ihk_mc_alloc_pages(pages, IHK_MC_AP_NOWAIT);
|
||||||
|
|
||||||
if (!thread->fp_regs) {
|
if (!thread->fp_regs) {
|
||||||
@ -1555,14 +1575,15 @@ save_fp_regs(struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(thread->fp_regs, 0, sizeof(fp_regs_struct));
|
memset(thread->fp_regs, 0, sizeof(fp_regs_struct));
|
||||||
|
memset(thread->fp_regs, 0, pages * PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xsave_available) {
|
if (xsave_available) {
|
||||||
unsigned int low, high;
|
unsigned int low, high;
|
||||||
|
|
||||||
/* Request full save of x87, SSE and AVX states */
|
/* Request full save of x87, SSE, AVX and AVX-512 states */
|
||||||
low = 0x7;
|
low = (unsigned int)xsave_mask;
|
||||||
high = 0;
|
high = (unsigned int)(xsave_mask >> 32);
|
||||||
|
|
||||||
asm volatile("xsave %0" : : "m" (*thread->fp_regs), "a" (low), "d" (high)
|
asm volatile("xsave %0" : : "m" (*thread->fp_regs), "a" (low), "d" (high)
|
||||||
: "memory");
|
: "memory");
|
||||||
@ -1584,9 +1605,9 @@ restore_fp_regs(struct thread *thread)
|
|||||||
if (xsave_available) {
|
if (xsave_available) {
|
||||||
unsigned int low, high;
|
unsigned int low, high;
|
||||||
|
|
||||||
/* Request full restore of x87, SSE and AVX states */
|
/* Request full restore of x87, SSE, AVX and AVX-512 states */
|
||||||
low = 0x7;
|
low = (unsigned int)xsave_mask;
|
||||||
high = 0;
|
high = (unsigned int)(xsave_mask >> 32);
|
||||||
|
|
||||||
asm volatile("xrstor %0" : : "m" (*thread->fp_regs),
|
asm volatile("xrstor %0" : : "m" (*thread->fp_regs),
|
||||||
"a" (low), "d" (high));
|
"a" (low), "d" (high));
|
||||||
|
|||||||
@ -39,6 +39,7 @@ void check_signal(unsigned long rc, void *regs0, int num);
|
|||||||
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long, unsigned long);
|
unsigned long, unsigned long, unsigned long);
|
||||||
extern int get_xsave_size();
|
extern int get_xsave_size();
|
||||||
|
extern uint64_t get_xsave_mask();
|
||||||
|
|
||||||
//#define DEBUG_PRINT_SC
|
//#define DEBUG_PRINT_SC
|
||||||
|
|
||||||
@ -273,8 +274,9 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
void *fpregs = kmalloc(xsavesize + 64, IHK_MC_AP_NOWAIT);
|
void *fpregs = kmalloc(xsavesize + 64, IHK_MC_AP_NOWAIT);
|
||||||
|
|
||||||
if(fpregs){
|
if(fpregs){
|
||||||
unsigned int low = 0x7;
|
uint64_t xsave_mask = get_xsave_mask();
|
||||||
unsigned int high = 0;
|
unsigned int low = (unsigned int)xsave_mask;
|
||||||
|
unsigned int high = (unsigned int)(xsave_mask >> 32);
|
||||||
struct xsave_struct *kfpregs;
|
struct xsave_struct *kfpregs;
|
||||||
|
|
||||||
kfpregs = (void *)((((unsigned long)fpregs) + 63) & ~63);
|
kfpregs = (void *)((((unsigned long)fpregs) + 63) & ~63);
|
||||||
@ -776,8 +778,9 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
if(num != 0 && rc == -EINTR && sig == SIGCHLD)
|
if(num != 0 && rc == -EINTR && sig == SIGCHLD)
|
||||||
ksigsp.restart = 1;
|
ksigsp.restart = 1;
|
||||||
if(xsavesize){
|
if(xsavesize){
|
||||||
unsigned int low = 0x7;
|
uint64_t xsave_mask = get_xsave_mask();
|
||||||
unsigned int high = 0;
|
unsigned int low = (unsigned int)xsave_mask;
|
||||||
|
unsigned int high = (unsigned int)(xsave_mask >> 32);
|
||||||
void *_kfpregs = kmalloc(xsavesize + 64, IHK_MC_AP_NOWAIT);
|
void *_kfpregs = kmalloc(xsavesize + 64, IHK_MC_AP_NOWAIT);
|
||||||
struct xsave_struct *kfpregs;
|
struct xsave_struct *kfpregs;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user