AMD64 - Make signals operational, fix reg mappings, fix %fs management, trace
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 2 Apr 2009 00:57:01 +0000 (17:57 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 2 Apr 2009 00:57:01 +0000 (17:57 -0700)
Adjust sigframe, trapframe, mcontext, ucontext, and regs.  Add tf_xflags
too all structures.  Reorder struct regs to match the register layout
in the other structures.

Implement the commented out signaling code.  Signals now work, or at least
do not crash programs.  Theoretically the FP state is also saved and restored.

The exec() code failed to adjust gd_user_fs and gd_user_gs when setting
the msr registers for the user %fs and %gs, causing %fs to unexpectedly
change in running user programs.

Implement trace/debug support functions to set %rip and to single-step.

Define the missing vkernel flag FP_SOFTFP.

16 files changed:
sys/cpu/amd64/include/asmacros.h
sys/cpu/amd64/include/frame.h
sys/cpu/amd64/include/pmap.h
sys/cpu/amd64/include/psl.h
sys/cpu/amd64/include/reg.h
sys/cpu/amd64/include/signal.h
sys/cpu/amd64/include/ucontext.h
sys/platform/pc64/amd64/exception.S
sys/platform/pc64/amd64/genassym.c
sys/platform/pc64/amd64/ipl.s
sys/platform/pc64/amd64/machdep.c
sys/platform/pc64/amd64/support.s
sys/platform/pc64/amd64/swtch.s
sys/platform/pc64/amd64/trap.c
sys/platform/pc64/icu/icu_vector.s
sys/platform/pc64/include/pcb.h

index 3f5ec08..d012719 100644 (file)
        jz      1f ;            /* keep kernel GS.base */               \
        cli ;                                                           \
        swapgs ;                                                        \
-1:     addq    $TF_RIP,%rsp    /* skip over tf_err, tf_trapno */
+1:     addq    $TF_RIP,%rsp    /* skip over tf_err, tf_trapno, tf_xflags */
 
 /*
  * Access per-CPU data.
index ee389dd..59cfd00 100644 (file)
@@ -58,9 +58,7 @@
  */
 
 struct trapframe {
-       /* fs XXX */
-       /* es XXX */
-       /* ds XXX */
+       /* note: tf_rdi matches mc_rdi in mcontext */
        register_t      tf_rdi;
        register_t      tf_rsi;
        register_t      tf_rdx;
@@ -76,6 +74,7 @@ struct trapframe {
        register_t      tf_r13;
        register_t      tf_r14;
        register_t      tf_r15;
+       register_t      tf_xflags;
        register_t      tf_trapno;
        register_t      tf_addr;
        register_t      tf_flags;
index cbed116..5c5d0b8 100644 (file)
 #define PGEX_RSV       0x08    /* reserved PTE field is non-zero */
 #define PGEX_I         0x10    /* during an instruction fetch */
 
+/*
+ * Virtual kernel bits, managed by software.  Stored in tf_xflags.
+ *
+ * PGEX_FPFAULT - Force the FP unit to generate a T_DNA fault if an
+ *               emulated user process tried to use it.  This bit is
+ *               only used by vmspace_ctl().
+ *
+ * PGEX_MAILBOX - Set in xflags by signal code to indicate that a mailbox
+ *               signal was pending.  Remerged on signal return.  This
+ *               bit is only used in a signal vector frame.
+ */
+#define PGEX_MAILBOX   0x40
+#define PGEX_FPFAULT   0x80
+
 #endif /* !_CPU_PMAP_H_ */
index eaacaea..7fddf84 100644 (file)
@@ -56,7 +56,7 @@
 #define        PSL_IOPL        0x00003000      /* i/o privilege level */
 #define        PSL_NT          0x00004000      /* nested task bit */
 #define        PSL_RF          0x00010000      /* resume flag bit */
-/* #define PSL_VM              0x00020000 */   /* virtual 8086 mode bit */
+#define PSL_VM_UNSUPP  0x00020000      /* virtual 8086 mode bit */
 #define        PSL_AC          0x00040000      /* alignment checking */
 /* #define PSL_VIF     0x00080000 */   /* virtual interrupt enable */
 /* #define PSL_VIP     0x00100000 */   /* virtual interrupt pending */
index 58ad151..1289d4a 100644 (file)
  * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
  */
 struct reg {
-       register_t      r_r15;
-       register_t      r_r14;
-       register_t      r_r13;
-       register_t      r_r12;
-       register_t      r_r11;
-       register_t      r_r10;
-       register_t      r_r9;
-       register_t      r_r8;
        register_t      r_rdi;
        register_t      r_rsi;
-       register_t      r_rbp;
-       register_t      r_rbx;
        register_t      r_rdx;
        register_t      r_rcx;
+       register_t      r_r8;
+       register_t      r_r9;
        register_t      r_rax;
+       register_t      r_rbx;
+       register_t      r_rbp;
+       register_t      r_r10;
+       register_t      r_r11;
+       register_t      r_r12;
+       register_t      r_r13;
+       register_t      r_r14;
+       register_t      r_r15;
+       register_t      r_xflags;
        register_t      r_trapno;
+       register_t      r_addr;
+       register_t      r_flags;
        register_t      r_err;
        register_t      r_rip;
        register_t      r_cs;
index 5dbc973..8cdad1e 100644 (file)
@@ -132,6 +132,7 @@ struct      sigcontext {
        long            sc_r13;
        long            sc_r14;
        long            sc_r15;
+       long            sc_xflags;
        long            sc_trapno;
        long            sc_addr;
        long            sc_flags;
index b53c769..396dd62 100644 (file)
@@ -39,6 +39,9 @@ typedef struct __mcontext {
         * The first 20 fields must match the definition of
         * sigcontext. So that we can support sigcontext
         * and ucontext_t at the same time.
+        *
+        * NOTE: bcopy in sendsig copies trapframe to this
+        * structure as of mc_rdi.
         */
        __register_t    mc_onstack;     /* XXX - sigcontext compat. */
        __register_t    mc_rdi;
@@ -56,6 +59,7 @@ typedef struct __mcontext {
        __register_t    mc_r13;
        __register_t    mc_r14;
        __register_t    mc_r15;
+       __register_t    mc_xflags;
        __register_t    mc_trapno;
        __register_t    mc_addr;
        __register_t    mc_flags;
index ae9c540..e469fec 100644 (file)
@@ -84,6 +84,7 @@ MCOUNT_LABEL(btrap)
 /* Traps that we leave interrupts disabled for.. */
 #define        TRAP_NOEN(a)    \
        subq $TF_RIP,%rsp; \
+       movq $0,TF_XFLAGS(%rsp) ; \
        movq $(a),TF_TRAPNO(%rsp) ; \
        movq $0,TF_ADDR(%rsp) ; \
        movq $0,TF_ERR(%rsp) ; \
@@ -96,6 +97,7 @@ IDTVEC(bpt)
 /* Regular traps; The cpu does not supply tf_err for these. */
 #define        TRAP(a)  \
        subq $TF_RIP,%rsp; \
+       movq $0,TF_XFLAGS(%rsp) ; \
        movq $(a),TF_TRAPNO(%rsp) ; \
        movq $0,TF_ADDR(%rsp) ; \
        movq $0,TF_ERR(%rsp) ; \
@@ -463,9 +465,6 @@ pmsg4:  .asciz      "fork_trampoline mpcount %d after calling %p"
         *
         * trapframe is at the top of the stack.
         */
-#if JG
-       pushl   $0                      /* cpl to restore */
-#endif
        MEXITCOUNT
        jmp     doreti
 
index df64c12..64cb85e 100644 (file)
@@ -150,6 +150,7 @@ ASSYM(TF_RCX, offsetof(struct trapframe, tf_rcx));
 ASSYM(TF_RAX, offsetof(struct trapframe, tf_rax));
 
 ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno));
+ASSYM(TF_XFLAGS, offsetof(struct trapframe, tf_xflags));
 ASSYM(TF_ADDR, offsetof(struct trapframe, tf_addr));
 ASSYM(TF_ERR, offsetof(struct trapframe, tf_err));
 ASSYM(TF_FLAGS, offsetof(struct trapframe, tf_flags));
index d5ac7b4..d63fcaa 100644 (file)
@@ -505,6 +505,7 @@ splz_ipiq:
        pushq   %rax ;                  /* phys int frame / cs */       \
        pushq   3*8(%rsp) ;             /* original caller eip */       \
        subq    $TF_RIP,%rsp ;          /* trap frame */                \
+       movq    $0,TF_XFLAGS(%rsp) ;    /* extras */                    \
        movq    $0,TF_TRAPNO(%rsp) ;    /* extras */                    \
        movq    $0,TF_ADDR(%rsp) ;      /* extras */                    \
        movq    $0,TF_FLAGS(%rsp) ;     /* extras */                    \
index ef52ecc..390fa00 100644 (file)
@@ -299,7 +299,8 @@ cpu_startup(void *dummy)
 #ifdef PERFMON
        perfmon_init();
 #endif
-       kprintf("real memory  = %llu (%lluK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
+       kprintf("real memory  = %llu (%lluK bytes)\n",
+               (long long)ptoa(Maxmem), (long long)ptoa(Maxmem) / 1024);
        /*
         * Display any holes after the first chunk of extended memory.
         */
@@ -311,8 +312,10 @@ cpu_startup(void *dummy)
                        vm_paddr_t size1 = phys_avail[indx + 1] - phys_avail[indx];
 
                        kprintf("0x%08llx - 0x%08llx, %llu bytes (%llu pages)\n",
-                           phys_avail[indx], phys_avail[indx + 1] - 1, size1,
-                           size1 / PAGE_SIZE);
+                           (long long)phys_avail[indx],
+                           (long long)phys_avail[indx + 1] - 1,
+                           (long long)size1,
+                           (long long)(size1 / PAGE_SIZE));
                }
        }
 
@@ -415,8 +418,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.
@@ -463,18 +467,15 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
        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 */
        sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext);
 
        /* save mailbox pending state for syscall interlock semantics */
-#if JG
        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 &&
@@ -483,9 +484,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
                    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
+               sfp = (struct sigframe *)regs->tf_rsp - 1;
        }
 
        /* Translate the signal is appropriate */
@@ -548,9 +547,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 +560,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_rflags &= ~(PSL_T|PSL_D);
 
        regs->tf_cs = _ucodesel;
-#if JG
-       regs->tf_ds = _udatasel;
-       regs->tf_es = _udatasel;
-#endif
+       /* no DS or ES */
 
        /*
-        * 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.
+        * Set a degenerate SS.  We don't have to worry about %fs or %gs?
         */
-       if (regs->tf_trapno == T_PROTFLT) {
-#if JG
-               regs->tf_fs = _udatasel;
-               regs->tf_gs = _udatasel;
-#endif
-       }
        regs->tf_ss = _udatasel;
 }
 
@@ -612,19 +591,11 @@ 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 +631,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 +644,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 +669,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 +702,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 +718,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 +744,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 +820,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 +871,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)
@@ -1121,22 +1072,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. */
@@ -1700,7 +1656,10 @@ 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;
@@ -1850,8 +1809,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;
@@ -1998,18 +1958,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 +1976,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 +1989,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);
 }
index b19e4e3..6995903 100644 (file)
@@ -669,7 +669,7 @@ ENTRY(lgdt)
        movl    %eax,%ds
        movl    %eax,%es
        movl    %eax,%fs        /* Beware, use wrmsr to set 64 bit base */
-       movl    %eax,%gs
+       movl    %eax,%gs        /* Beware, use wrmsr to set 64 bit base */
        movl    %eax,%ss
 
        /* reload code selector by turning return into intersegmental return */
index 3a5b07e..2b10dd6 100644 (file)
@@ -318,6 +318,7 @@ ENTRY(cpu_heavy_restore)
         * already have been set before we set it above, check? YYY
         */
 #if JG
+#error x
        movq    %cr3,%rsi
        movq    PCB_CR3(%rdx),%rcx
        cmpq    %rsi,%rcx
index dc8c603..04fc9ae 100644 (file)
@@ -898,6 +898,9 @@ nogo:
         * NOTE: on amd64 we have a tf_addr field in the trapframe, no
         * kludge is needed to pass the fault address to signal handlers.
         */
+       kprintf("seg-fault accessing address %p ip=%p\n",
+               va, frame->tf_rip);
+       Debugger("seg-fault");
 
        return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
 }
index b0b18e1..63ef84d 100644 (file)
@@ -89,7 +89,8 @@
  * Macro helpers
  */
 #define ICU_PUSH_FRAME                                                 \
-       PUSH_FRAME ;            /* 15 regs + space for 4 extras */      \
+       PUSH_FRAME ;            /* 15 regs + space for 5 extras */      \
+       movl $0,TF_XFLAGS(%rsp) ;                                       \
        movl $0,TF_TRAPNO(%rsp) ;                                       \
        movl $0,TF_ADDR(%rsp) ;                                         \
        movl $0,TF_FLAGS(%rsp) ;                                        \
index 4656a9d..7dd0151 100644 (file)
@@ -81,6 +81,7 @@ struct pcb {
 #define        PCB_DBREGS      0x02    /* process using debug registers */
 #define        PCB_FPUINITDONE 0x08    /* fpu state is initialized */
 #define        PCB_FULLCTX     0x80    /* full context restore on sysret */
+#define FP_SOFTFP       0x01    /* process using software fltng pnt emulator */
 #define        FP_VIRTFP       0x04    /* virtual kernel wants exception */
        caddr_t pcb_onfault;    /* copyin/out fault recovery */
        int     pcb_unused;