|
@@ -113,6 +113,33 @@ static int i8k_smm(struct smm_regs *regs)
|
|
|
int rc;
|
|
|
int eax = regs->eax;
|
|
|
|
|
|
+#if defined(CONFIG_X86_64)
|
|
|
+ asm("pushq %%rax\n\t"
|
|
|
+ "movl 0(%%rax),%%edx\n\t"
|
|
|
+ "pushq %%rdx\n\t"
|
|
|
+ "movl 4(%%rax),%%ebx\n\t"
|
|
|
+ "movl 8(%%rax),%%ecx\n\t"
|
|
|
+ "movl 12(%%rax),%%edx\n\t"
|
|
|
+ "movl 16(%%rax),%%esi\n\t"
|
|
|
+ "movl 20(%%rax),%%edi\n\t"
|
|
|
+ "popq %%rax\n\t"
|
|
|
+ "out %%al,$0xb2\n\t"
|
|
|
+ "out %%al,$0x84\n\t"
|
|
|
+ "xchgq %%rax,(%%rsp)\n\t"
|
|
|
+ "movl %%ebx,4(%%rax)\n\t"
|
|
|
+ "movl %%ecx,8(%%rax)\n\t"
|
|
|
+ "movl %%edx,12(%%rax)\n\t"
|
|
|
+ "movl %%esi,16(%%rax)\n\t"
|
|
|
+ "movl %%edi,20(%%rax)\n\t"
|
|
|
+ "popq %%rdx\n\t"
|
|
|
+ "movl %%edx,0(%%rax)\n\t"
|
|
|
+ "lahf\n\t"
|
|
|
+ "shrl $8,%%eax\n\t"
|
|
|
+ "andl $1,%%eax\n"
|
|
|
+ :"=a"(rc)
|
|
|
+ : "a"(regs)
|
|
|
+ : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
|
|
|
+#else
|
|
|
asm("pushl %%eax\n\t"
|
|
|
"movl 0(%%eax),%%edx\n\t"
|
|
|
"push %%edx\n\t"
|
|
@@ -137,7 +164,7 @@ static int i8k_smm(struct smm_regs *regs)
|
|
|
"andl $1,%%eax\n":"=a"(rc)
|
|
|
: "a"(regs)
|
|
|
: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
|
|
|
-
|
|
|
+#endif
|
|
|
if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
|
|
|
return -EINVAL;
|
|
|
|