kernel/x86_64: Use VZEROALL to clear XMM/YMM/etc. registers when available.
It comes with AVX, so enable it if we've enabled AVX. This also adjusts altcodepatch_replace to explicitly set NOPs for the remainder of the patch area. Change-Id: Ia07549851d86836ff5428635b580c751b4e5b2a3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10867 Reviewed-by: waddlesplash <[email protected]> Reviewed-by: Jérôme Duval <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
009b56e781
commit
facff75dd4
@@ -24,6 +24,7 @@
|
||||
#define ALTCODEPATCH_TAG_CLAC 2
|
||||
#define ALTCODEPATCH_TAG_XSAVE 3
|
||||
#define ALTCODEPATCH_TAG_XRSTOR 4
|
||||
#define ALTCODEPATCH_TAG_CLEAR_FPU 5
|
||||
|
||||
|
||||
#ifdef _ASSEMBLER
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
1:
|
||||
|
||||
#define CLEAR_FPU_STATE() \
|
||||
CODEPATCH_START \
|
||||
pxor %xmm0, %xmm0; \
|
||||
pxor %xmm1, %xmm1; \
|
||||
pxor %xmm2, %xmm2; \
|
||||
@@ -133,7 +134,8 @@
|
||||
pxor %xmm12, %xmm12; \
|
||||
pxor %xmm13, %xmm13; \
|
||||
pxor %xmm14, %xmm14; \
|
||||
pxor %xmm15, %xmm15
|
||||
pxor %xmm15, %xmm15; \
|
||||
CODEPATCH_END(ALTCODEPATCH_TAG_CLEAR_FPU)
|
||||
|
||||
// The following code defines the interrupt service routines for all 256
|
||||
// interrupts. It creates a block of handlers, each 16 bytes, that the IDT
|
||||
|
||||
@@ -28,3 +28,7 @@ FUNCTION_END(_xsavec)
|
||||
FUNCTION(_xrstor):
|
||||
xrstor64 (%rdi)
|
||||
FUNCTION_END(_xrstor)
|
||||
|
||||
FUNCTION(_vzeroall):
|
||||
vzeroall
|
||||
FUNCTION_END(_vzeroall)
|
||||
|
||||
@@ -45,7 +45,9 @@ arch_altcodepatch_replace(uint16 tag, void* newcodepatch, size_t length)
|
||||
void* address = (void*)(KERNEL_LOAD_BASE + patch->kernel_offset);
|
||||
if (patch->length < length)
|
||||
panic("can't copy patch: new code is too long\n");
|
||||
|
||||
memcpy(address, newcodepatch, length);
|
||||
memset((uint8*)address + length, 0x90 /* nop */, patch->length - length);
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ extern addr_t _clac;
|
||||
extern addr_t _xsave;
|
||||
extern addr_t _xsavec;
|
||||
extern addr_t _xrstor;
|
||||
extern addr_t _vzeroall;
|
||||
uint64 gXsaveMask;
|
||||
uint64 gFPUSaveLength = 512;
|
||||
bool gHasXsave = false;
|
||||
@@ -1944,6 +1945,9 @@ arch_cpu_init_post_vm(kernel_args* args)
|
||||
arch_altcodepatch_replace(ALTCODEPATCH_TAG_XRSTOR,
|
||||
&_xrstor, 4);
|
||||
|
||||
if ((gXsaveMask & IA32_XCR0_AVX) != 0)
|
||||
arch_altcodepatch_replace(ALTCODEPATCH_TAG_CLEAR_FPU, &_vzeroall, 3);
|
||||
|
||||
dprintf("enable %s 0x%" B_PRIx64 " %" B_PRId64 "\n",
|
||||
gHasXsavec ? "XSAVEC" : "XSAVE", gXsaveMask, gFPUSaveLength);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user