unsigned int edx;
        unsigned int esi;
        unsigned int edi;
-} __packed;
+};
 
 static const char * const temp_labels[] = {
        "CPU",
        struct smm_regs *regs = par;
        int eax = regs->eax;
        int ebx = regs->ebx;
+       unsigned char carry;
        long long duration;
-       int rc;
 
        /* SMM requires CPU 0 */
        if (smp_processor_id() != 0)
                return -EBUSY;
 
-#if defined(CONFIG_X86_64)
-       asm volatile("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"
-               "pushfq\n\t"
-               "popq %%rax\n\t"
-               "andl $1,%%eax\n"
-               : "=a"(rc)
-               :    "a"(regs)
-               :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
-#else
-       asm volatile("pushl %%eax\n\t"
-           "movl 0(%%eax),%%edx\n\t"
-           "push %%edx\n\t"
-           "movl 4(%%eax),%%ebx\n\t"
-           "movl 8(%%eax),%%ecx\n\t"
-           "movl 12(%%eax),%%edx\n\t"
-           "movl 16(%%eax),%%esi\n\t"
-           "movl 20(%%eax),%%edi\n\t"
-           "popl %%eax\n\t"
-           "out %%al,$0xb2\n\t"
-           "out %%al,$0x84\n\t"
-           "xchgl %%eax,(%%esp)\n\t"
-           "movl %%ebx,4(%%eax)\n\t"
-           "movl %%ecx,8(%%eax)\n\t"
-           "movl %%edx,12(%%eax)\n\t"
-           "movl %%esi,16(%%eax)\n\t"
-           "movl %%edi,20(%%eax)\n\t"
-           "popl %%edx\n\t"
-           "movl %%edx,0(%%eax)\n\t"
-           "lahf\n\t"
-           "shrl $8,%%eax\n\t"
-           "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)
-               rc = -EINVAL;
+       asm volatile("out %%al,$0xb2\n\t"
+                    "out %%al,$0x84\n\t"
+                    "setc %0\n"
+                    : "=mr" (carry),
+                      "+a" (regs->eax),
+                      "+b" (regs->ebx),
+                      "+c" (regs->ecx),
+                      "+d" (regs->edx),
+                      "+S" (regs->esi),
+                      "+D" (regs->edi));
 
        duration = ktime_us_delta(ktime_get(), calltime);
-       pr_debug("smm(0x%.4x 0x%.4x) = 0x%.4x  (took %7lld usecs)\n", eax, ebx,
-                (rc ? 0xffff : regs->eax & 0xffff), duration);
+       pr_debug("smm(0x%.4x 0x%.4x) = 0x%.4x carry: %d (took %7lld usecs)\n",
+                eax, ebx, regs->eax & 0xffff, carry, duration);
 
        if (duration > DELL_SMM_MAX_DURATION)
                pr_warn_once("SMM call took %lld usecs!\n", duration);
 
-       return rc;
+       if (carry || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
+               return -EINVAL;
+
+       return 0;
 }
 
 /*