Fix amd64 trap handling.
authorSimon 'corecode' Schubert <corecode@fs.ei.tum.de>
Sat, 27 Dec 2008 20:06:46 +0000 (21:06 +0100)
committerSimon 'corecode' Schubert <corecode@fs.ei.tum.de>
Sat, 27 Dec 2008 20:06:46 +0000 (21:06 +0100)
Submitted-by: dillon@
sys/cpu/amd64/include/asmacros.h
sys/cpu/amd64/include/param.h
sys/platform/pc64/amd64/ipl.s
sys/platform/pc64/amd64/trap.c
sys/sys/bus.h

index c5aa487..3f5ec08 100644 (file)
 /*
  * Macros to create and destroy a trap frame.
  */
-#define PUSH_FRAME                                                     \
-       subq    $TF_RIP,%rsp ;  /* extend hardware frame to trapframe */ \
-       testb   $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */     \
-       jz      1f ;            /* Yes, dont swapgs again */            \
-       swapgs ;                                                        \
-1:     movq    %rdi,TF_RDI(%rsp) ;                                     \
+#define PUSH_FRAME_REGS                                                        \
+       movq    %rdi,TF_RDI(%rsp) ;                                     \
        movq    %rsi,TF_RSI(%rsp) ;                                     \
        movq    %rdx,TF_RDX(%rsp) ;                                     \
        movq    %rcx,TF_RCX(%rsp) ;                                     \
        movq    %r14,TF_R14(%rsp) ;                                     \
        movq    %r15,TF_R15(%rsp)
 
+#define PUSH_FRAME                                                     \
+       subq    $TF_RIP,%rsp ;  /* extend hardware frame to trapframe */ \
+       testb   $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */     \
+       jz      1f ;            /* Yes, dont swapgs again */            \
+       swapgs ;                                                        \
+1:                                                                     \
+       PUSH_FRAME_REGS                                                 \
+
+#define PUSH_FRAME_NOSWAP                                              \
+       subq    $TF_RIP,%rsp ;  /* extend hardware frame to trapframe */ \
+       PUSH_FRAME_REGS                                                 \
+
 #define POP_FRAME                                                      \
        movq    TF_RDI(%rsp),%rdi ;                                     \
        movq    TF_RSI(%rsp),%rsi ;                                     \
index a640d84..1a5ed83 100644 (file)
 /*
  * Mach derived conversion macros
  */
-#define        round_page(x)   ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
-#define        trunc_page(x)   ((unsigned long)(x) & ~(PAGE_MASK))
-#define trunc_2mpage(x)        ((unsigned long)(x) & ~PDRMASK)
-#define round_2mpage(x)        ((((unsigned long)(x)) + PDRMASK) & ~PDRMASK)
+#define        round_page(x)   ((((unsigned long)(x)) + PAGE_MASK) & ~(unsigned long)(PAGE_MASK))
+#define        trunc_page(x)   ((unsigned long)(x) & ~(unsigned long)(PAGE_MASK))
+#define trunc_2mpage(x)        ((unsigned long)(x) & ~(unsigned long)PDRMASK)
+#define round_2mpage(x)        ((((unsigned long)(x)) + PDRMASK) & ~(unsigned long)PDRMASK)
 
 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
 #define        atop(x)         ((vm_pindex_t)((x) >> PAGE_SHIFT))
index 839dbf1..d5ac7b4 100644 (file)
@@ -214,7 +214,7 @@ doreti_iret:
        ALIGN_TEXT
        .globl  doreti_iret_fault
 doreti_iret_fault:
-       PUSH_FRAME
+       PUSH_FRAME_NOSWAP
        testq   $PSL_I,TF_RFLAGS(%rsp)
        jz      2f
        sti
index 4c10823..d814fd5 100644 (file)
@@ -296,53 +296,32 @@ userexit(struct lwp *lp)
        struct thread *td = lp->lwp_thread;
        globaldata_t gd = td->td_gd;
 
-#if 0
-       /*
-        * If a user reschedule is requested force a new process to be
-        * chosen by releasing the current process.  Our process will only
-        * be chosen again if it has a considerably better priority.
-        */
-       if (user_resched_wanted())
-               lp->lwp_proc->p_usched->release_curproc(lp);
-#endif
-
        /*
-        * Handle a LWKT reschedule request first.  Since our passive release
-        * is still in place we do not have to do anything special.
+        * Handle stop requests at kernel priority.  Any requests queued
+        * after this loop will generate another AST.
         */
-       while (lwkt_resched_wanted()) {
-               lwkt_switch();
-
-               /*
-                * The thread that preempted us may have stopped our process.
-                */
-               while (lp->lwp_proc->p_stat == SSTOP) {
-                       get_mplock();
-                       tstop();
-                       rel_mplock();
-               }
+       while (lp->lwp_proc->p_stat == SSTOP) {
+               get_mplock();
+               tstop();
+               rel_mplock();
        }
 
        /*
-        * Acquire the current process designation for this user scheduler
-        * on this cpu.  This will also handle any user-reschedule requests.
-        */
-       lp->lwp_proc->p_usched->acquire_curproc(lp);
-       /* We may have switched cpus on acquisition */
-       gd = td->td_gd;
-
-       /*
         * Reduce our priority in preparation for a return to userland.  If
         * our passive release function was still in place, our priority was
         * never raised and does not need to be reduced.
-        *
-        * Note that at this point there may be other LWKT thread at
-        * TDPRI_KERN_USER (aka higher then our currenet priority).  We
-        * do NOT want to run these threads yet.
         */
        if (td->td_release == NULL)
                lwkt_setpri_self(TDPRI_USER_NORM);
        td->td_release = NULL;
+
+       /*
+        * Become the current user scheduled process if we aren't already,
+        * and deal with reschedule requests and other factors.
+        */
+       lp->lwp_proc->p_usched->acquire_curproc(lp);
+       /* WARNING: we may have migrated cpu's */
+       /* gd = td->td_gd; */
 }
 
 #if !defined(KTR_KERNENTRY)
@@ -657,6 +636,10 @@ trap(struct trapframe *frame)
                                                td->td_pcb->pcb_onfault;
                                        goto out2;
                                }
+                               if (frame->tf_rip == (long)doreti_iret) {
+                                       frame->tf_rip = (long)doreti_iret_fault;
+                                       goto out2;
+                               }
                        }
                        break;
 
index 40d230b..cf86c40 100644 (file)
@@ -506,6 +506,140 @@ static moduledata_t name##_##busname##_mod = {                            \
 DECLARE_MODULE(name##_##busname, name##_##busname##_mod,               \
               SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
 
+/**
+ * Shorthand macros, taking resource argument
+ */
+
+#define bus_barrier(r, o, l, f) \
+       bus_space_barrier((r)->r_bustag, (r)->r_bushandle, (o), (l), (f))
+#define bus_read_1(r, o) \
+       bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_1(r, o, d, c) \
+       bus_space_read_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_1(r, o, d, c) \
+       bus_space_read_region_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_1(r, o, v, c) \
+       bus_space_set_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_1(r, o, v, c) \
+       bus_space_set_region_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_1(r, o, v) \
+       bus_space_write_1((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_1(r, o, d, c) \
+       bus_space_write_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_1(r, o, d, c) \
+       bus_space_write_region_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_stream_1(r, o) \
+       bus_space_read_stream_1((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_stream_1(r, o, d, c) \
+       bus_space_read_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_stream_1(r, o, d, c) \
+       bus_space_read_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_stream_1(r, o, v, c) \
+       bus_space_set_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_stream_1(r, o, v, c) \
+       bus_space_set_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_stream_1(r, o, v) \
+       bus_space_write_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_stream_1(r, o, d, c) \
+       bus_space_write_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_stream_1(r, o, d, c) \
+       bus_space_write_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_2(r, o) \
+       bus_space_read_2((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_2(r, o, d, c) \
+       bus_space_read_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_2(r, o, d, c) \
+       bus_space_read_region_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_2(r, o, v, c) \
+       bus_space_set_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_2(r, o, v, c) \
+       bus_space_set_region_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_2(r, o, v) \
+       bus_space_write_2((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_2(r, o, d, c) \
+       bus_space_write_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_2(r, o, d, c) \
+       bus_space_write_region_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_stream_2(r, o) \
+       bus_space_read_stream_2((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_stream_2(r, o, d, c) \
+       bus_space_read_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_stream_2(r, o, d, c) \
+       bus_space_read_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_stream_2(r, o, v, c) \
+       bus_space_set_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_stream_2(r, o, v, c) \
+       bus_space_set_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_stream_2(r, o, v) \
+       bus_space_write_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_stream_2(r, o, d, c) \
+       bus_space_write_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_stream_2(r, o, d, c) \
+       bus_space_write_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_4(r, o) \
+       bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_4(r, o, d, c) \
+       bus_space_read_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_4(r, o, d, c) \
+       bus_space_read_region_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_4(r, o, v, c) \
+       bus_space_set_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_4(r, o, v, c) \
+       bus_space_set_region_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_4(r, o, v) \
+       bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_4(r, o, d, c) \
+       bus_space_write_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_4(r, o, d, c) \
+       bus_space_write_region_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_stream_4(r, o) \
+       bus_space_read_stream_4((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_stream_4(r, o, d, c) \
+       bus_space_read_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_stream_4(r, o, d, c) \
+       bus_space_read_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_stream_4(r, o, v, c) \
+       bus_space_set_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_stream_4(r, o, v, c) \
+       bus_space_set_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_stream_4(r, o, v) \
+       bus_space_write_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_stream_4(r, o, d, c) \
+       bus_space_write_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_stream_4(r, o, d, c) \
+       bus_space_write_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_8(r, o) \
+       bus_space_read_8((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_8(r, o, d, c) \
+       bus_space_read_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_8(r, o, d, c) \
+       bus_space_read_region_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_8(r, o, v, c) \
+       bus_space_set_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_8(r, o, v, c) \
+       bus_space_set_region_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_8(r, o, v) \
+       bus_space_write_8((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_8(r, o, d, c) \
+       bus_space_write_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_8(r, o, d, c) \
+       bus_space_write_region_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_stream_8(r, o) \
+       bus_space_read_stream_8((r)->r_bustag, (r)->r_bushandle, (o))
+#define bus_read_multi_stream_8(r, o, d, c) \
+       bus_space_read_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_read_region_stream_8(r, o, d, c) \
+       bus_space_read_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_set_multi_stream_8(r, o, v, c) \
+       bus_space_set_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_set_region_stream_8(r, o, v, c) \
+       bus_space_set_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c))
+#define bus_write_stream_8(r, o, v) \
+       bus_space_write_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v))
+#define bus_write_multi_stream_8(r, o, d, c) \
+       bus_space_write_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
+#define bus_write_region_stream_8(r, o, d, c) \
+       bus_space_write_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c))
 #endif /* _KERNEL */
 
 #endif /* !_SYS_BUS_H_ */