From 89ffa1cfd7ec4cf2acf0f2b8dfabed0924583d09 Mon Sep 17 00:00:00 2001 From: Simon 'corecode' Schubert Date: Sat, 27 Dec 2008 21:06:46 +0100 Subject: [PATCH] Fix amd64 trap handling. Submitted-by: dillon@ --- sys/cpu/amd64/include/asmacros.h | 20 +++-- sys/cpu/amd64/include/param.h | 8 +- sys/platform/pc64/amd64/ipl.s | 2 +- sys/platform/pc64/amd64/trap.c | 53 +++++------- sys/sys/bus.h | 134 +++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 46 deletions(-) diff --git a/sys/cpu/amd64/include/asmacros.h b/sys/cpu/amd64/include/asmacros.h index c5aa487780..3f5ec08eb8 100644 --- a/sys/cpu/amd64/include/asmacros.h +++ b/sys/cpu/amd64/include/asmacros.h @@ -142,12 +142,8 @@ /* * 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) ; \ @@ -163,6 +159,18 @@ 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 ; \ diff --git a/sys/cpu/amd64/include/param.h b/sys/cpu/amd64/include/param.h index a640d841ba..1a5ed832f6 100644 --- a/sys/cpu/amd64/include/param.h +++ b/sys/cpu/amd64/include/param.h @@ -205,10 +205,10 @@ /* * 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)) diff --git a/sys/platform/pc64/amd64/ipl.s b/sys/platform/pc64/amd64/ipl.s index 839dbf1a12..d5ac7b4a8e 100644 --- a/sys/platform/pc64/amd64/ipl.s +++ b/sys/platform/pc64/amd64/ipl.s @@ -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 diff --git a/sys/platform/pc64/amd64/trap.c b/sys/platform/pc64/amd64/trap.c index 4c10823aa1..d814fd59c0 100644 --- a/sys/platform/pc64/amd64/trap.c +++ b/sys/platform/pc64/amd64/trap.c @@ -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; diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 40d230bd61..cf86c40432 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -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_ */ -- 2.41.0