amd64: Properly size an array for SMP.
[dragonfly.git] / sys / platform / pc64 / amd64 / machdep.c
index ef52ecc..c370a60 100644 (file)
@@ -99,7 +99,6 @@
 #if JG
 #include <machine/bootinfo.h>
 #endif
-#include <machine/intr_machdep.h>      /* for inthand_t */
 #include <machine/md_var.h>
 #include <machine/metadata.h>
 #include <machine/pc/bios.h>
 #include <machine/cputypes.h>
 
 #ifdef OLD_BUS_ARCH
-#include <bus/isa/i386/isa_device.h>
+#include <bus/isa/isa_device.h>
 #endif
 #include <machine_base/isa/intr_machdep.h>
 #include <bus/isa/rtc.h>
@@ -152,15 +151,13 @@ SYSINIT(cpu, SI_BOOT2_SMP, SI_ORDER_FIRST, cpu_startup, NULL)
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
-uint64_t common_lvl4_phys;
-uint64_t common_lvl3_phys;
-uint64_t IdlePTD;
 uint64_t KPTphys;
 uint64_t SMPptpa;
 pt_entry_t *SMPpt;
-pdp_entry_t *link_pdpe;
 
 
+struct privatespace CPU_prvspace[MAXCPU];
+
 int    _udatasel, _ucodesel, _ucode32sel;
 u_long atdevbase;
 #ifdef SMP
@@ -203,13 +200,9 @@ SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD,
 static int
 sysctl_hw_availpages(SYSCTL_HANDLER_ARGS)
 {
-#if JG
        int error = sysctl_handle_int(oidp, 0,
-               i386_btop(avail_end - avail_start), req);
+               amd64_btop(avail_end - avail_start), req);
        return (error);
-#else
-       return -1;
-#endif
 }
 
 SYSCTL_PROC(_hw, OID_AUTO, availpages, CTLTYPE_INT|CTLFLAG_RD,
@@ -415,8 +408,9 @@ again:
        cninit();               /* the preferred console may have changed */
 #endif
 
-       kprintf("avail memory = %u (%uK bytes)\n", ptoa(vmstats.v_free_count),
-           ptoa(vmstats.v_free_count) / 1024);
+       kprintf("avail memory = %lu (%luK bytes)\n",
+               ptoa(vmstats.v_free_count),
+               ptoa(vmstats.v_free_count) / 1024);
 
        /*
         * Set up buffers, so they can be used to read disk labels.
@@ -447,70 +441,82 @@ again:
 void
 sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 {
-       kprintf0("sendsig\n");
        struct lwp *lp = curthread->td_lwp;
        struct proc *p = lp->lwp_proc;
        struct trapframe *regs;
        struct sigacts *psp = p->p_sigacts;
        struct sigframe sf, *sfp;
        int oonstack;
+       char *sp;
 
        regs = lp->lwp_md.md_regs;
        oonstack = (lp->lwp_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
 
-       /* save user context */
+       /* Save user context */
        bzero(&sf, sizeof(struct sigframe));
        sf.sf_uc.uc_sigmask = *mask;
        sf.sf_uc.uc_stack = lp->lwp_sigstk;
        sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
-#if JG
-       bcopy(regs, &sf.sf_uc.uc_mcontext.mc_gs, sizeof(struct trapframe));
-#endif
+       KKASSERT(__offsetof(struct trapframe, tf_rdi) == 0);
+       bcopy(regs, &sf.sf_uc.uc_mcontext.mc_rdi, sizeof(struct trapframe));
 
-       /* make the size of the saved context visible to userland */
+       /* Make the size of the saved context visible to userland */
        sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext);
 
-       /* save mailbox pending state for syscall interlock semantics */
-#if JG
+       /* Save mailbox pending state for syscall interlock semantics */
        if (p->p_flag & P_MAILBOX)
                sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX;
-#endif
 
        /* Allocate and validate space for the signal handler context. */
         if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack &&
            SIGISMEMBER(psp->ps_sigonstack, sig)) {
-               sfp = (struct sigframe *)(lp->lwp_sigstk.ss_sp +
-                   lp->lwp_sigstk.ss_size - sizeof(struct sigframe));
+               sp = (char *)(lp->lwp_sigstk.ss_sp + lp->lwp_sigstk.ss_size -
+                             sizeof(struct sigframe));
                lp->lwp_sigstk.ss_flags |= SS_ONSTACK;
        } else {
-#if JG
-               sfp = (struct sigframe *)regs->tf_esp - 1;
-#endif
+               /* We take red zone into account */
+               sp = (char *)regs->tf_rsp - sizeof(struct sigframe) - 128;
        }
 
+       /* Align to 16 bytes */
+       sfp = (struct sigframe *)((intptr_t)sp & ~0xFUL);
+
        /* Translate the signal is appropriate */
        if (p->p_sysent->sv_sigtbl) {
                if (sig <= p->p_sysent->sv_sigsize)
                        sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
        }
 
-       /* Build the argument list for the signal handler. */
-       sf.sf_signum = sig;
-       sf.sf_ucontext = (register_t)&sfp->sf_uc;
+       /*
+        * Build the argument list for the signal handler.
+        *
+        * Arguments are in registers (%rdi, %rsi, %rdx, %rcx)
+        */
+       regs->tf_rdi = sig;                             /* argument 1 */
+       regs->tf_rdx = (register_t)&sfp->sf_uc;         /* argument 3 */
+
        if (SIGISMEMBER(psp->ps_siginfo, sig)) {
-               /* Signal handler installed with SA_SIGINFO. */
-               sf.sf_siginfo = (register_t)&sfp->sf_si;
+               /*
+                * Signal handler installed with SA_SIGINFO.
+                *
+                * action(signo, siginfo, ucontext)
+                */
+               regs->tf_rsi = (register_t)&sfp->sf_si; /* argument 2 */
+               regs->tf_rcx = (register_t)regs->tf_err; /* argument 4 */
                sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
 
                /* fill siginfo structure */
                sf.sf_si.si_signo = sig;
                sf.sf_si.si_code = code;
-               sf.sf_si.si_addr = (void*)regs->tf_err;
-       }
-       else {
-               /* Old FreeBSD-style arguments. */
-               sf.sf_siginfo = code;
-               sf.sf_addr = regs->tf_err;
+               sf.sf_si.si_addr = (void *)regs->tf_err;
+       } else {
+               /*
+                * Old FreeBSD-style arguments.
+                *
+                * handler (signo, code, [uc], addr)
+                */
+               regs->tf_rsi = (register_t)code;        /* argument 2 */
+               regs->tf_rcx = (register_t)regs->tf_err; /* argument 4 */
                sf.sf_ahu.sf_handler = catcher;
        }
 
@@ -548,9 +554,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
        /*
         * Save the FPU state and reinit the FP unit
         */
-#if JG
        npxpush(&sf.sf_uc.uc_mcontext);
-#endif
 
        /*
         * Copy the sigframe out to the user's stack.
@@ -563,39 +567,21 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
                sigexit(lp, SIGILL);
        }
 
-#if JG
-       regs->tf_esp = (int)sfp;
-       regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
-#endif
+       regs->tf_rsp = (register_t)sfp;
+       regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
 
        /*
         * i386 abi specifies that the direction flag must be cleared
         * on function entry
         */
-#if JG
-       regs->tf_eflags &= ~(PSL_T|PSL_D);
-#endif
-
-       regs->tf_cs = _ucodesel;
-#if JG
-       regs->tf_ds = _udatasel;
-       regs->tf_es = _udatasel;
-#endif
+       regs->tf_rflags &= ~(PSL_T|PSL_D);
 
        /*
-        * Allow the signal handler to inherit %fs in addition to %gs as
-        * the userland program might be using both.
-        *
-        * However, if a T_PROTFLT occured the segment registers could be
-        * totally broken.  They must be reset in order to be able to
-        * return to userland.
+        * 64 bit mode has a code and stack selector but
+        * no data or extra selector.  %fs and %gs are not
+        * stored in-context.
         */
-       if (regs->tf_trapno == T_PROTFLT) {
-#if JG
-               regs->tf_fs = _udatasel;
-               regs->tf_gs = _udatasel;
-#endif
-       }
+       regs->tf_cs = _ucodesel;
        regs->tf_ss = _udatasel;
 }
 
@@ -610,21 +596,12 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 int
 cpu_sanitize_frame(struct trapframe *frame)
 {
-       kprintf0("cpu_sanitize_frame\n");
        frame->tf_cs = _ucodesel;
-#if JG
-       frame->tf_ds = _udatasel;
-       frame->tf_es = _udatasel;       /* XXX allow userland this one too? */
-#endif
-#if 0
-       frame->tf_fs = _udatasel;
-       frame->tf_gs = _udatasel;
-#endif
        frame->tf_ss = _udatasel;
-#if JG
-       frame->tf_eflags &= (PSL_RF | PSL_USERCHANGE);
-       frame->tf_eflags |= PSL_RESERVED_DEFAULT | PSL_I;
-#endif
+       /* XXX VM (8086) mode not supported? */
+       frame->tf_rflags &= (PSL_RF | PSL_USERCHANGE | PSL_VM_UNSUPP);
+       frame->tf_rflags |= PSL_RESERVED_DEFAULT | PSL_I;
+
        return(0);
 }
 
@@ -660,8 +637,8 @@ sys_sigreturn(struct sigreturn_args *uap)
        struct trapframe *regs;
        ucontext_t uc;
        ucontext_t *ucp;
+       register_t rflags;
        int cs;
-       int eflags;
        int error;
 
        /*
@@ -673,9 +650,10 @@ sys_sigreturn(struct sigreturn_args *uap)
        if (error)
                return (error);
        ucp = &uc;
-#if JG
-       eflags = ucp->uc_mcontext.mc_eflags;
-#endif
+       rflags = ucp->uc_mcontext.mc_rflags;
+
+       /* VM (8086) mode not supported */
+       rflags &= ~PSL_VM_UNSUPP;
 
 #if JG
        if (eflags & PSL_VM) {
@@ -697,32 +675,26 @@ sys_sigreturn(struct sigreturn_args *uap)
                        trapsignal(lp, SIGBUS, 0);
 
                if (vm86->vm86_has_vme) {
-#if JG
                        eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
                            (eflags & VME_USERCHANGE) | PSL_VM;
-#endif
                } else {
-#if JG
                        vm86->vm86_eflags = eflags;     /* save VIF, VIP */
                        eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
                            (eflags & VM_USERCHANGE) | PSL_VM;
-#endif
                }
-#if JG
                bcopy(&ucp->uc_mcontext.mc_gs, tf, sizeof(struct trapframe));
                tf->tf_eflags = eflags;
-#endif
                tf->tf_vm86_ds = tf->tf_ds;
                tf->tf_vm86_es = tf->tf_es;
                tf->tf_vm86_fs = tf->tf_fs;
                tf->tf_vm86_gs = tf->tf_gs;
                tf->tf_ds = _udatasel;
                tf->tf_es = _udatasel;
-#if 0
                tf->tf_fs = _udatasel;
                tf->tf_gs = _udatasel;
+       } else
 #endif
-       } else {
+       {
                /*
                 * Don't allow users to change privileged or reserved flags.
                 */
@@ -736,12 +708,10 @@ sys_sigreturn(struct sigreturn_args *uap)
                 * Corruption of the PSL_RF bit at worst causes one more or
                 * one less debugger trap, so allowing it is fairly harmless.
                 */
-#if JG
-               if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
-                       kprintf("sigreturn: eflags = 0x%x\n", eflags);
+               if (!EFL_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
+                       kprintf("sigreturn: rflags = 0x%lx\n", (long)rflags);
                        return(EINVAL);
                }
-#endif
 
                /*
                 * Don't allow users to load a valid privileged %cs.  Let the
@@ -754,27 +724,20 @@ sys_sigreturn(struct sigreturn_args *uap)
                        trapsignal(lp, SIGBUS, T_PROTFLT);
                        return(EINVAL);
                }
-#if JG
-               bcopy(&ucp->uc_mcontext.mc_gs, regs, sizeof(struct trapframe));
-#endif
+               bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(struct trapframe));
        }
-#endif
 
        /*
         * Restore the FPU state from the frame
         */
-#if JG
        npxpop(&ucp->uc_mcontext);
-#endif
 
        /*
         * Merge saved signal mailbox pending flag to maintain interlock
         * semantics against system calls.
         */
-#if JG
        if (ucp->uc_mcontext.mc_xflags & PGEX_MAILBOX)
                p->p_flag |= P_MAILBOX;
-#endif
 
        if (ucp->uc_mcontext.mc_onstack & 1)
                lp->lwp_sigstk.ss_flags |= SS_ONSTACK;
@@ -787,14 +750,14 @@ sys_sigreturn(struct sigreturn_args *uap)
 }
 
 /*
- * Stack frame on entry to function.  %eax will contain the function vector,
- * %ecx will contain the function data.  flags, ecx, and eax will have 
+ * Stack frame on entry to function.  %rax will contain the function vector,
+ * %rcx will contain the function data.  flags, rcx, and rax will have
  * already been pushed on the stack.
  */
 struct upc_frame {
-       register_t      eax;
-       register_t      ecx;
-       register_t      edx;
+       register_t      rax;
+       register_t      rcx;
+       register_t      rdx;
        register_t      flags;
        register_t      oldip;
 };
@@ -863,23 +826,21 @@ sendupcall(struct vmupcall *vu, int morepending)
         * Construct a stack frame and issue the upcall
         */
        regs = lp->lwp_md.md_regs;
-#if JG
-       upc_frame.eax = regs->tf_eax;
-       upc_frame.ecx = regs->tf_ecx;
-       upc_frame.edx = regs->tf_edx;
-       upc_frame.flags = regs->tf_eflags;
-       upc_frame.oldip = regs->tf_eip;
-       if (copyout(&upc_frame, (void *)(regs->tf_esp - sizeof(upc_frame)),
+       upc_frame.rax = regs->tf_rax;
+       upc_frame.rcx = regs->tf_rcx;
+       upc_frame.rdx = regs->tf_rdx;
+       upc_frame.flags = regs->tf_rflags;
+       upc_frame.oldip = regs->tf_rip;
+       if (copyout(&upc_frame, (void *)(regs->tf_rsp - sizeof(upc_frame)),
            sizeof(upc_frame)) != 0) {
                kprintf("bad stack on upcall\n");
        } else {
-               regs->tf_eax = (register_t)vu->vu_func;
-               regs->tf_ecx = (register_t)vu->vu_data;
-               regs->tf_edx = (register_t)lp->lwp_upcall;
-               regs->tf_eip = (register_t)vu->vu_ctx;
-               regs->tf_esp -= sizeof(upc_frame);
+               regs->tf_rax = (register_t)vu->vu_func;
+               regs->tf_rcx = (register_t)vu->vu_data;
+               regs->tf_rdx = (register_t)lp->lwp_upcall;
+               regs->tf_rip = (register_t)vu->vu_ctx;
+               regs->tf_rsp -= sizeof(upc_frame);
        }
-#endif
 }
 
 /*
@@ -916,27 +877,23 @@ fetchupcall(struct vmupcall *vu, int morepending, void *rsp)
                crit_count += TDPRI_CRIT;
                if (error == 0)
                        error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int));
-#if JG
-               regs->tf_eax = (register_t)vu->vu_func;
-               regs->tf_ecx = (register_t)vu->vu_data;
-               regs->tf_edx = (register_t)lp->lwp_upcall;
-               regs->tf_eip = (register_t)vu->vu_ctx;
-               regs->tf_esp = (register_t)rsp;
-#endif
+               regs->tf_rax = (register_t)vu->vu_func;
+               regs->tf_rcx = (register_t)vu->vu_data;
+               regs->tf_rdx = (register_t)lp->lwp_upcall;
+               regs->tf_rip = (register_t)vu->vu_ctx;
+               regs->tf_rsp = (register_t)rsp;
            } else {
                /*
                 * This returns us to the originally interrupted code.
                 */
                error = copyin(rsp, &upc_frame, sizeof(upc_frame));
-#if JG
-               regs->tf_eax = upc_frame.eax;
-               regs->tf_ecx = upc_frame.ecx;
-               regs->tf_edx = upc_frame.edx;
-               regs->tf_eflags = (regs->tf_eflags & ~PSL_USERCHANGE) |
+               regs->tf_rax = upc_frame.rax;
+               regs->tf_rcx = upc_frame.rcx;
+               regs->tf_rdx = upc_frame.rdx;
+               regs->tf_rflags = (regs->tf_rflags & ~PSL_USERCHANGE) |
                                (upc_frame.flags & PSL_USERCHANGE);
-               regs->tf_eip = upc_frame.oldip;
-               regs->tf_esp = (register_t)((char *)rsp + sizeof(upc_frame));
-#endif
+               regs->tf_rip = upc_frame.oldip;
+               regs->tf_rsp = (register_t)((char *)rsp + sizeof(upc_frame));
            }
        }
        if (error == 0)
@@ -1078,8 +1035,6 @@ exec_setregs(u_long entry, u_long stack, u_long ps_strings)
        struct pcb *pcb = td->td_pcb;
        struct trapframe *regs = lp->lwp_md.md_regs;
 
-       kprintf0("exec_setregs\n");
-
        /* was i386_user_cleanup() in NetBSD */
        user_ldt_free(pcb);
   
@@ -1121,22 +1076,27 @@ exec_setregs(u_long entry, u_long stack, u_long ps_strings)
         * traps to the emulator (if it is done at all) mainly because
         * emulators don't provide an entry point for initialization.
         */
-#if JG
        pcb->pcb_flags &= ~FP_SOFTFP;
-#endif
 
        /*
-        * note: do not set CR0_TS here.  npxinit() must do it after clearing
-        * gd_npxthread.  Otherwise a preemptive interrupt thread may panic
-        * in npxdna().
+        * NOTE: do not set CR0_TS here.  npxinit() must do it after clearing
+        *       gd_npxthread.  Otherwise a preemptive interrupt thread
+        *       may panic in npxdna().
         */
        crit_enter();
        load_cr0(rcr0() | CR0_MP);
 
-       wrmsr(MSR_FSBASE, 0);
-       wrmsr(MSR_KGSBASE, 0);  /* User value while we're in the kernel */
-       pcb->pcb_fsbase = 0;
+       /*
+        * NOTE: The MSR values must be correct so we can return to
+        *       userland.  gd_user_fs/gs must be correct so the switch
+        *       code knows what the current MSR values are.
+        */
+       pcb->pcb_fsbase = 0;    /* Values loaded from PCB on switch */
        pcb->pcb_gsbase = 0;
+       mdcpu->gd_user_fs = 0;  /* Cache of current MSR values */
+       mdcpu->gd_user_gs = 0;
+       wrmsr(MSR_FSBASE, 0);   /* Set MSR values for return to userland */
+       wrmsr(MSR_KGSBASE, 0);
 
 #if NNPX > 0
        /* Initialize the npx (if any) for the current process. */
@@ -1480,6 +1440,9 @@ getmemsize(caddr_t kmdp, u_int64_t first)
 #ifdef SMP
        /* make hole for AP bootstrap code */
        physmap[1] = mp_bootaddress(physmap[1] / 1024);
+
+       /* look for the MP hardware - needed for apic addresses */
+       mp_probe();
 #endif
 
        /*
@@ -1509,7 +1472,7 @@ getmemsize(caddr_t kmdp, u_int64_t first)
                kprintf("Physical memory use set to %ldK\n", Maxmem * 4);
 
        /* call pmap initialization to make new kernel address space */
-       pmap_bootstrap(&first, 0);
+       pmap_bootstrap(&first);
 
        /*
         * Size up each available chunk of physical memory.
@@ -1665,6 +1628,8 @@ do_next:
        /* Trim off space for the message buffer. */
        phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
 
+       avail_end = phys_avail[pa_indx];
+
        /* Map the message buffer. */
        for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
                pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
@@ -1700,16 +1665,21 @@ u_int64_t
 hammer_time(u_int64_t modulep, u_int64_t physfree)
 {
        caddr_t kmdp;
-       int gsel_tss, metadata_missing, off, x;
+       int gsel_tss, x;
+#if JG
+       int metadata_missing, off;
+#endif
        struct mdglobaldata *gd;
        u_int64_t msr;
        char *env;
 
+#if JG
        /*
         * This must be done before the first references
         * to CPU_prvspace[0] are made.
         */
        init_paging(&physfree);
+#endif
 
        /*
         * Prevent lowering of the ipl if we call tsleep() early.
@@ -1776,6 +1746,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
        }
        ssdtosyssd(&gdt_segs[GPROC0_SEL],
            (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
+
        r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
        r_gdt.rd_base =  (long) gdt;
        lgdt(&r_gdt);
@@ -1850,8 +1821,9 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
        initializecpu();        /* Initialize CPU registers */
 
        /* make an initial tss so cpu can get interrupt stack on syscall! */
-       gd->gd_common_tss.tss_rsp0 = thread0.td_kstack + \
-           KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb);
+       gd->gd_common_tss.tss_rsp0 =
+               (register_t)(thread0.td_kstack +
+                            KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb));
        /* Ensure the stack is aligned to 16 bytes */
        gd->gd_common_tss.tss_rsp0 &= ~0xFul;
        gd->gd_rsp0 = gd->gd_common_tss.tss_rsp0;
@@ -1903,11 +1875,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 
        /* setup proc 0's pcb */
        thread0.td_pcb->pcb_flags = 0;
-#if JG
        thread0.td_pcb->pcb_cr3 = KPML4phys;
-#else
-       thread0.td_pcb->pcb_cr3 = IdlePTD;
-#endif
        thread0.td_pcb->pcb_ext = 0;
        lwp0.lwp_md.md_regs = &proc0_tf;
         env = kgetenv("kernelname");
@@ -1998,18 +1966,14 @@ f00f_hack(void *unused)
 int
 ptrace_set_pc(struct lwp *lp, unsigned long addr)
 {
-#if JG
-       lp->lwp_md.md_regs->tf_eip = addr;
-#endif
+       lp->lwp_md.md_regs->tf_rip = addr;
        return (0);
 }
 
 int
 ptrace_single_step(struct lwp *lp)
 {
-#if JG
-       lp->lwp_md.md_regs->tf_eflags |= PSL_T;
-#endif
+       lp->lwp_md.md_regs->tf_rflags |= PSL_T;
        return (0);
 }
 
@@ -2020,26 +1984,8 @@ fill_regs(struct lwp *lp, struct reg *regs)
        struct trapframe *tp;
 
        tp = lp->lwp_md.md_regs;
-#if JG
-       regs->r_gs = tp->tf_gs;
-       regs->r_fs = tp->tf_fs;
-       regs->r_es = tp->tf_es;
-       regs->r_ds = tp->tf_ds;
-       regs->r_edi = tp->tf_edi;
-       regs->r_esi = tp->tf_esi;
-       regs->r_ebp = tp->tf_ebp;
-       regs->r_ebx = tp->tf_ebx;
-       regs->r_edx = tp->tf_edx;
-       regs->r_ecx = tp->tf_ecx;
-       regs->r_eax = tp->tf_eax;
-       regs->r_eip = tp->tf_eip;
-#endif
-       regs->r_cs = tp->tf_cs;
-#if JG
-       regs->r_eflags = tp->tf_eflags;
-       regs->r_esp = tp->tf_esp;
-#endif
-       regs->r_ss = tp->tf_ss;
+       bcopy(&tp->tf_rdi, &regs->r_rdi, sizeof(*regs));
+
        pcb = lp->lwp_thread->td_pcb;
        return (0);
 }
@@ -2051,29 +1997,10 @@ set_regs(struct lwp *lp, struct reg *regs)
        struct trapframe *tp;
 
        tp = lp->lwp_md.md_regs;
-#if JG
-       if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
+       if (!EFL_SECURE(regs->r_rflags, tp->tf_rflags) ||
            !CS_SECURE(regs->r_cs))
                return (EINVAL);
-       tp->tf_gs = regs->r_gs;
-       tp->tf_fs = regs->r_fs;
-       tp->tf_es = regs->r_es;
-       tp->tf_ds = regs->r_ds;
-       tp->tf_edi = regs->r_edi;
-       tp->tf_esi = regs->r_esi;
-       tp->tf_ebp = regs->r_ebp;
-       tp->tf_ebx = regs->r_ebx;
-       tp->tf_edx = regs->r_edx;
-       tp->tf_ecx = regs->r_ecx;
-       tp->tf_eax = regs->r_eax;
-       tp->tf_eip = regs->r_eip;
-#endif
-       tp->tf_cs = regs->r_cs;
-#if JG
-       tp->tf_eflags = regs->r_eflags;
-       tp->tf_esp = regs->r_esp;
-#endif
-       tp->tf_ss = regs->r_ss;
+       bcopy(&regs->r_rdi, &tp->tf_rdi, sizeof(*regs));
        pcb = lp->lwp_thread->td_pcb;
        return (0);
 }