CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Mon Nov 27 09:18:01 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c process_machdep.c Log Message: Inline _FRAME_GREG, and mask only 16 bits of the segment registers, otherwise the upper 48 bits may contain stack garbage. By the way, I find it suspicious that we're not masking regs[_REG_RFLAGS] with PSL_USER in process_write_regs. To generate a diff of this commit: cvs rdiff -u -r1.277 -r1.278 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.36 -r1.37 src/sys/arch/amd64/amd64/process_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.277 src/sys/arch/amd64/amd64/machdep.c:1.278 --- src/sys/arch/amd64/amd64/machdep.c:1.277 Tue Nov 21 10:42:44 2017 +++ src/sys/arch/amd64/amd64/machdep.c Mon Nov 27 09:18:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.278 2017/11/27 09:18:01 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.278 2017/11/27 09:18:01 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1876,10 +1876,33 @@ cpu_getmcontext(struct lwp *l, mcontext_ const struct trapframe *tf = l->l_md.md_regs; __greg_t ras_rip; - /* Copy general registers member by member */ -#define copy_from_tf(reg, REG, idx) mcp->__gregs[_REG_##REG] = tf->tf_##reg; - _FRAME_GREG(copy_from_tf) -#undef copy_from_tf + mcp->__gregs[_REG_RDI] = tf->tf_rdi; + mcp->__gregs[_REG_RSI] = tf->tf_rsi; + mcp->__gregs[_REG_RDX] = tf->tf_rdx; + mcp->__gregs[_REG_R10] = tf->tf_r10; + mcp->__gregs[_REG_R8] = tf->tf_r8; + mcp->__gregs[_REG_R9] = tf->tf_r9; + /* argX not touched */ + mcp->__gregs[_REG_RCX] = tf->tf_rcx; + mcp->__gregs[_REG_R11] = tf->tf_r11; + mcp->__gregs[_REG_R12] = tf->tf_r12; + mcp->__gregs[_REG_R13] = tf->tf_r13; + mcp->__gregs[_REG_R14] = tf->tf_r14; + mcp->__gregs[_REG_R15] = tf->tf_r15; + mcp->__gregs[_REG_RBP] = tf->tf_rbp; + mcp->__gregs[_REG_RBX] = tf->tf_rbx; + mcp->__gregs[_REG_RAX] = tf->tf_rax; + mcp->__gregs[_REG_GS] = tf->tf_gs & 0x; + mcp->__gregs[_REG_FS] = tf->tf_fs & 0x; + mcp->__gregs[_REG_ES] = tf->tf_es & 0x; + mcp->__gregs[_REG_DS] = tf->tf_ds & 0x; + mcp->__gregs[_REG_TRAPNO] = tf->tf_trapno; + mcp->__gregs[_REG_ERR] = tf->tf_err; + mcp->__gregs[_REG_RIP] = tf->tf_rip; + mcp->__gregs[_REG_CS] = tf->tf_cs & 0x; + mcp->__gregs[_REG_RFLAGS] = tf->tf_rflags; + mcp->__gregs[_REG_RSP] = tf->tf_rsp; + mcp->__gregs[_REG_SS] = tf->tf_ss & 0x; if ((ras_rip = (__greg_t)ras_lookup(l->l_proc, (void *) mcp->__gregs[_REG_RIP])) != -1) @@ -1901,7 +1924,6 @@ cpu_setmcontext(struct lwp *l, const mco const __greg_t *gr = mcp->__gregs; struct proc *p = l->l_proc; int error; - int err, trapno; int64_t rflags; CTASSERT(sizeof (mcontext_t) == 26 * 8 + 8 + 512); @@ -1910,33 +1932,44 @@ cpu_setmcontext(struct lwp *l, const mco error = cpu_mcontext_validate(l, mcp); if (error != 0) return error; - /* - * save and restore some values we don't want to change. - * _FRAME_GREG(copy_to_tf) below overwrites them. - * - * XXX maybe inline this. - */ - rflags = tf->tf_rflags; - err = tf->tf_err; - trapno = tf->tf_trapno; - /* Copy general registers member by member */ -#define copy_to_tf(reg, REG, idx) tf->tf_##reg = gr[_REG_##REG]; - _FRAME_GREG(copy_to_tf) -#undef copy_to_tf + tf->tf_rdi = gr[_REG_RDI]; + tf->tf_rsi = gr[_REG_RSI]; + tf->tf_rdx = gr[_REG_RDX]; + tf->tf_r10 = gr[_REG_R10]; + tf->tf_r8 = gr[_REG_R8]; + tf->tf_r9 = gr[_REG_R9]; + /* argX not touched */ + tf->tf_rcx = gr[_REG_RCX]; + tf->tf_r11 = gr[_REG_R11]; + tf->tf_r12 = gr[_REG_R12]; + tf->tf_r13 = gr[_REG_R13]; + tf->tf_r14 = gr[_REG_R14]; + tf->tf_r15 = gr[_REG_R15]; + tf->tf_rbp = gr[_REG_RBP]; + tf->tf_rbx = gr[_REG_RBX]; + tf->tf_rax = gr[_REG_RAX]; + tf->tf_gs = gr[_REG_GS] & 0x; + tf->tf_fs = gr[_REG_FS] & 0x; + tf->tf_es = gr[_REG_ES] & 0x; + tf->tf_ds = gr[_REG_DS] & 0x; + /* trapno, err not touched */ + tf->tf_rip = gr[_REG_RIP]; + tf->tf_cs = gr[_REG_CS] & 0x; + rflags = tf->tf_rflags; + rflags &= ~PSL_USER; + tf->tf_rflags = rflags | (gr[_REG_RFLAGS] & PSL_USER); + tf->tf_rsp = gr[_REG_RSP]; + tf->tf_ss = gr[_REG_SS] & 0x; #ifdef XEN /* * Xen has its own way of dealing with %cs and %ss, - * reset it to proper values. + * reset them to proper values. */ tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL); tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL); #endif - rflags &= ~PSL_USER; - tf->tf_rflags = rflags | (gr[_REG_RFLAGS] & PSL_USER); - tf->tf_err = err; -
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Nov 26 15:00:16 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Update a comment, and use testw instead. To generate a diff of this commit: cvs rdiff -u -r1.142 -r1.143 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.142 src/sys/arch/amd64/amd64/locore.S:1.143 --- src/sys/arch/amd64/amd64/locore.S:1.142 Sun Nov 26 14:54:43 2017 +++ src/sys/arch/amd64/amd64/locore.S Sun Nov 26 15:00:16 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.142 2017/11/26 14:54:43 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.143 2017/11/26 15:00:16 maxv Exp $ */ /* * Copyright-o-rama! @@ -1197,7 +1197,7 @@ ENTRY(cpu_switchto) movq PCB_GS(%r14),%rax movq %rax,(GUGS_SEL*8)(%rcx) - /* Set default 32bit values in %ds, %es and %fs. %gs is special. */ + /* Set default 32bit values in %ds, %es, %fs and %gs. */ movq L_MD_REGS(%r12),%rbx movq $GSEL(GUDATA32_SEL, SEL_UPL),%rax movw %ax,%ds @@ -1474,7 +1474,7 @@ END(pagezero) ENTRY(intrfastexit) INTR_RESTORE_GPRS - testq $SEL_UPL,TF_CS(%rsp) /* interrupted %cs */ + testw $SEL_UPL,TF_CS(%rsp) /* interrupted %cs */ jz .Lkexit cmpw $LSEL(LUCODE_SEL, SEL_UPL),TF_CS(%rsp) je .Luexit64
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Nov 26 14:54:43 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S locore.S mptramp.S Log Message: Hide a bunch of raw symbols. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/arch/amd64/amd64/amd64_trap.S cvs rdiff -u -r1.141 -r1.142 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.25 -r1.26 src/sys/arch/amd64/amd64/mptramp.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.12 src/sys/arch/amd64/amd64/amd64_trap.S:1.13 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.12 Tue Oct 17 07:33:44 2017 +++ src/sys/arch/amd64/amd64/amd64_trap.S Sun Nov 26 14:54:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: amd64_trap.S,v 1.12 2017/10/17 07:33:44 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.13 2017/11/26 14:54:43 maxv Exp $ */ /* * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ #if 0 #include -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.12 2017/10/17 07:33:44 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.13 2017/11/26 14:54:43 maxv Exp $"); #endif /* @@ -132,21 +132,21 @@ IDTVEC(trap02) movl $MSR_GSBASE,%ecx rdmsr cmpl $VM_MIN_KERNEL_ADDRESS_HIGH32,%edx - jae noswapgs + jae .Lnoswapgs swapgs movq %rsp,%rdi incq CPUVAR(NTRAP) call _C_LABEL(nmitrap) swapgs - jmp nmileave + jmp .Lnmileave -noswapgs: +.Lnoswapgs: movq %rsp,%rdi incq CPUVAR(NTRAP) call _C_LABEL(trap) -nmileave: +.Lnmileave: movw TF_ES(%rsp),%es movw TF_DS(%rsp),%ds INTR_RESTORE_GPRS Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.141 src/sys/arch/amd64/amd64/locore.S:1.142 --- src/sys/arch/amd64/amd64/locore.S:1.141 Tue Nov 21 09:58:09 2017 +++ src/sys/arch/amd64/amd64/locore.S Sun Nov 26 14:54:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.141 2017/11/21 09:58:09 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.142 2017/11/26 14:54:43 maxv Exp $ */ /* * Copyright-o-rama! @@ -450,7 +450,7 @@ ENTRY(start) /* Load 'bootinfo' */ movl 12(%esp),%eax testl %eax,%eax /* bootinfo = NULL? */ - jz bootinfo_finished + jz .Lbootinfo_finished movl (%eax),%ebx /* bootinfo::bi_nentries */ movl $RELOC(bootinfo),%ebp @@ -459,9 +459,9 @@ ENTRY(start) movl %ebx,(%edx) addl $4,%edx -bootinfo_entryloop: +.Lbootinfo_entryloop: testl %ebx,%ebx /* no remaining entries? */ - jz bootinfo_finished + jz .Lbootinfo_finished addl $4,%eax movl (%eax),%ecx /* address of entry */ @@ -473,7 +473,7 @@ bootinfo_entryloop: movl %edx,%edi addl %eax,%edx /* update dest pointer */ cmpl %ebp,%edx /* beyond bootinfo+BOOTINFO_MAXSIZE? */ - jg bootinfo_overflow + jg .Lbootinfo_overflow movl %ecx,%esi movl %eax,%ecx @@ -483,34 +483,34 @@ bootinfo_entryloop: * later to compute the initial bootstrap tables. */ cmpl $BTINFO_MODULELIST,4(%esi) /* btinfo_common::type */ - jne bootinfo_copy + jne .Lbootinfo_copy /* Skip the modules if we won't have enough VA to map them */ movl 12(%esi),%eax /* btinfo_modulelist::endpa */ addl $PGOFSET,%eax /* roundup to a page */ andl $~PGOFSET,%eax cmpl $BOOTMAP_VA_SIZE,%eax - jg bootinfo_skip + jg .Lbootinfo_skip movl %eax,RELOC(eblob) addl $KERNBASE_LO,RELOC(eblob) adcl $KERNBASE_HI,RELOC(eblob)+4 -bootinfo_copy: +.Lbootinfo_copy: rep movsb/* copy esi -> edi */ - jmp bootinfo_next + jmp .Lbootinfo_next -bootinfo_skip: +.Lbootinfo_skip: subl %ecx,%edx /* revert dest pointer */ -bootinfo_next: +.Lbootinfo_next: popl %eax popl %esi popl %edi subl $1,%ebx /* decrement the # of entries */ - jmp bootinfo_entryloop + jmp .Lbootinfo_entryloop -bootinfo_overflow: +.Lbootinfo_overflow: /* * Cleanup for overflow case. Pop the registers, and correct the number * of entries. @@ -521,7 +521,7 @@ bootinfo_overflow: movl $RELOC(bootinfo),%ebp movl %ebp,%edx subl %ebx,(%edx) /* correct the number of entries */ -bootinfo_finished: +.Lbootinfo_finished: /* Load 'esym' */ movl 16(%esp),%eax @@ -539,22 +539,22 @@ bootinfo_finished: movl $RELOC(biosextmem),%ebp movl (%ebp),%eax testl %eax,%eax /* already set? */ - jnz biosextmem_finished + jnz .Lbiosextmem_finished movl 20(%esp),%eax movl %eax,(%ebp) -biosextmem_finished: +.Lbiosextmem_finished: /* Load 'biosbasemem' */ movl $RELOC(biosbasemem),%ebp movl (%ebp),%eax testl %eax,%eax /* already set? */ - jnz biosbasemem_finished + jnz .Lbiosbasemem_finished movl 24(%esp),%eax movl %eax,(%ebp) -biosbasemem_finished: +.Lbiosbasemem_finished: /* * Done with the parameters! */ @@ -588,9 +588,9 @@ biosbasemem_finished: movl $0x8001,%eax cpuid andl $CPUID_NOX,%edx - jz no_NOX + jz .Lno_NOX movl $PG_NX32,RELOC(nox_flag) -no_NOX: +.Lno_NOX: /* * There are four levels of
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Nov 21 10:42:44 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Remove unused variables. To generate a diff of this commit: cvs rdiff -u -r1.276 -r1.277 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.276 src/sys/arch/amd64/amd64/machdep.c:1.277 --- src/sys/arch/amd64/amd64/machdep.c:1.276 Sat Nov 11 12:51:06 2017 +++ src/sys/arch/amd64/amd64/machdep.c Tue Nov 21 10:42:44 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.276 2017/11/11 12:51:06 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.276 2017/11/11 12:51:06 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -232,8 +232,6 @@ int cpu_class = CPUCLASS_686; struct mtrr_funcs *mtrr_funcs; #endif -uint64_t dumpmem_low; -uint64_t dumpmem_high; int cpu_class; int use_pae;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Nov 21 09:58:09 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Remove unused symbol - it is aligned to 4096 and this reduces the number of possible locations for .bss in KASLR kernels. To generate a diff of this commit: cvs rdiff -u -r1.140 -r1.141 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.140 src/sys/arch/amd64/amd64/locore.S:1.141 --- src/sys/arch/amd64/amd64/locore.S:1.140 Sat Oct 28 20:57:17 2017 +++ src/sys/arch/amd64/amd64/locore.S Tue Nov 21 09:58:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.140 2017/10/28 20:57:17 bouyer Exp $ */ +/* $NetBSD: locore.S,v 1.141 2017/11/21 09:58:09 maxv Exp $ */ /* * Copyright-o-rama! @@ -421,9 +421,6 @@ END(farjmp64) .space 512 tmpstk: - .globl _C_LABEL(cpu_private) - .comm _C_LABEL(cpu_private),PAGE_SIZE,PAGE_SIZE - /* * Some hackage to deal with 64bit symbols in 32 bit mode. * This may not be needed if things are cleaned up a little.
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Nov 8 18:29:04 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: vector.S Log Message: Don't fall through. To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/arch/amd64/amd64/vector.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/vector.S diff -u src/sys/arch/amd64/amd64/vector.S:1.52 src/sys/arch/amd64/amd64/vector.S:1.53 --- src/sys/arch/amd64/amd64/vector.S:1.52 Mon Oct 30 17:06:42 2017 +++ src/sys/arch/amd64/amd64/vector.S Wed Nov 8 18:29:04 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: vector.S,v 1.52 2017/10/30 17:06:42 maxv Exp $ */ +/* $NetBSD: vector.S,v 1.53 2017/11/08 18:29:04 maxv Exp $ */ -/*- +/* * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. * All rights reserved. * @@ -140,6 +140,7 @@ IDTVEC(intr_lapic_ipi) movl CPUVAR(ILEVEL),%ebx cmpl $IPL_HIGH,%ebx jae 2f + jmp 1f IDTVEC_END(intr_lapic_ipi) IDTVEC(resume_lapic_ipi) 1: @@ -223,6 +224,7 @@ IDTVEC(intr_lapic_ltimer) movl CPUVAR(ILEVEL),%ebx cmpl $IPL_CLOCK,%ebx jae 2f + jmp 1f IDTVEC_END(intr_lapic_ltimer) IDTVEC(resume_lapic_ltimer) 1:
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Nov 1 09:38:43 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: linux32_sigcode.S linux_sigcode.S netbsd32_sigcode.S Log Message: More END(). In linux_sigcode.S we only provide symbols, not defined as functions. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/amd64/amd64/linux32_sigcode.S cvs rdiff -u -r1.3 -r1.4 src/sys/arch/amd64/amd64/linux_sigcode.S cvs rdiff -u -r1.7 -r1.8 src/sys/arch/amd64/amd64/netbsd32_sigcode.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/linux32_sigcode.S diff -u src/sys/arch/amd64/amd64/linux32_sigcode.S:1.4 src/sys/arch/amd64/amd64/linux32_sigcode.S:1.5 --- src/sys/arch/amd64/amd64/linux32_sigcode.S:1.4 Mon Oct 30 17:06:42 2017 +++ src/sys/arch/amd64/amd64/linux32_sigcode.S Wed Nov 1 09:38:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_sigcode.S,v 1.4 2017/10/30 17:06:42 maxv Exp $ */ +/* $NetBSD: linux32_sigcode.S,v 1.5 2017/11/01 09:38:43 maxv Exp $ */ #include "assym.h" #include @@ -6,7 +6,7 @@ .code32 NENTRY(linux32_sigcode) call *LINUX32_SF_HANDLER(%esp) - leal LINUX32_SF_SC(%esp),%ebx # scp + leal LINUX32_SF_SC(%esp),%ebx /* scp */ pushl %eax movl $LINUX32_SYS_sigreturn,%eax int $0x80 @@ -17,7 +17,7 @@ END(linux32_sigcode) .balign 16 NENTRY(linux32_rt_sigcode) call *LINUX32_RT_SF_HANDLER(%esp) - leal LINUX32_RT_SF_UC(%esp),%ebx # scp + leal LINUX32_RT_SF_UC(%esp),%ebx /* scp */ pushl %eax movl $LINUX32_SYS_rt_sigreturn,%eax int $0x80 @@ -26,4 +26,5 @@ NENTRY(linux32_rt_sigcode) .balign 16 .globl _C_LABEL(linux32_esigcode) _C_LABEL(linux32_esigcode): +END(linux32_rt_sigcode) Index: src/sys/arch/amd64/amd64/linux_sigcode.S diff -u src/sys/arch/amd64/amd64/linux_sigcode.S:1.3 src/sys/arch/amd64/amd64/linux_sigcode.S:1.4 --- src/sys/arch/amd64/amd64/linux_sigcode.S:1.3 Mon Oct 30 17:06:42 2017 +++ src/sys/arch/amd64/amd64/linux_sigcode.S Wed Nov 1 09:38:43 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: linux_sigcode.S,v 1.3 2017/10/30 17:06:42 maxv Exp $ */ +/* $NetBSD: linux_sigcode.S,v 1.4 2017/11/01 09:38:43 maxv Exp $ */ -/*- +/* * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,16 +34,12 @@ #include /* - * The signal trampoline are not used on Linux/amd64: a - * libc provided trampoline is always used. - * We just provide the symbol so that the kernel builds. + * The signal trampoline are not used on Linux/amd64: a libc provided + * trampoline is always used. We just provide the symbol so that the kernel + * builds. */ -/* LINTSTUB: Var: char linux_sigcode[1], linux_esigcode[1]; */ -NENTRY(linux_sigcode) -END(linux_sigcode) + .globl _C_LABEL(linux_sigcode), _C_LABEL(linux_esigcode) + .set _C_LABEL(linux_sigcode),0 + .set _C_LABEL(linux_esigcode),0 -/* LINTSTUB: Var: char linux_rt_sigcode[1]; */ -NENTRY(linux_rt_sigcode) - .globl _C_LABEL(linux_esigcode) -_C_LABEL(linux_esigcode): Index: src/sys/arch/amd64/amd64/netbsd32_sigcode.S diff -u src/sys/arch/amd64/amd64/netbsd32_sigcode.S:1.7 src/sys/arch/amd64/amd64/netbsd32_sigcode.S:1.8 --- src/sys/arch/amd64/amd64/netbsd32_sigcode.S:1.7 Mon Apr 28 20:23:12 2008 +++ src/sys/arch/amd64/amd64/netbsd32_sigcode.S Wed Nov 1 09:38:43 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: netbsd32_sigcode.S,v 1.7 2008/04/28 20:23:12 martin Exp $ */ +/* $NetBSD: netbsd32_sigcode.S,v 1.8 2017/11/01 09:38:43 maxv Exp $ */ -/*- +/* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. * All rights reserved. * @@ -36,23 +36,22 @@ /* * Signal trampoline for 1.6 compatibility; copied to top of user stack. */ - -NENTRY(netbsd32_sigcode) - .code32 +NENTRY(netbsd32_sigcode) /* * Handler has returned here as if we called it. The sigcontext * is on the stack after the 3 args "we" pushed. */ - leal 12(%esp),%eax # get pointer to sigcontext - movl %eax,4(%esp) # put it in the argument slot - # fake return address already there + leal 12(%esp),%eax /* get pointer to sigcontext */ + movl %eax,4(%esp) /* put it in the argument slot */ + /* fake return address already there */ movl $SYS_compat_16___sigreturn14,%eax - int $0x80 # enter kernel with args on stack + int $0x80 /* enter kernel with args on stack */ movl $SYS_exit,%eax - int $0x80 # exit if sigreturn fails + int $0x80 /* exit if sigreturn fails */ .globl _C_LABEL(netbsd32_esigcode) _C_LABEL(netbsd32_esigcode): +END(netbsd32_sigcode) /* * There is no NetBSD-1.6 compatibility for native code.
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Nov 1 09:17:28 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S cpufunc.S Log Message: Don't fall through functions, explicitly jump instead. While here don't call smap_enable twice (harmless), and add END() markers. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/arch/amd64/amd64/copy.S cvs rdiff -u -r1.30 -r1.31 src/sys/arch/amd64/amd64/cpufunc.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.27 src/sys/arch/amd64/amd64/copy.S:1.28 --- src/sys/arch/amd64/amd64/copy.S:1.27 Mon Oct 30 17:06:42 2017 +++ src/sys/arch/amd64/amd64/copy.S Wed Nov 1 09:17:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.27 2017/10/30 17:06:42 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.28 2017/11/01 09:17:28 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -258,19 +258,17 @@ END(copyin) NENTRY(copy_efault) movq $EFAULT,%rax - -/* - * kcopy_fault is used by kcopy and copy_fault is used by copyin/out. - * - * they're distinguished for lazy pmap switching. see trap(). - */ + ret +END(copy_efault) NENTRY(kcopy_fault) ret +END(kcopy_fault) NENTRY(copy_fault) callq smap_enable ret +END(copy_fault) ENTRY(copyoutstr) DEFERRED_SWITCH_CHECK @@ -362,6 +360,8 @@ END(copyinstr) ENTRY(copystr_efault) movl $EFAULT,%eax + jmp copystr_return +END(copystr_efault) ENTRY(copystr_fault) callq smap_enable @@ -371,8 +371,8 @@ copystr_return: jz 8f subq %rdx,%r8 movq %r8,(%r9) - 8: ret +END(copystr_fault) ENTRY(copystr) xchgq %rdi,%rsi @@ -564,10 +564,13 @@ END(ucas_32) ENTRY(ucas_efault) movq $EFAULT,%rax + ret +END(ucas_efault) NENTRY(ucas_fault) callq smap_enable ret +END(ucas_fault) /* * int ucas_ptr(volatile void **uptr, void *old, void *new, void **ret); Index: src/sys/arch/amd64/amd64/cpufunc.S diff -u src/sys/arch/amd64/amd64/cpufunc.S:1.30 src/sys/arch/amd64/amd64/cpufunc.S:1.31 --- src/sys/arch/amd64/amd64/cpufunc.S:1.30 Mon Oct 30 17:06:42 2017 +++ src/sys/arch/amd64/amd64/cpufunc.S Wed Nov 1 09:17:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.S,v 1.30 2017/10/30 17:06:42 maxv Exp $ */ +/* $NetBSD: cpufunc.S,v 1.31 2017/11/01 09:17:28 maxv Exp $ */ /* * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -424,8 +424,7 @@ END(__byte_swap_u16_variable) * Load a new GDT pointer (and do any necessary cleanup). * XXX It's somewhat questionable whether reloading all the segment registers * is necessary, since the actual descriptor data is not changed except by - * process creation and exit, both of which clean up via task switches. OTOH, - * this only happens at run time when the GDT is resized. + * process creation and exit, both of which clean up via task switches. */ #ifndef XEN ENTRY(lgdt) @@ -435,19 +434,21 @@ ENTRY(lgdt) /* Flush the prefetch q. */ jmp 1f nop -1: /* Reload "stale" selectors. */ -#else /* XEN */ +1: jmp _C_LABEL(lgdt_finish) +END(lgdt) +#endif + /* * void lgdt_finish(void); * Reload segments after a GDT change */ ENTRY(lgdt_finish) -#endif /* XEN */ movl $GSEL(GDATA_SEL, SEL_KPL),%eax movl %eax,%ds movl %eax,%es movl %eax,%ss - /* FALLTHROUGH */ + jmp _C_LABEL(x86_flush) +END(lgdt_finish) /* * void x86_flush()
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Mon Oct 30 17:06:42 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S cpufunc.S linux32_sigcode.S linux_sigcode.S vector.S Log Message: Always use END() markers when declaring functions in assembly, so that ld can compute the size of the functions. A few remain. While here, fix a bug in the INTRSTUB macro: we are falling through resume_, but it is aligned, so it looks like we're executing the inter- function padding - which probably happens to contain NOPs, but that's still bad. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/arch/amd64/amd64/copy.S cvs rdiff -u -r1.29 -r1.30 src/sys/arch/amd64/amd64/cpufunc.S cvs rdiff -u -r1.3 -r1.4 src/sys/arch/amd64/amd64/linux32_sigcode.S cvs rdiff -u -r1.2 -r1.3 src/sys/arch/amd64/amd64/linux_sigcode.S cvs rdiff -u -r1.51 -r1.52 src/sys/arch/amd64/amd64/vector.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.26 src/sys/arch/amd64/amd64/copy.S:1.27 --- src/sys/arch/amd64/amd64/copy.S:1.26 Tue Oct 17 07:02:50 2017 +++ src/sys/arch/amd64/amd64/copy.S Mon Oct 30 17:06:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.26 2017/10/17 07:02:50 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.27 2017/10/30 17:06:42 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -105,6 +105,7 @@ ENTRY(do_pmap_load) popq %rdi leaveq ret +END(do_pmap_load) /* * SMAP functions. ret+int3+int3 is patched dynamically to STAC/CLAC. @@ -116,6 +117,7 @@ ENTRY(smap_enable) int3 int3 ret +END(smap_enable) ENTRY(smap_disable) .Lstacpatch: @@ -123,6 +125,7 @@ ENTRY(smap_disable) int3 int3 ret +END(smap_disable) /* * Copy routines from and to userland, plus a few more. See the @@ -190,6 +193,7 @@ ENTRY(kcopy) .Lkcopy_end: xorq %rax,%rax ret +END(kcopy) ENTRY(copyout) DEFERRED_SWITCH_CHECK @@ -219,6 +223,7 @@ ENTRY(copyout) xorl %eax,%eax ret DEFERRED_SWITCH_CALL +END(copyout) ENTRY(copyin) DEFERRED_SWITCH_CHECK @@ -249,6 +254,7 @@ ENTRY(copyin) xorl %eax,%eax ret DEFERRED_SWITCH_CALL +END(copyin) NENTRY(copy_efault) movq $EFAULT,%rax @@ -308,6 +314,7 @@ ENTRY(copyoutstr) movq $ENAMETOOLONG,%rax jmp copystr_return DEFERRED_SWITCH_CALL +END(copyoutstr) ENTRY(copyinstr) DEFERRED_SWITCH_CHECK @@ -351,6 +358,7 @@ ENTRY(copyinstr) movq $ENAMETOOLONG,%rax jmp copystr_return DEFERRED_SWITCH_CALL +END(copyinstr) ENTRY(copystr_efault) movl $EFAULT,%eax @@ -394,7 +402,7 @@ ENTRY(copystr) movq %r8,(%rcx) 7: ret - +END(copystr) ENTRY(fuswintr) cmpl $TLBSTATE_VALID,CPUVAR(TLBSTATE) @@ -412,6 +420,7 @@ ENTRY(fuswintr) movq $0,PCB_ONFAULT(%rcx) ret +END(fuswintr) ENTRY(fubyte) DEFERRED_SWITCH_CHECK @@ -429,6 +438,7 @@ ENTRY(fubyte) movq $0,PCB_ONFAULT(%rcx) ret DEFERRED_SWITCH_CALL +END(fubyte) ENTRY(suswintr) cmpl $TLBSTATE_VALID,CPUVAR(TLBSTATE) @@ -447,6 +457,7 @@ ENTRY(suswintr) xorq %rax,%rax movq %rax,PCB_ONFAULT(%rcx) ret +END(suswintr) ENTRY(subyte) DEFERRED_SWITCH_CHECK @@ -466,6 +477,7 @@ ENTRY(subyte) movq %rax,PCB_ONFAULT(%rcx) ret DEFERRED_SWITCH_CALL +END(subyte) /* * These are the same, but must reside at different addresses, @@ -476,16 +488,19 @@ ENTRY(fusuintrfailure) movq $0,PCB_ONFAULT(%rcx) movl $-1,%eax ret +END(fusuintrfailure) ENTRY(fusufailure) callq smap_enable movq $0,PCB_ONFAULT(%rcx) movl $-1,%eax ret +END(fusufailure) ENTRY(fusuaddrfault) movl $-1,%eax ret +END(fusuaddrfault) /* * Compare-and-swap the 64-bit integer in the user-space. @@ -516,6 +531,7 @@ ENTRY(ucas_64) xorq %rax,%rax ret DEFERRED_SWITCH_CALL +END(ucas_64) /* * int ucas_32(volatile int32_t *uptr, int32_t old, int32_t new, int32_t *ret); @@ -544,6 +560,7 @@ ENTRY(ucas_32) xorq %rax,%rax ret DEFERRED_SWITCH_CALL +END(ucas_32) ENTRY(ucas_efault) movq $EFAULT,%rax Index: src/sys/arch/amd64/amd64/cpufunc.S diff -u src/sys/arch/amd64/amd64/cpufunc.S:1.29 src/sys/arch/amd64/amd64/cpufunc.S:1.30 --- src/sys/arch/amd64/amd64/cpufunc.S:1.29 Sun Oct 15 11:31:00 2017 +++ src/sys/arch/amd64/amd64/cpufunc.S Mon Oct 30 17:06:42 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: cpufunc.S,v 1.29 2017/10/15 11:31:00 maxv Exp $ */ +/* $NetBSD: cpufunc.S,v 1.30 2017/10/30 17:06:42 maxv Exp $ */ -/*- +/* * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. * All rights reserved. * @@ -51,23 +51,28 @@ ENTRY(x86_lfence) lfence ret +END(x86_lfence) ENTRY(x86_sfence) sfence ret +END(x86_sfence) ENTRY(x86_mfence) mfence ret +END(x86_mfence) #ifndef XEN ENTRY(invlpg) invlpg (%rdi) ret +END(invlpg) ENTRY(lidt) lidt (%rdi) ret +END(lidt) ENTRY(lldt) cmpl %edi, CPUVAR(CURLDT) @@ -77,51 +82,63 @@ ENTRY(lldt) movl %edi, CPUVAR(CURLDT) lldt %di ret
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Oct 29 10:25:28 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Use bootspace.head.va instead of the direct map. Otherwise there's the assumption that the offsets contained in sh_offset in physical memory are equal to the offsets in virtual memory, which won't be true in the future. To generate a diff of this commit: cvs rdiff -u -r1.273 -r1.274 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.273 src/sys/arch/amd64/amd64/machdep.c:1.274 --- src/sys/arch/amd64/amd64/machdep.c:1.273 Sun Oct 29 10:01:21 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Oct 29 10:25:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.273 2017/10/29 10:01:21 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.274 2017/10/29 10:25:28 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.273 2017/10/29 10:01:21 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.274 2017/10/29 10:25:28 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1481,8 +1481,8 @@ init_x86_64_ksyms(void) symtab = lookup_bootinfo(BTINFO_SYMTAB); if (symtab) { #ifdef KASLR - tssym = PMAP_DIRECT_MAP((paddr_t)symtab->ssym); - tesym = PMAP_DIRECT_MAP((paddr_t)symtab->esym); + tssym = bootspace.head.va; + tesym = bootspace.head.va; /* (unused...) */ #else tssym = (vaddr_t)symtab->ssym + KERNBASE; tesym = (vaddr_t)symtab->esym + KERNBASE;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: bouyer Date: Sat Oct 28 20:57:17 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: genassym.cf locore.S Log Message: Use FLAT_RING3_CS64 (defined in Xen public headers) instead of numeric value. To generate a diff of this commit: cvs rdiff -u -r1.61 -r1.62 src/sys/arch/amd64/amd64/genassym.cf cvs rdiff -u -r1.139 -r1.140 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/genassym.cf diff -u src/sys/arch/amd64/amd64/genassym.cf:1.61 src/sys/arch/amd64/amd64/genassym.cf:1.62 --- src/sys/arch/amd64/amd64/genassym.cf:1.61 Sun Jul 16 14:02:48 2017 +++ src/sys/arch/amd64/amd64/genassym.cf Sat Oct 28 20:57:17 2017 @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.61 2017/07/16 14:02:48 cherry Exp $ +# $NetBSD: genassym.cf,v 1.62 2017/10/28 20:57:17 bouyer Exp $ # # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -349,6 +349,7 @@ define EVTCHN_UPCALL_MASK offsetof(struc define XEN_PT_BASE offsetof(struct start_info, pt_base) define XEN_NR_PT_FRAMES offsetof(struct start_info, nr_pt_frames) define __HYPERVISOR_iret __HYPERVISOR_iret +define FLAT_RING3_CS64 FLAT_RING3_CS64 endif define NKL4_KIMG_ENTRIES NKL4_KIMG_ENTRIES Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.139 src/sys/arch/amd64/amd64/locore.S:1.140 --- src/sys/arch/amd64/amd64/locore.S:1.139 Sat Oct 28 20:06:31 2017 +++ src/sys/arch/amd64/amd64/locore.S Sat Oct 28 20:57:17 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.139 2017/10/28 20:06:31 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.140 2017/10/28 20:57:17 bouyer Exp $ */ /* * Copyright-o-rama! @@ -1484,7 +1484,7 @@ ENTRY(intrfastexit) cmpw $GSEL(GUCODE_SEL, SEL_UPL),TF_CS(%rsp) je .Luexit64 #ifdef XEN - cmpw $0xe033,TF_CS(%rsp) + cmpw $FLAT_RING3_CS64,TF_CS(%rsp) je .Luexit64 #endif
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Oct 28 20:06:31 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: It appears that Xen remaps the userland %cs to 0xE033. So add it to the checklist. Otherwise we're going through Luexit32: %fs gets reloaded, which sets the FS.base to NULL, which will cause the thread to page-fault next time it accesses its TLS (as seen in PR/52662). This fix is not very clean, and it would be nice to understand why Xen remaps %cs. But I'm committing it now anyway, so that people can test. To generate a diff of this commit: cvs rdiff -u -r1.138 -r1.139 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.138 src/sys/arch/amd64/amd64/locore.S:1.139 --- src/sys/arch/amd64/amd64/locore.S:1.138 Sat Oct 21 08:08:26 2017 +++ src/sys/arch/amd64/amd64/locore.S Sat Oct 28 20:06:31 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.138 2017/10/21 08:08:26 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.139 2017/10/28 20:06:31 maxv Exp $ */ /* * Copyright-o-rama! @@ -1483,6 +1483,10 @@ ENTRY(intrfastexit) je .Luexit64 cmpw $GSEL(GUCODE_SEL, SEL_UPL),TF_CS(%rsp) je .Luexit64 +#ifdef XEN + cmpw $0xe033,TF_CS(%rsp) + je .Luexit64 +#endif .Luexit32: NOT_XEN(cli;)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Oct 21 08:08:26 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S trap.c Log Message: Use labels instead of disassembling *(%rip). intrfastexit is now the only place where the segregs can fault. To generate a diff of this commit: cvs rdiff -u -r1.137 -r1.138 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.103 -r1.104 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.137 src/sys/arch/amd64/amd64/locore.S:1.138 --- src/sys/arch/amd64/amd64/locore.S:1.137 Sat Oct 21 06:55:54 2017 +++ src/sys/arch/amd64/amd64/locore.S Sat Oct 21 08:08:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.137 2017/10/21 06:55:54 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.138 2017/10/21 08:08:26 maxv Exp $ */ /* * Copyright-o-rama! @@ -330,6 +330,10 @@ .globl _C_LABEL(biosextmem) .globl _C_LABEL(lwp0uarea) .globl do_sysret + .globl do_mov_es + .globl do_mov_ds + .globl do_mov_fs + .globl do_mov_gs .globl do_iret .type _C_LABEL(tablesize), @object @@ -1196,7 +1200,7 @@ lwp_32bit: movq PCB_GS(%r14),%rax movq %rax,(GUGS_SEL*8)(%rcx) - /* Set default 32bit values in %ds, %es, %fs and %gs. */ + /* Set default 32bit values in %ds, %es and %fs. %gs is special. */ movq L_MD_REGS(%r12),%rbx movq $GSEL(GUDATA32_SEL, SEL_UPL),%rax movw %ax,%ds @@ -1482,11 +1486,15 @@ ENTRY(intrfastexit) .Luexit32: NOT_XEN(cli;) +do_mov_es: movw TF_ES(%rsp),%es +do_mov_ds: movw TF_DS(%rsp),%ds +do_mov_fs: movw TF_FS(%rsp),%fs SWAPGS #ifndef XEN +do_mov_gs: movw TF_GS(%rsp),%gs #endif jmp .Lkexit Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.103 src/sys/arch/amd64/amd64/trap.c:1.104 --- src/sys/arch/amd64/amd64/trap.c:1.103 Sat Oct 21 07:23:22 2017 +++ src/sys/arch/amd64/amd64/trap.c Sat Oct 21 08:08:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.103 2017/10/21 07:23:22 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.104 2017/10/21 08:08:26 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.103 2017/10/21 07:23:22 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.104 2017/10/21 08:08:26 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -236,6 +236,8 @@ static void trap_user_kernelmode(struct static void trap_user_kernelmode(struct trapframe *frame, int type, lwp_t *l, proc_t *p) { + extern uint64_t do_mov_es, do_mov_ds, do_mov_fs, do_mov_gs; + extern uint64_t do_iret; struct trapframe *vframe; ksiginfo_t ksi; @@ -260,8 +262,7 @@ trap_user_kernelmode(struct trapframe *f */ vframe = (void *)frame->tf_rsp; - switch (*(uint16_t *)frame->tf_rip) { - case 0xcf48: /* iretq */ + if (frame->tf_rip == (uint64_t)_iret) { /* * The 'iretq' instruction faulted, so we have the * 'user' registers saved after the kernel @@ -277,12 +278,10 @@ trap_user_kernelmode(struct trapframe *f memmove(vframe, frame, offsetof(struct trapframe, tf_rip)); /* Set the faulting address to the user %rip */ ksi.ksi_addr = (void *)vframe->tf_rip; - break; - - case 0x848e: /* mov 0xa8(%rsp),%es (8e 84 24 a8 00 00 00) */ - case 0x9c8e: /* mov 0xb0(%rsp),%ds (8e 9c 24 b0 00 00 00) */ - case 0xa48e: /* mov 0xa0(%rsp),%fs (8e a4 24 a0 00 00 00) */ - case 0xac8e: /* mov 0x98(%rsp),%gs (8e ac 24 98 00 00 00) */ + } else if (frame->tf_rip == (uint64_t)_mov_es || + frame->tf_rip == (uint64_t)_mov_ds || + frame->tf_rip == (uint64_t)_mov_fs || + frame->tf_rip == (uint64_t)_mov_gs) { /* * We faulted loading one of the user segment registers. * The stack frame containing the user registers is @@ -291,9 +290,7 @@ trap_user_kernelmode(struct trapframe *f if (KERNELMODE(vframe->tf_cs)) return; /* There is no valid address for the fault */ - break; - - default: + } else { return; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Oct 21 07:23:22 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: Handle by default. To generate a diff of this commit: cvs rdiff -u -r1.102 -r1.103 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.102 src/sys/arch/amd64/amd64/trap.c:1.103 --- src/sys/arch/amd64/amd64/trap.c:1.102 Tue Oct 17 06:58:15 2017 +++ src/sys/arch/amd64/amd64/trap.c Sat Oct 21 07:23:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.102 2017/10/17 06:58:15 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.103 2017/10/21 07:23:22 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.102 2017/10/17 06:58:15 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.103 2017/10/21 07:23:22 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -281,10 +281,8 @@ trap_user_kernelmode(struct trapframe *f case 0x848e: /* mov 0xa8(%rsp),%es (8e 84 24 a8 00 00 00) */ case 0x9c8e: /* mov 0xb0(%rsp),%ds (8e 9c 24 b0 00 00 00) */ -#ifdef USER_LDT case 0xa48e: /* mov 0xa0(%rsp),%fs (8e a4 24 a0 00 00 00) */ case 0xac8e: /* mov 0x98(%rsp),%gs (8e ac 24 98 00 00 00) */ -#endif /* * We faulted loading one of the user segment registers. * The stack frame containing the user registers is
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Oct 19 20:27:12 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Use cmpw. To generate a diff of this commit: cvs rdiff -u -r1.135 -r1.136 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.135 src/sys/arch/amd64/amd64/locore.S:1.136 --- src/sys/arch/amd64/amd64/locore.S:1.135 Thu Oct 19 19:05:53 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Oct 19 20:27:12 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.135 2017/10/19 19:05:53 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.136 2017/10/19 20:27:12 maxv Exp $ */ /* * Copyright-o-rama! @@ -1475,9 +1475,9 @@ ENTRY(intrfastexit) INTR_RESTORE_GPRS testq $SEL_UPL,TF_CS(%rsp) /* interrupted %cs */ jz .Lkexit - cmpq $LSEL(LUCODE_SEL, SEL_UPL),TF_CS(%rsp) + cmpw $LSEL(LUCODE_SEL, SEL_UPL),TF_CS(%rsp) je .Luexit64 - cmpq $GSEL(GUCODE_SEL, SEL_UPL),TF_CS(%rsp) + cmpw $GSEL(GUCODE_SEL, SEL_UPL),TF_CS(%rsp) je .Luexit64 .Luexit32:
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Oct 19 09:32:01 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: process_machdep.c Log Message: Make sure we don't go farther with 32bit LWPs. There appears to be some confusion in the code - in part introduced by myself -, and clearly this place is not supposed to handle 32bit LWPs. Right now we're returning EINVAL, but verily we would need to redirect these calls to their netbsd32 counterparts. To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 src/sys/arch/amd64/amd64/process_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/process_machdep.c diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.35 src/sys/arch/amd64/amd64/process_machdep.c:1.36 --- src/sys/arch/amd64/amd64/process_machdep.c:1.35 Sun Aug 13 08:07:52 2017 +++ src/sys/arch/amd64/amd64/process_machdep.c Thu Oct 19 09:32:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: process_machdep.c,v 1.35 2017/08/13 08:07:52 maxv Exp $ */ +/* $NetBSD: process_machdep.c,v 1.36 2017/10/19 09:32:01 maxv Exp $ */ /* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.35 2017/08/13 08:07:52 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.36 2017/10/19 09:32:01 maxv Exp $"); #include "opt_xen.h" #include @@ -103,6 +103,11 @@ int process_read_regs(struct lwp *l, struct reg *regs) { struct trapframe *tf = process_frame(l); + struct proc *p = l->l_proc; + + if (p->p_flag & PK_32) { + return EINVAL; + } #define copy_to_reg(reg, REG, idx) regs->regs[_REG_##REG] = tf->tf_##reg; _FRAME_GREG(copy_to_reg) @@ -114,6 +119,11 @@ process_read_regs(struct lwp *l, struct int process_read_fpregs(struct lwp *l, struct fpreg *regs, size_t *sz) { + struct proc *p = l->l_proc; + + if (p->p_flag & PK_32) { + return EINVAL; + } process_read_fpregs_xmm(l, >fxstate); @@ -123,6 +133,11 @@ process_read_fpregs(struct lwp *l, struc int process_read_dbregs(struct lwp *l, struct dbreg *regs, size_t *sz) { + struct proc *p = l->l_proc; + + if (p->p_flag & PK_32) { + return EINVAL; + } x86_dbregs_read(l, regs); @@ -133,10 +148,15 @@ int process_write_regs(struct lwp *l, const struct reg *regp) { struct trapframe *tf = process_frame(l); + struct proc *p = l->l_proc; int error; const long *regs = regp->regs; int err, trapno; + if (p->p_flag & PK_32) { + return EINVAL; + } + /* * Check for security violations. * Note that struct regs is compatible with @@ -168,6 +188,11 @@ process_write_regs(struct lwp *l, const int process_write_fpregs(struct lwp *l, const struct fpreg *regs, size_t sz) { + struct proc *p = l->l_proc; + + if (p->p_flag & PK_32) { + return EINVAL; + } process_write_fpregs_xmm(l, >fxstate); return 0; @@ -176,8 +201,13 @@ process_write_fpregs(struct lwp *l, cons int process_write_dbregs(struct lwp *l, const struct dbreg *regs, size_t sz) { + struct proc *p = l->l_proc; int error; + if (p->p_flag & PK_32) { + return EINVAL; + } + /* * Check for security violations. */ @@ -207,6 +237,11 @@ int process_set_pc(struct lwp *l, void *addr) { struct trapframe *tf = process_frame(l); + struct proc *p = l->l_proc; + + if (p->p_flag & PK_32) { + return EINVAL; + } if ((uint64_t)addr >= VM_MAXUSER_ADDRESS) return EINVAL;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Oct 17 07:48:10 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S machdep.c Log Message: Move %ds and %es into the GDT on 64bit LWPs. To generate a diff of this commit: cvs rdiff -u -r1.132 -r1.133 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.267 -r1.268 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.132 src/sys/arch/amd64/amd64/locore.S:1.133 --- src/sys/arch/amd64/amd64/locore.S:1.132 Tue Oct 17 07:33:44 2017 +++ src/sys/arch/amd64/amd64/locore.S Tue Oct 17 07:48:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.132 2017/10/17 07:33:44 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.133 2017/10/17 07:48:10 maxv Exp $ */ /* * Copyright-o-rama! @@ -1284,7 +1284,7 @@ IDTVEC(syscall) movw %es,TF_ES(%rsp) movw %fs,TF_FS(%rsp) movw %gs,TF_GS(%rsp) - movw $(LSEL(LUDATA_SEL, SEL_UPL)),TF_DS(%rsp) + movw $(GSEL(GUDATA_SEL, SEL_UPL)),TF_DS(%rsp) STI(si) do_syscall: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.267 src/sys/arch/amd64/amd64/machdep.c:1.268 --- src/sys/arch/amd64/amd64/machdep.c:1.267 Sun Oct 15 13:34:24 2017 +++ src/sys/arch/amd64/amd64/machdep.c Tue Oct 17 07:48:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.267 2017/10/15 13:34:24 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.268 2017/10/17 07:48:10 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.267 2017/10/15 13:34:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.268 2017/10/17 07:48:10 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1331,8 +1331,8 @@ setregs(struct lwp *l, struct exec_packa l->l_md.md_flags = MDL_IRET; tf = l->l_md.md_regs; - tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL); - tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL); + tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL); + tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL); cpu_segregs64_zero(l); tf->tf_rdi = 0; tf->tf_rsi = 0;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Oct 17 07:02:50 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S Log Message: fix comment, rdx, not edx To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/arch/amd64/amd64/copy.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.25 src/sys/arch/amd64/amd64/copy.S:1.26 --- src/sys/arch/amd64/amd64/copy.S:1.25 Tue Oct 17 06:58:15 2017 +++ src/sys/arch/amd64/amd64/copy.S Tue Oct 17 07:02:50 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.25 2017/10/17 06:58:15 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.26 2017/10/17 07:02:50 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -343,7 +343,7 @@ ENTRY(copyinstr) xorq %rax,%rax jmp copystr_return -2: /* edx is zero -- return EFAULT or ENAMETOOLONG. */ +2: /* rdx is zero -- return EFAULT or ENAMETOOLONG. */ callq smap_enable movq $VM_MAXUSER_ADDRESS,%r11 cmpq %r11,%rsi @@ -384,7 +384,7 @@ ENTRY(copystr) xorl %eax,%eax jmp 6f -4: /* edx is zero -- return ENAMETOOLONG. */ +4: /* rdx is zero -- return ENAMETOOLONG. */ movl $ENAMETOOLONG,%eax 6: /* Set *lencopied and return %eax. */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Oct 15 13:34:24 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Mmh, don't forget to clear the TLS gdt slots on Xen. Otherwise, when doing a lwp32->lwp64 context switch, the new lwp can use the slots to reconstruct the address of the previous lwp's TLS space (and defeat ASLR?). To generate a diff of this commit: cvs rdiff -u -r1.266 -r1.267 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.266 src/sys/arch/amd64/amd64/machdep.c:1.267 --- src/sys/arch/amd64/amd64/machdep.c:1.266 Sun Oct 15 12:49:53 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Oct 15 13:34:24 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.266 2017/10/15 12:49:53 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.267 2017/10/15 13:34:24 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.266 2017/10/15 12:49:53 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.267 2017/10/15 13:34:24 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -431,6 +431,7 @@ x86_64_tls_switch(struct lwp *l) struct cpu_info *ci = curcpu(); struct pcb *pcb = lwp_getpcb(l); struct trapframe *tf = l->l_md.md_regs; + uint64_t zero = 0; /* * Raise the IPL to IPL_HIGH. @@ -453,6 +454,8 @@ x86_64_tls_switch(struct lwp *l) setfs(tf->tf_fs); HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, tf->tf_gs); } else { + update_descriptor(()->ci_gdt[GUFS_SEL], ); + update_descriptor(()->ci_gdt[GUGS_SEL], ); setfs(0); HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, 0); HYPERVISOR_set_segment_base(SEGBASE_FS, pcb->pcb_fs);
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Oct 11 16:56:26 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Use bootspace. To generate a diff of this commit: cvs rdiff -u -r1.263 -r1.264 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.263 src/sys/arch/amd64/amd64/machdep.c:1.264 --- src/sys/arch/amd64/amd64/machdep.c:1.263 Sun Oct 8 09:06:50 2017 +++ src/sys/arch/amd64/amd64/machdep.c Wed Oct 11 16:56:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.263 2017/10/08 09:06:50 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.264 2017/10/11 16:56:26 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.263 2017/10/08 09:06:50 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.264 2017/10/11 16:56:26 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1994,16 +1994,44 @@ cpu_initclocks(void) int mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) { - extern char start, __data_start; const vaddr_t v = (vaddr_t)ptr; + vaddr_t kva, kva_end; - if (v >= (vaddr_t) && v < (vaddr_t)kern_end) { + kva = bootspace.text.va; + kva_end = kva + bootspace.text.sz; + if (v >= kva && v < kva_end) { *handled = true; - /* Either the text or rodata segment */ - if (v < (vaddr_t)&__data_start && (prot & VM_PROT_WRITE)) + if (prot & VM_PROT_WRITE) { return EFAULT; + } + return 0; + } + + kva = bootspace.rodata.va; + kva_end = kva + bootspace.rodata.sz; + if (v >= kva && v < kva_end) { + *handled = true; + if (prot & VM_PROT_WRITE) { + return EFAULT; + } + return 0; + } + + kva = bootspace.data.va; + kva_end = kva + bootspace.data.sz; + if (v >= kva && v < kva_end) { + *handled = true; + return 0; + } + + kva = bootspace.boot.va; + kva_end = kva + bootspace.boot.sz; + if (v >= kva && v < kva_end) { + *handled = true; + return 0; + } - } else if (v >= module_start && v < module_end) { + if (v >= module_start && v < module_end) { *handled = true; if (!uvm_map_checkprot(module_map, v, v + 1, prot)) return EFAULT;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Sep 28 17:35:08 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S machdep.c Log Message: Clean up, and initialize the lwp0 fields in init_x86_64. To generate a diff of this commit: cvs rdiff -u -r1.129 -r1.130 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.260 -r1.261 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.129 src/sys/arch/amd64/amd64/locore.S:1.130 --- src/sys/arch/amd64/amd64/locore.S:1.129 Fri Sep 15 17:32:12 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Sep 28 17:35:08 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.129 2017/09/15 17:32:12 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.130 2017/09/28 17:35:08 maxv Exp $ */ /* * Copyright-o-rama! @@ -328,6 +328,7 @@ .globl _C_LABEL(bootinfo) .globl _C_LABEL(biosbasemem) .globl _C_LABEL(biosextmem) + .globl _C_LABEL(lwp0uarea) .globl do_sysret .globl do_iret @@ -369,6 +370,9 @@ LABEL(biosextmem) .long 0 /* extended me LABEL(biosextmem) .long REALEXTMEM #endif END(biosextmem) + .type _C_LABEL(lwp0uarea), @object +LABEL(lwp0uarea) .quad 0 +END(lwp0uarea) #ifndef XEN .globl gdt64_lo @@ -872,9 +876,8 @@ longmode_hi: /* Set up bootstrap stack. */ leaq (PROC0_STK_OFF)(%rsi),%rax addq %r8,%rax - movq %rax,(_C_LABEL(lwp0)+L_PCB)(%rip) /* XXX L_PCB != uarea */ + movq %rax,_C_LABEL(lwp0uarea)(%rip) leaq (USPACE-FRAMESIZE)(%rax),%rsp - movq %rsi,PCB_CR3(%rax) /* pcb->pcb_cr3 */ xorq %rbp,%rbp /* mark end of frames */ xorw %ax,%ax @@ -954,7 +957,7 @@ longmode_hi: * use it as the UAREA, and set up the stack here. */ movq %rax,%rsi - movq %rsi,(_C_LABEL(lwp0)+L_PCB) /* XXX L_PCB != uarea */ + movq %rsi,_C_LABEL(lwp0uarea)(%rip) leaq (USPACE-FRAMESIZE)(%rsi),%rsp xorq %rbp,%rbp Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.260 src/sys/arch/amd64/amd64/machdep.c:1.261 --- src/sys/arch/amd64/amd64/machdep.c:1.260 Tue Jul 25 17:43:44 2017 +++ src/sys/arch/amd64/amd64/machdep.c Thu Sep 28 17:35:08 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: machdep.c,v 1.260 2017/07/25 17:43:44 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.261 2017/09/28 17:35:08 maxv Exp $ */ -/*- +/* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 * The NetBSD Foundation, Inc. * All rights reserved. @@ -73,10 +73,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * */ -/*- +/* * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. * All rights reserved. * @@ -111,7 +110,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.260 2017/07/25 17:43:44 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.261 2017/09/28 17:35:08 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1439,7 +1438,7 @@ cpu_init_idt(void) struct region_descriptor region; setregion(, idt, NIDT * sizeof(idt[0]) - 1); - lidt(); + lidt(); #else if (HYPERVISOR_set_trap_table(xen_idt)) panic("HYPERVISOR_set_trap_table() failed"); @@ -1495,6 +1494,7 @@ init_x86_64(paddr_t first_avail) struct mem_segment_descriptor *ldt_segp; int x; struct pcb *pcb; + extern vaddr_t lwp0uarea; #ifndef XEN extern paddr_t local_apic_pa; int ist; @@ -1505,9 +1505,9 @@ init_x86_64(paddr_t first_avail) #ifdef XEN KASSERT(HYPERVISOR_shared_info != NULL); cpu_info_primary.ci_vcpu = _shared_info->vcpu_info[0]; +#endif - __PRINTK(("init_x86_64(0x%lx)\n", first_avail)); -#endif /* XEN */ + uvm_lwp_setuarea(, lwp0uarea); cpu_probe(_info_primary); cpu_init_msrs(_info_primary, true); @@ -1518,7 +1518,8 @@ init_x86_64(paddr_t first_avail) #ifdef XEN mutex_init(_lock, MUTEX_DEFAULT, IPL_VM); pcb->pcb_cr3 = xen_start_info.pt_base - KERNBASE; - __PRINTK(("pcb_cr3 0x%lx\n", xen_start_info.pt_base - KERNBASE)); +#else + pcb->pcb_cr3 = PDPpaddr; #endif #if NISA > 0 || NPCI > 0 @@ -1790,7 +1791,7 @@ cpu_reset(void) * invalid and causing a fault. */ kpreempt_disable(); - pmap_changeprot_local(idt_vaddr, VM_PROT_READ|VM_PROT_WRITE); + pmap_changeprot_local(idt_vaddr, VM_PROT_READ|VM_PROT_WRITE); memset((void *)idt, 0, NIDT * sizeof(idt[0])); kpreempt_enable(); breakpoint(); @@ -1801,7 +1802,7 @@ cpu_reset(void) * entire address space and doing a TLB flush. */ memset((void *)PTD, 0, PAGE_SIZE); - tlbflush(); + tlbflush(); #endif #endif /* XEN */ @@ -2041,7 +2042,6 @@ cpu_fsgs_reload(struct lwp *l, int fssel kpreempt_enable(); } - #ifdef __HAVE_DIRECT_MAP bool mm_md_direct_mapped_io(void *addr, paddr_t *paddr)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Sep 15 17:22:09 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: Obviously, I was being absolutely dumb here; it's XEN, not Xen. To generate a diff of this commit: cvs rdiff -u -r1.99 -r1.100 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.99 src/sys/arch/amd64/amd64/trap.c:1.100 --- src/sys/arch/amd64/amd64/trap.c:1.99 Sun Sep 3 09:19:51 2017 +++ src/sys/arch/amd64/amd64/trap.c Fri Sep 15 17:22:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.99 2017/09/03 09:19:51 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.100 2017/09/15 17:22:09 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 2017/09/03 09:19:51 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.100 2017/09/15 17:22:09 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -230,7 +230,7 @@ nmitrap(struct trapframe *frame) * Such traps can be triggered when the kernel fails to return to userland, * because of incorrect segment registers. */ -#ifndef Xen +#ifndef XEN static void trap_user_kernelmode(struct trapframe *, int, lwp_t *, proc_t *); static void
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Sep 10 10:51:13 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: simplify To generate a diff of this commit: cvs rdiff -u -r1.42 -r1.43 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.42 src/sys/arch/amd64/amd64/gdt.c:1.43 --- src/sys/arch/amd64/amd64/gdt.c:1.42 Wed Sep 6 12:39:18 2017 +++ src/sys/arch/amd64/amd64/gdt.c Sun Sep 10 10:51:13 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.42 2017/09/06 12:39:18 bouyer Exp $ */ +/* $NetBSD: gdt.c,v 1.43 2017/09/10 10:51:13 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.42 2017/09/06 12:39:18 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.43 2017/09/10 10:51:13 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -300,12 +300,12 @@ void lgdt(struct region_descriptor *desc) { paddr_t frames[16]; - int i; + size_t i; vaddr_t va; /* - * XXX: Xen even checks descriptors AFTER limit. - * Zero out last frame after limit if needed. + * Xen even checks descriptors AFTER limit. Zero out last frame after + * limit if needed. */ va = desc->rd_base + desc->rd_limit + 1; memset((void *)va, 0, roundup(va, PAGE_SIZE) - va); @@ -315,11 +315,10 @@ lgdt(struct region_descriptor *desc) * Xen. Mark pages R/O too, otherwise Xen will refuse to use them. */ for (i = 0; i < roundup(desc->rd_limit, PAGE_SIZE) >> PAGE_SHIFT; i++) { - frames[i] = ((paddr_t) xpmap_ptetomach( - (pt_entry_t *)(desc->rd_base + (i << PAGE_SHIFT >> + va = desc->rd_base + (i << PAGE_SHIFT); + frames[i] = ((paddr_t)xpmap_ptetomach((pt_entry_t *)va)) >> PAGE_SHIFT; - pmap_pte_clearbits(kvtopte(desc->rd_base + (i << PAGE_SHIFT)), - PG_RW); + pmap_pte_clearbits(kvtopte(va), PG_RW); } if (HYPERVISOR_set_gdt(frames, (desc->rd_limit + 1) >> 3))
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Sep 3 09:19:51 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: Declare onfault_restore, and be stricter with SMEP. To generate a diff of this commit: cvs rdiff -u -r1.98 -r1.99 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.98 src/sys/arch/amd64/amd64/trap.c:1.99 --- src/sys/arch/amd64/amd64/trap.c:1.98 Sun Sep 3 09:01:03 2017 +++ src/sys/arch/amd64/amd64/trap.c Sun Sep 3 09:19:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.98 2017/09/03 09:01:03 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.99 2017/09/03 09:19:51 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.98 2017/09/03 09:01:03 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 2017/09/03 09:19:51 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -153,6 +153,13 @@ int trap_types = __arraycount(trap_type) #define IDTVEC(name) __CONCAT(X, name) +static void +onfault_restore(struct trapframe *frame, void *onfault, int error) +{ + frame->tf_rip = (uintptr_t)onfault; + frame->tf_rax = error; +} + static void * onfault_handler(const struct pcb *pcb, const struct trapframe *tf) { @@ -405,11 +412,7 @@ trap(struct trapframe *frame) /* Check for copyin/copyout fault. */ onfault = onfault_handler(pcb, frame); if (onfault != NULL) { -copyefault: - error = EFAULT; -copyfault: - frame->tf_rip = (uintptr_t)onfault; - frame->tf_rax = error; + onfault_restore(frame, onfault, EFAULT); return; } @@ -537,7 +540,8 @@ copyfault: */ onfault = pcb->pcb_onfault; if (onfault == fusuintrfailure) { - goto copyefault; + onfault_restore(frame, fusuintrfailure, EFAULT); + return; } if (cpu_intr_p() || (l->l_pflag & LP_INTR) != 0) { goto we_re_toast; @@ -547,7 +551,7 @@ copyfault: if (frame->tf_err & PGEX_X) { /* SMEP might have brought us here */ - if (cr2 > VM_MIN_ADDRESS && cr2 <= VM_MAXUSER_ADDRESS) + if (cr2 < VM_MAXUSER_ADDRESS) panic("prevented execution of %p (SMEP)", (void *)cr2); } @@ -658,8 +662,11 @@ faultcommon: if (type == T_PAGEFLT) { onfault = onfault_handler(pcb, frame); - if (onfault != NULL) -goto copyfault; + if (onfault != NULL) { +onfault_restore(frame, onfault, error); +return; + } + printf("uvm_fault(%p, 0x%lx, %d) -> %x\n", map, va, ftype, error); goto we_re_toast;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Sep 3 09:01:03 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: Treat page faults from iretq/etc as fatal, otherwise we could hide kernel stack bugs. Note that it would be good to call check_swapgs from trap0e, but a few things need to be fixed before that. To generate a diff of this commit: cvs rdiff -u -r1.97 -r1.98 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.97 src/sys/arch/amd64/amd64/trap.c:1.98 --- src/sys/arch/amd64/amd64/trap.c:1.97 Sun Sep 3 08:52:18 2017 +++ src/sys/arch/amd64/amd64/trap.c Sun Sep 3 09:01:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.97 2017/09/03 08:52:18 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.98 2017/09/03 09:01:03 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.97 2017/09/03 08:52:18 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.98 2017/09/03 09:01:03 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -401,6 +401,7 @@ trap(struct trapframe *frame) case T_TSSFLT: if (p == NULL) goto we_re_toast; + /* Check for copyin/copyout fault. */ onfault = onfault_handler(pcb, frame); if (onfault != NULL) { @@ -412,7 +413,6 @@ copyfault: return; } -kernelfault: trap_user_kernelmode(frame, type, l, p); goto we_re_toast; @@ -662,7 +662,7 @@ faultcommon: goto copyfault; printf("uvm_fault(%p, 0x%lx, %d) -> %x\n", map, va, ftype, error); - goto kernelfault; + goto we_re_toast; } KSI_INIT_TRAP();
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Aug 31 15:41:14 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: check sc_eip in the ldt branch too To generate a diff of this commit: cvs rdiff -u -r1.107 -r1.108 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.107 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.108 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.107 Tue Jul 25 18:03:56 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Thu Aug 31 15:41:14 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.107 2017/07/25 18:03:56 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.108 2017/08/31 15:41:14 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.107 2017/07/25 18:03:56 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.108 2017/08/31 15:41:14 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1076,10 +1076,11 @@ check_sigcontext32(struct lwp *l, const return EINVAL; if (!VALID_USER_DSEL32(scp->sc_ds) || !VALID_USER_DSEL32(scp->sc_ss)) return EINVAL; - if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) - return EINVAL; } + if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) + return EINVAL; + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Aug 31 10:30:58 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S locore.S Log Message: Add a layer of mitigation against the intel sysret vuln: restore %gs when sysretq faults. Right now we try to make sure that %rip is canonical by performing sanity checks in several places, but I've already found missing checks two times already, and there may be others. By performing an additional swapgs here, we are turning ring0 exploits to simple DoSes - which are still security bugs, but of a lower impact. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/amd64/amd64/amd64_trap.S cvs rdiff -u -r1.127 -r1.128 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.8 src/sys/arch/amd64/amd64/amd64_trap.S:1.9 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.8 Thu Aug 31 09:33:19 2017 +++ src/sys/arch/amd64/amd64/amd64_trap.S Thu Aug 31 10:30:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: amd64_trap.S,v 1.8 2017/08/31 09:33:19 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.9 2017/08/31 10:30:58 maxv Exp $ */ /* * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ #if 0 #include -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.8 2017/08/31 09:33:19 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.9 2017/08/31 10:30:58 maxv Exp $"); #endif /* @@ -378,7 +378,13 @@ NENTRY(check_swapgs) /* * Trap in kernel mode. */ - /* Case 1: fault on iretq? */ + + /* Case 1: fault on sysretq? */ + leaq do_sysret(%rip),%rdi + cmpq %rdi,TF_RIP(%rsp) + je 1b + + /* Case 2: fault on iretq? */ movq TF_RIP(%rsp),%rax cmpw $0xcf48,(%rax) /* Faulting instruction is iretq ? */ jne 5f /* Jump if not */ @@ -388,7 +394,7 @@ NENTRY(check_swapgs) jmp 1b /* to user - must restore %gs */ 5: - /* Case 2: move to %gs? */ + /* Case 3: move to %gs? */ movw (%rax),%ax andb $070,%ah /* mask mod/rm from mod/reg/rm */ cmpw $0x8e+050*256,%ax /* Any move to %gs (reg 5) */ Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.127 src/sys/arch/amd64/amd64/locore.S:1.128 --- src/sys/arch/amd64/amd64/locore.S:1.127 Thu Aug 31 09:27:28 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Aug 31 10:30:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.127 2017/08/31 09:27:28 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.128 2017/08/31 10:30:58 maxv Exp $ */ /* * Copyright-o-rama! @@ -328,6 +328,7 @@ .globl _C_LABEL(bootinfo) .globl _C_LABEL(biosbasemem) .globl _C_LABEL(biosextmem) + .globl do_sysret .type _C_LABEL(tablesize), @object _C_LABEL(tablesize): .long TABLESIZE @@ -1313,6 +1314,7 @@ do_syscall: movq TF_RIP(%rsp),%rcx /* %rip for sysret */ movq TF_RFLAGS(%rsp),%r11 /* %flags for sysret */ movq TF_RSP(%rsp),%rsp +do_sysret: sysretq #else addq $TF_RIP,%rsp
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Aug 31 09:33:19 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S Log Message: Reorder for clarity, and style. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/arch/amd64/amd64/amd64_trap.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.7 src/sys/arch/amd64/amd64/amd64_trap.S:1.8 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.7 Fri Aug 18 14:52:19 2017 +++ src/sys/arch/amd64/amd64/amd64_trap.S Thu Aug 31 09:33:19 2017 @@ -1,11 +1,11 @@ -/* $NetBSD: amd64_trap.S,v 1.7 2017/08/18 14:52:19 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.8 2017/08/31 09:33:19 maxv Exp $ */ -/*- - * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. +/* + * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum and by Andrew Doran. + * by Charles M. Hannum, by Andrew Doran and by Maxime Villard. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,7 +66,7 @@ #if 0 #include -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.7 2017/08/18 14:52:19 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.8 2017/08/31 09:33:19 maxv Exp $"); #endif /* @@ -78,12 +78,12 @@ __KERNEL_RCSID(0, "$NetBSD: amd64_trap.S * (possibly the next clock tick). Thus, we disable interrupt before checking, * and only enable them again on the final `iret' or before calling the AST * handler. - */ + */ /*/ #ifdef XEN -#define PRE_TRAP movq (%rsp),%rcx ; movq 8(%rsp),%r11 ; addq $0x10,%rsp +#define PRE_TRAP movq (%rsp),%rcx ; movq 8(%rsp),%r11 ; addq $0x10,%rsp #else #define PRE_TRAP #endif @@ -214,7 +214,7 @@ IDTVEC(trap07) INTRENTRY #ifdef DIAGNOSTIC movl CPUVAR(ILEVEL),%ebx -#endif /* DIAGNOSTIC */ +#endif movq %rsp,%rdi call _C_LABEL(fpudna) jmp .Lalltraps_checkusr @@ -253,43 +253,7 @@ IDTVEC_END(trap0c) IDTVEC(trap0d) /* #GP() General protection */ TRAP_NJ(T_PROTFLT) -#ifdef check_swapgs jmp check_swapgs -#else -/* - * We need to worry about traps in kernel mode while the kernel %gs isn't - * loaded. These are either faults on iretq during return to user or loads to - * %gs. - * - * When such traps happen, we have CPL=0 and %gs=userland, and we must perform - * an additional swapgs to get %gs=kernel. - */ -check_swapgs: - INTRENTRY_L(3f,1:) -2: - sti - jmp calltrap -3: - /* - * Trap in kernel mode. - */ - /* Case 1: fault on iretq? */ - movq TF_RIP(%rsp),%rax - cmpw $0xcf48,(%rax) /* Faulting instruction is iretq ? */ - jne 5f /* Jump if not */ - movq TF_RSP(%rsp),%rax /* Must read %rsp, may be a pad word */ - testb $SEL_UPL,8(%rax) /* Check %cs of outer iret frame */ - je 2b /* jump if iret was to kernel */ - jmp 1b /* to user - must restore %gs */ -5: - - /* Case 2: move to %gs? */ - movw (%rax),%ax - andb $070,%ah /* mask mod/rm from mod/reg/rm */ - cmpw $0x8e+050*256,%ax /* Any move to %gs (reg 5) */ - jne 2b /* No - normal kernel fault */ - jmp 1b /* Yes - restore %gs */ -#endif IDTVEC_END(trap0d) IDTVEC(trap0e) @@ -302,7 +266,7 @@ IDTVEC(trap0f) INTRENTRY #ifdef DIAGNOSTIC movl CPUVAR(ILEVEL),%ebx -#endif /* DIAGNOSTIC */ +#endif jmp .Lalltraps_checkusr IDTVEC_END(trap0f) IDTVEC_END(intrspurious) @@ -313,7 +277,7 @@ IDTVEC(trap10) INTRENTRY #ifdef DIAGNOSTIC movl CPUVAR(ILEVEL),%ebx -#endif /* DIAGNOSTIC */ +#endif movq %rsp,%rdi call _C_LABEL(fputrap) jmp .Lalltraps_checkusr @@ -380,9 +344,9 @@ IDTVEC_END(exceptions) /* * trap() calls here when it detects a fault in INTRFASTEXIT (loading the - * segment registers or during the iret itself). - * The address of the (possibly reconstructed) user trap frame is - * passed as an argument. + * segment registers or during the iret itself). The address of the (possibly + * reconstructed) user trap frame is passed as an argument. + * * Typically the code will have raised a SIGSEGV which will be actioned * by the code below. */ @@ -392,10 +356,47 @@ LABEL(trap_return_fault_return) #ifdef DIAGNOSTIC /* We can't recover the saved %rbx, so suppress warning */ movl CPUVAR(ILEVEL),%ebx -#endif /* DIAGNOSTIC */ +#endif jmp .Lalltraps_checkusr END(trap_return_fault_return) +#ifndef check_swapgs +/* + * We need to worry about traps in kernel mode while the kernel %gs isn't + * loaded. These are either faults on iretq during return to user or loads to + * %gs. + * + * When such traps happen, we have CPL=0 and %gs=userland, and we must perform + * an additional swapgs to get %gs=kernel. + */ +NENTRY(check_swapgs) +
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Aug 31 09:27:28 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Construct the trap frame with interrupts disabled, for safety, just like the rest of the interrupt entry points. To generate a diff of this commit: cvs rdiff -u -r1.126 -r1.127 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.126 src/sys/arch/amd64/amd64/locore.S:1.127 --- src/sys/arch/amd64/amd64/locore.S:1.126 Thu Aug 10 12:49:11 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Aug 31 09:27:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.126 2017/08/10 12:49:11 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.127 2017/08/31 09:27:28 maxv Exp $ */ /* * Copyright-o-rama! @@ -1264,28 +1264,19 @@ IDTVEC(syscall) movq $2,TF_ERR(%rsp) /* syscall instruction size */ movq $T_ASTFLT,TF_TRAPNO(%rsp) - - movw %es,TF_ES(%rsp) - sti - INTR_SAVE_GPRS - movw %fs,TF_FS(%rsp) - movw %gs,TF_GS(%rsp) - movw $(LSEL(LUDATA_SEL, SEL_UPL)),TF_DS(%rsp) #else /* Xen already switched to kernel stack */ - pushq %rsi - STI(si) - popq %rsi addq $0x10,%rsp /* gap to match cs:rip */ pushq $2 /* error code */ pushq $T_ASTFLT subq $TF_REGSIZE,%rsp +#endif INTR_SAVE_GPRS + movw %es,TF_ES(%rsp) movw %fs,TF_FS(%rsp) movw %gs,TF_GS(%rsp) - movw %es,TF_ES(%rsp) movw $(LSEL(LUDATA_SEL, SEL_UPL)),TF_DS(%rsp) -#endif + STI(si) do_syscall: movq CPUVAR(CURLWP),%r14
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Aug 25 11:35:03 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S Log Message: Move incq outside of the copy section. No functional change, reduces my smap diff. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/arch/amd64/amd64/copy.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.23 src/sys/arch/amd64/amd64/copy.S:1.24 --- src/sys/arch/amd64/amd64/copy.S:1.23 Fri Aug 25 11:05:46 2017 +++ src/sys/arch/amd64/amd64/copy.S Fri Aug 25 11:35:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.23 2017/08/25 11:05:46 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.24 2017/08/25 11:35:03 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -259,10 +259,9 @@ ENTRY(copyoutstr) jae 1f movq %rax,%rdx movq %rax,%r8 - -.Lcopyoutstr_start: 1: incq %rdx +.Lcopyoutstr_start: 1: decq %rdx jz 2f lodsb @@ -300,10 +299,9 @@ ENTRY(copyinstr) jae 1f movq %rax,%rdx movq %rax,%r8 - -.Lcopyinstr_start: 1: incq %rdx +.Lcopyinstr_start: 1: decq %rdx jz 2f lodsb
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Aug 25 11:05:46 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S Log Message: Split comment, otherwise it is misleading. kcopy operates on kernel memory, and must *not* be used with userland pages. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/arch/amd64/amd64/copy.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.22 src/sys/arch/amd64/amd64/copy.S:1.23 --- src/sys/arch/amd64/amd64/copy.S:1.22 Wed Aug 23 08:14:18 2017 +++ src/sys/arch/amd64/amd64/copy.S Fri Aug 25 11:05:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.22 2017/08/23 08:14:18 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.23 2017/08/25 11:05:46 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -107,9 +107,6 @@ ENTRY(do_pmap_load) ret /* - * int kcopy(const void *from, void *to, size_t len); - * Copy len bytes, abort on fault. - * * Copy routines from and to userland, plus a few more. See the * section 9 manpages for info. Some cases can be optimized more. * @@ -125,6 +122,10 @@ ENTRY(do_pmap_load) * be ably to do cache-line size copies */ +/* + * int kcopy(const void *from, void *to, size_t len); + * Copy len bytes from and to kernel memory, and abort on fault. + */ ENTRY(kcopy) xchgq %rdi,%rsi movq %rdx,%rcx
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Aug 23 08:14:18 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S Log Message: style, reduces an incoming diff To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/arch/amd64/amd64/copy.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.21 src/sys/arch/amd64/amd64/copy.S:1.22 --- src/sys/arch/amd64/amd64/copy.S:1.21 Wed Aug 23 08:04:22 2017 +++ src/sys/arch/amd64/amd64/copy.S Wed Aug 23 08:14:18 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.21 2017/08/23 08:04:22 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.22 2017/08/23 08:14:18 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -44,8 +44,8 @@ #include #define GET_CURPCB(reg) \ - movq CPUVAR(CURLWP), reg; \ - movq L_PCB(reg), reg + movq CPUVAR(CURLWP),reg; \ + movq L_PCB(reg),reg /* * These are arranged so that the abnormal case is a forwards @@ -55,10 +55,10 @@ #define DEFERRED_SWITCH_CHECK \ CHECK_DEFERRED_SWITCH ; \ jnz 99f; \ -98: +98: #define DEFERRED_SWITCH_CALL \ -99: ; \ +99: ; \ call _C_LABEL(do_pmap_load) ; \ jmp 98b @@ -85,18 +85,18 @@ ENTRY(do_pmap_load) pushq %rdx pushq %rcx pushq %rbx - movq CPUVAR(CURLWP), %rbx + movq CPUVAR(CURLWP),%rbx 1: incl L_NOPREEMPT(%rbx) call _C_LABEL(pmap_load) decl L_NOPREEMPT(%rbx) jnz 2f - cmpl $0, L_DOPREEMPT(%rbx) + cmpl $0,L_DOPREEMPT(%rbx) jz 2f - xorq %rdi, %rdi + xorq %rdi,%rdi call _C_LABEL(kpreempt) 2: - cmpl $0, CPUVAR(WANT_PMAPLOAD) + cmpl $0,CPUVAR(WANT_PMAPLOAD) jnz 1b popq %rbx popq %rcx @@ -194,6 +194,7 @@ ENTRY(copyout) rep movsb/* copy remaining bytes */ .Lcopyout_end: + xorl %eax,%eax ret DEFERRED_SWITCH_CALL @@ -221,6 +222,7 @@ ENTRY(copyin) rep movsb .Lcopyin_end: + xorl %eax,%eax ret DEFERRED_SWITCH_CALL @@ -256,6 +258,7 @@ ENTRY(copyoutstr) jae 1f movq %rax,%rdx movq %rax,%r8 + .Lcopyoutstr_start: 1: incq %rdx @@ -266,6 +269,7 @@ ENTRY(copyoutstr) testb %al,%al jnz 1b .Lcopyoutstr_end: + /* Success -- 0 byte reached. */ decq %rdx xorq %rax,%rax @@ -295,6 +299,7 @@ ENTRY(copyinstr) jae 1f movq %rax,%rdx movq %rax,%r8 + .Lcopyinstr_start: 1: incq %rdx @@ -363,7 +368,7 @@ ENTRY(copystr) ENTRY(fuswintr) - cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE) + cmpl $TLBSTATE_VALID,CPUVAR(TLBSTATE) jnz _C_LABEL(fusuaddrfault) movq $VM_MAXUSER_ADDRESS-2,%r11 cmpq %r11,%rdi @@ -371,7 +376,9 @@ ENTRY(fuswintr) GET_CURPCB(%rcx) leaq _C_LABEL(fusuintrfailure)(%rip),%r11 movq %r11,PCB_ONFAULT(%rcx) + movzwl (%rdi),%eax + movq $0,PCB_ONFAULT(%rcx) ret @@ -383,13 +390,15 @@ ENTRY(fubyte) GET_CURPCB(%rcx) leaq _C_LABEL(fusufailure)(%rip),%r11 movq %r11,PCB_ONFAULT(%rcx) + movzbl (%rdi),%eax + movq $0,PCB_ONFAULT(%rcx) ret DEFERRED_SWITCH_CALL ENTRY(suswintr) - cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE) + cmpl $TLBSTATE_VALID,CPUVAR(TLBSTATE) jnz _C_LABEL(fusuaddrfault) movq $VM_MAXUSER_ADDRESS-2,%r11 cmpq %r11,%rdi @@ -397,7 +406,9 @@ ENTRY(suswintr) GET_CURPCB(%rcx) leaq _C_LABEL(fusuintrfailure)(%rip),%r11 movq %r11,PCB_ONFAULT(%rcx) + movw %si,(%rdi) + xorq %rax,%rax movq %rax,PCB_ONFAULT(%rcx) ret @@ -413,6 +424,7 @@ ENTRY(subyte) movq %r11,PCB_ONFAULT(%rcx) movb %sil,(%rdi) + xorq %rax,%rax movq %rax,PCB_ONFAULT(%rcx) ret @@ -444,21 +456,23 @@ ENTRY(fusuaddrfault) ENTRY(ucas_64) DEFERRED_SWITCH_CHECK /* Fail if kernel-space */ - movq $VM_MAXUSER_ADDRESS-8, %r8 - cmpq %r8, %rdi + movq $VM_MAXUSER_ADDRESS-8,%r8 + cmpq %r8,%rdi ja _C_LABEL(ucas_efault) - movq %rsi, %rax + movq %rsi,%rax + .Lucas64_start: /* Perform the CAS */ lock - cmpxchgq %rdx, (%rdi) + cmpxchgq %rdx,(%rdi) .Lucas64_end: + /* * Note: %rax is "old" value. * Set the return values. */ - movq %rax, (%rcx) - xorq %rax, %rax + movq %rax,(%rcx) + xorq %rax,%rax ret DEFERRED_SWITCH_CALL @@ -468,21 +482,23 @@ ENTRY(ucas_64) ENTRY(ucas_32) DEFERRED_SWITCH_CHECK /* Fail if kernel-space */ - movq $VM_MAXUSER_ADDRESS-4, %r8 - cmpq %r8, %rdi + movq $VM_MAXUSER_ADDRESS-4,%r8 + cmpq %r8,%rdi ja _C_LABEL(ucas_efault) - movl %esi, %eax + movl %esi,%eax + .Lucas32_start: /* Perform the CAS */ lock - cmpxchgl %edx, (%rdi) + cmpxchgl %edx,(%rdi) .Lucas32_end: + /* * Note: %eax is "old" value. * Set the return values. */ - movl %eax, (%rcx) - xorq %rax, %rax + movl %eax,(%rcx) + xorq %rax,%rax ret DEFERRED_SWITCH_CALL
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Aug 23 08:04:22 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: copy.S Log Message: Fix a bug in ucas_32 and ucas_64. There is a branch where they don't initialize %rax. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/arch/amd64/amd64/copy.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.20 src/sys/arch/amd64/amd64/copy.S:1.21 --- src/sys/arch/amd64/amd64/copy.S:1.20 Wed Dec 9 16:55:18 2015 +++ src/sys/arch/amd64/amd64/copy.S Wed Aug 23 08:04:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.20 2015/12/09 16:55:18 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.21 2017/08/23 08:04:22 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -446,7 +446,7 @@ ENTRY(ucas_64) /* Fail if kernel-space */ movq $VM_MAXUSER_ADDRESS-8, %r8 cmpq %r8, %rdi - ja _C_LABEL(ucas_fault) + ja _C_LABEL(ucas_efault) movq %rsi, %rax .Lucas64_start: /* Perform the CAS */ @@ -470,7 +470,7 @@ ENTRY(ucas_32) /* Fail if kernel-space */ movq $VM_MAXUSER_ADDRESS-4, %r8 cmpq %r8, %rdi - ja _C_LABEL(ucas_fault) + ja _C_LABEL(ucas_efault) movl %esi, %eax .Lucas32_start: /* Perform the CAS */ @@ -486,10 +486,9 @@ ENTRY(ucas_32) ret DEFERRED_SWITCH_CALL -/* - * Fault handler for ucas_*(). - * Just return the error set by trap(). - */ +ENTRY(ucas_efault) + movq $EFAULT,%rax + NENTRY(ucas_fault) ret
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 13 08:07:52 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: process_machdep.c Log Message: Mmh, restore %cs and %ss on Xen. Otherwise (unpriv) userland could set a non-three ring, causing the hypervisor to send a fatal interrupt to the kernel. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/arch/amd64/amd64/process_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/process_machdep.c diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.34 src/sys/arch/amd64/amd64/process_machdep.c:1.35 --- src/sys/arch/amd64/amd64/process_machdep.c:1.34 Sun Aug 13 07:16:44 2017 +++ src/sys/arch/amd64/amd64/process_machdep.c Sun Aug 13 08:07:52 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: process_machdep.c,v 1.34 2017/08/13 07:16:44 maxv Exp $ */ +/* $NetBSD: process_machdep.c,v 1.35 2017/08/13 08:07:52 maxv Exp $ */ /* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -74,8 +74,9 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.34 2017/08/13 07:16:44 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.35 2017/08/13 08:07:52 maxv Exp $"); +#include "opt_xen.h" #include #include #include @@ -155,6 +156,12 @@ process_write_regs(struct lwp *l, const tf->tf_err = err; tf->tf_trapno = trapno; +#ifdef XEN + /* see comment in cpu_setmcontext */ + tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL); + tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL); +#endif + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 13 07:16:44 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: process_machdep.c Log Message: Remove unused include, remove dead code, KNF, and fix off-by-one. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/sys/arch/amd64/amd64/process_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/process_machdep.c diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.33 src/sys/arch/amd64/amd64/process_machdep.c:1.34 --- src/sys/arch/amd64/amd64/process_machdep.c:1.33 Tue Aug 8 17:27:34 2017 +++ src/sys/arch/amd64/amd64/process_machdep.c Sun Aug 13 07:16:44 2017 @@ -1,6 +1,6 @@ -/* $NetBSD: process_machdep.c,v 1.33 2017/08/08 17:27:34 maxv Exp $ */ +/* $NetBSD: process_machdep.c,v 1.34 2017/08/13 07:16:44 maxv Exp $ */ -/*- +/* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. * All rights reserved. * @@ -71,19 +71,16 @@ * * process_set_pc(proc) * Set the process's program counter. - * */ - #include -__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.33 2017/08/08 17:27:34 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.34 2017/08/13 07:16:44 maxv Exp $"); #include #include #include #include #include -#include #include #include @@ -93,16 +90,12 @@ __KERNEL_RCSID(0, "$NetBSD: process_mach #include static inline struct trapframe *process_frame(struct lwp *); -#if 0 -static inline int verr_gdt(struct pmap *, int sel); -static inline int verr_ldt(struct pmap *, int sel); -#endif static inline struct trapframe * process_frame(struct lwp *l) { - return (l->l_md.md_regs); + return l->l_md.md_regs; } int @@ -114,7 +107,7 @@ process_read_regs(struct lwp *l, struct _FRAME_GREG(copy_to_reg) #undef copy_to_reg - return (0); + return 0; } int @@ -162,7 +155,7 @@ process_write_regs(struct lwp *l, const tf->tf_err = err; tf->tf_trapno = trapno; - return (0); + return 0; } int @@ -200,7 +193,7 @@ process_sstep(struct lwp *l, int sstep) else tf->tf_rflags &= ~PSL_T; - return (0); + return 0; } int @@ -208,9 +201,9 @@ process_set_pc(struct lwp *l, void *addr { struct trapframe *tf = process_frame(l); - if ((uint64_t)addr > VM_MAXUSER_ADDRESS) + if ((uint64_t)addr >= VM_MAXUSER_ADDRESS) return EINVAL; tf->tf_rip = (uint64_t)addr; - return (0); + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Aug 8 17:27:34 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: process_machdep.c Log Message: Mmh, don't overwrite tf_err and tf_trapno. Looks like it can be used to exploit the intel sysret vulnerability once again. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/arch/amd64/amd64/process_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/process_machdep.c diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.32 src/sys/arch/amd64/amd64/process_machdep.c:1.33 --- src/sys/arch/amd64/amd64/process_machdep.c:1.32 Thu Feb 23 03:34:22 2017 +++ src/sys/arch/amd64/amd64/process_machdep.c Tue Aug 8 17:27:34 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: process_machdep.c,v 1.32 2017/02/23 03:34:22 kamil Exp $ */ +/* $NetBSD: process_machdep.c,v 1.33 2017/08/08 17:27:34 maxv Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -76,7 +76,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.32 2017/02/23 03:34:22 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.33 2017/08/08 17:27:34 maxv Exp $"); #include #include @@ -141,6 +141,7 @@ process_write_regs(struct lwp *l, const struct trapframe *tf = process_frame(l); int error; const long *regs = regp->regs; + int err, trapno; /* * Check for security violations. @@ -151,10 +152,16 @@ process_write_regs(struct lwp *l, const if (error != 0) return error; + err = tf->tf_err; + trapno = tf->tf_trapno; + #define copy_to_frame(reg, REG, idx) tf->tf_##reg = regs[_REG_##REG]; _FRAME_GREG(copy_to_frame) #undef copy_to_frame + tf->tf_err = err; + tf->tf_trapno = trapno; + return (0); }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Aug 8 17:00:42 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Remove dumb debug code and outdated comment. To generate a diff of this commit: cvs rdiff -u -r1.124 -r1.125 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.124 src/sys/arch/amd64/amd64/locore.S:1.125 --- src/sys/arch/amd64/amd64/locore.S:1.124 Sat Jul 1 10:44:42 2017 +++ src/sys/arch/amd64/amd64/locore.S Tue Aug 8 17:00:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.124 2017/07/01 10:44:42 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.125 2017/08/08 17:00:42 maxv Exp $ */ /* * Copyright-o-rama! @@ -1082,12 +1082,6 @@ skip_save: /* Switch to newlwp's stack. */ movq L_PCB(%r12),%r14 -#ifdef XEN /* XXX debug code */ - cmpq $0,PCB_RSP(%r14) - jne 999f - callq _C_LABEL(cpu_Debugger); -999: -#endif movq PCB_RSP(%r14),%rsp movq PCB_RBP(%r14),%rbp @@ -1236,8 +1230,6 @@ IDTVEC_END(syscall32) * syscall() * * syscall insn entry. - * This currently isn't much faster, but it can be made faster in the future. - * (Actually we've already saved a few 100 clocks by not loading the trap gate) */ IDTVEC(syscall) #ifndef XEN
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Jul 25 18:03:56 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: This branch must be static, otherwise there is a condition under which the KASSERT in startlwp32 would be triggered. To generate a diff of this commit: cvs rdiff -u -r1.106 -r1.107 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.106 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.107 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.106 Sat Jul 22 13:00:42 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Tue Jul 25 18:03:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.106 2017/07/22 13:00:42 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.107 2017/07/25 18:03:56 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.106 2017/07/22 13:00:42 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.107 2017/07/25 18:03:56 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1086,37 +1086,36 @@ check_sigcontext32(struct lwp *l, const int cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp) { - struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; const __greg32_t *gr; struct trapframe *tf; - struct pcb *pcb; gr = mcp->__gregs; tf = l->l_md.md_regs; - pcb = lwp_getpcb(l); if (((gr[_REG32_EFL] ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) return EINVAL; - if (__predict_false(pmap->pm_ldt != NULL)) { - /* Only when the LDT is user-set (with USER_LDT) */ - if (!USERMODE(gr[_REG32_CS], gr[_REG32_EFL])) - return EINVAL; - } else { - if (!VALID_USER_CSEL32(gr[_REG32_CS])) - return EINVAL; - if (gr[_REG32_FS] != 0 && !VALID_USER_DSEL32(gr[_REG32_FS]) && - !(VALID_USER_FSEL32(gr[_REG32_FS]) && pcb->pcb_fs != 0)) - return EINVAL; - if (gr[_REG32_GS] != 0 && !VALID_USER_DSEL32(gr[_REG32_GS]) && - !(VALID_USER_GSEL32(gr[_REG32_GS]) && pcb->pcb_gs != 0)) - return EINVAL; - if (gr[_REG32_ES] != 0 && !VALID_USER_DSEL32(gr[_REG32_ES])) - return EINVAL; - if (!VALID_USER_DSEL32(gr[_REG32_DS]) || - !VALID_USER_DSEL32(gr[_REG32_SS])) - return EINVAL; - } +#ifdef USER_LDT + /* Userland is allowed to have unfamiliar segment register values */ + if (!USERMODE(gr[_REG32_CS], gr[_REG32_EFL])) + return EINVAL; +#else + struct pcb *pcb = lwp_getpcb(l); + + if (!VALID_USER_CSEL32(gr[_REG32_CS])) + return EINVAL; + if (gr[_REG32_FS] != 0 && !VALID_USER_DSEL32(gr[_REG32_FS]) && + !(VALID_USER_FSEL32(gr[_REG32_FS]) && pcb->pcb_fs != 0)) + return EINVAL; + if (gr[_REG32_GS] != 0 && !VALID_USER_DSEL32(gr[_REG32_GS]) && + !(VALID_USER_GSEL32(gr[_REG32_GS]) && pcb->pcb_gs != 0)) + return EINVAL; + if (gr[_REG32_ES] != 0 && !VALID_USER_DSEL32(gr[_REG32_ES])) + return EINVAL; + if (!VALID_USER_DSEL32(gr[_REG32_DS]) || + !VALID_USER_DSEL32(gr[_REG32_SS])) + return EINVAL; +#endif if (gr[_REG32_EIP] >= VM_MAXUSER_ADDRESS32) return EINVAL;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Jul 25 17:43:44 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Must not be from n32. To generate a diff of this commit: cvs rdiff -u -r1.259 -r1.260 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.259 src/sys/arch/amd64/amd64/machdep.c:1.260 --- src/sys/arch/amd64/amd64/machdep.c:1.259 Sat Jul 22 09:20:01 2017 +++ src/sys/arch/amd64/amd64/machdep.c Tue Jul 25 17:43:44 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.259 2017/07/22 09:20:01 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.260 2017/07/25 17:43:44 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.259 2017/07/22 09:20:01 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.260 2017/07/25 17:43:44 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1898,66 +1898,46 @@ cpu_setmcontext(struct lwp *l, const mco int cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp) { - struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; - struct proc *p = l->l_proc; + struct proc *p __diagused = l->l_proc; struct trapframe *tf = l->l_md.md_regs; const __greg_t *gr; uint16_t sel; + KASSERT((p->p_flag & PK_32) == 0); gr = mcp->__gregs; if (((gr[_REG_RFLAGS] ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) return EINVAL; - if (__predict_false(pmap->pm_ldt != NULL)) { - /* Only when the LDT is user-set (with USER_LDT) */ - if ((gr[_REG_DS] & 0x) == 0) - return EINVAL; -#ifndef XEN - if ((gr[_REG_SS] & 0x) == 0) - return EINVAL; - if (!USERMODE(gr[_REG_CS], gr[_REG_RFLAGS])) - return EINVAL; -#endif - } else { -#define VUD(sel) \ -((p->p_flag & PK_32) ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) -#define VUF(sel) /* XXX: Shouldn't this be FSEL32? */ \ -((p->p_flag & PK_32) ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) -#define VUG(sel) \ -((p->p_flag & PK_32) ? VALID_USER_GSEL32(sel) : VALID_USER_DSEL(sel)) -#define VUC(sel) \ -((p->p_flag & PK_32) ? VALID_USER_CSEL32(sel) : VALID_USER_CSEL(sel)) - - sel = gr[_REG_ES] & 0x; - if (sel != 0 && !VUD(sel)) - return EINVAL; - - sel = gr[_REG_FS] & 0x; - if (sel != 0 && !VUF(sel)) - return EINVAL; - - sel = gr[_REG_GS] & 0x; - if (sel != 0 && !VUG(sel)) - return EINVAL; - - sel = gr[_REG_DS] & 0x; - if (!VUD(sel)) - return EINVAL; + sel = gr[_REG_ES] & 0x; + if (sel != 0 && !VALID_USER_DSEL(sel)) + return EINVAL; + + sel = gr[_REG_FS] & 0x; + if (sel != 0 && !VALID_USER_DSEL(sel)) + return EINVAL; + + sel = gr[_REG_GS] & 0x; + if (sel != 0 && !VALID_USER_DSEL(sel)) + return EINVAL; + + sel = gr[_REG_DS] & 0x; + if (!VALID_USER_DSEL(sel)) + return EINVAL; #ifndef XEN - sel = gr[_REG_SS] & 0x; - if (!VUD(sel)) - return EINVAL; - - sel = gr[_REG_CS] & 0x; - if (!VUC(sel)) - return EINVAL; + sel = gr[_REG_SS] & 0x; + if (!VALID_USER_DSEL(sel)) + return EINVAL; + + sel = gr[_REG_CS] & 0x; + if (!VALID_USER_CSEL(sel)) + return EINVAL; #endif - } if (gr[_REG_RIP] >= VM_MAXUSER_ADDRESS) return EINVAL; + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Jul 22 13:00:42 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: Branch for USER_LDT. To generate a diff of this commit: cvs rdiff -u -r1.105 -r1.106 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.105 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.106 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.105 Thu Jun 1 02:45:05 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Sat Jul 22 13:00:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.105 2017/06/01 02:45:05 chs Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.106 2017/07/22 13:00:42 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.105 2017/06/01 02:45:05 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.106 2017/07/22 13:00:42 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1042,34 +1042,44 @@ startlwp32(void *arg) /* * For various reasons, the amd64 port can't do what the i386 port does, - * and rely on catching invalid user contexts on exit from the kernel. + * and relies on catching invalid user contexts on exit from the kernel. * These functions perform the needed checks. */ static int check_sigcontext32(struct lwp *l, const struct netbsd32_sigcontext *scp) { + struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; struct trapframe *tf; struct pcb *pcb; tf = l->l_md.md_regs; pcb = lwp_getpcb(curlwp); - if (((scp->sc_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || - !VALID_USER_CSEL32(scp->sc_cs)) - return EINVAL; - if (scp->sc_fs != 0 && !VALID_USER_DSEL32(scp->sc_fs) && - !(VALID_USER_FSEL32(scp->sc_fs) && pcb->pcb_fs != 0)) - return EINVAL; - if (scp->sc_gs != 0 && !VALID_USER_DSEL32(scp->sc_gs) && - !(VALID_USER_GSEL32(scp->sc_gs) && pcb->pcb_gs != 0)) - return EINVAL; - if (scp->sc_es != 0 && !VALID_USER_DSEL32(scp->sc_es)) - return EINVAL; - if (!VALID_USER_DSEL32(scp->sc_ds) || !VALID_USER_DSEL32(scp->sc_ss)) - return EINVAL; - if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) + if (((scp->sc_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) return EINVAL; + + if (__predict_false(pmap->pm_ldt != NULL)) { + /* Only when the LDT is user-set (with USER_LDT) */ + if (!USERMODE(scp->sc_cs, scp->sc_eflags)) + return EINVAL; + } else { + if (!VALID_USER_CSEL32(scp->sc_cs)) + return EINVAL; + if (scp->sc_fs != 0 && !VALID_USER_DSEL32(scp->sc_fs) && + !(VALID_USER_FSEL32(scp->sc_fs) && pcb->pcb_fs != 0)) + return EINVAL; + if (scp->sc_gs != 0 && !VALID_USER_DSEL32(scp->sc_gs) && + !(VALID_USER_GSEL32(scp->sc_gs) && pcb->pcb_gs != 0)) + return EINVAL; + if (scp->sc_es != 0 && !VALID_USER_DSEL32(scp->sc_es)) + return EINVAL; + if (!VALID_USER_DSEL32(scp->sc_ds) || !VALID_USER_DSEL32(scp->sc_ss)) + return EINVAL; + if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) + return EINVAL; + } + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Jul 22 09:20:01 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Must be curlwp. To generate a diff of this commit: cvs rdiff -u -r1.258 -r1.259 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.258 src/sys/arch/amd64/amd64/machdep.c:1.259 --- src/sys/arch/amd64/amd64/machdep.c:1.258 Sat Jul 22 09:01:46 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sat Jul 22 09:20:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.258 2017/07/22 09:01:46 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.259 2017/07/22 09:20:01 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.258 2017/07/22 09:01:46 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.259 2017/07/22 09:20:01 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -401,7 +401,7 @@ cpu_startup(void) cpu_init_tss(_info_primary); #if !defined(XEN) ltr(cpu_info_primary.ci_tss_sel); -#endif /* !defined(XEN) */ +#endif x86_startup(); } @@ -2001,38 +2001,33 @@ cpu_fsgs_zero(struct lwp *l) struct pcb *pcb; uint64_t zero = 0; + KASSERT(l == curlwp); + pcb = lwp_getpcb(l); - if (l == curlwp) { - kpreempt_disable(); - tf->tf_fs = 0; - tf->tf_gs = 0; - setfs(0); + + kpreempt_disable(); + tf->tf_fs = 0; + tf->tf_gs = 0; + setfs(0); #ifndef XEN - setusergs(0); + setusergs(0); #else - HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, 0); + HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, 0); #endif - if ((l->l_proc->p_flag & PK_32) == 0) { + if ((l->l_proc->p_flag & PK_32) == 0) { #ifndef XEN - wrmsr(MSR_FSBASE, 0); - wrmsr(MSR_KERNELGSBASE, 0); + wrmsr(MSR_FSBASE, 0); + wrmsr(MSR_KERNELGSBASE, 0); #else - HYPERVISOR_set_segment_base(SEGBASE_FS, 0); - HYPERVISOR_set_segment_base(SEGBASE_GS_USER, 0); + HYPERVISOR_set_segment_base(SEGBASE_FS, 0); + HYPERVISOR_set_segment_base(SEGBASE_GS_USER, 0); #endif - } - pcb->pcb_fs = 0; - pcb->pcb_gs = 0; - update_descriptor(()->ci_gdt[GUFS_SEL], ); - update_descriptor(()->ci_gdt[GUGS_SEL], ); - kpreempt_enable(); - } else { - tf->tf_fs = 0; - tf->tf_gs = 0; - pcb->pcb_fs = 0; - pcb->pcb_gs = 0; } - + pcb->pcb_fs = 0; + pcb->pcb_gs = 0; + update_descriptor(()->ci_gdt[GUFS_SEL], ); + update_descriptor(()->ci_gdt[GUGS_SEL], ); + kpreempt_enable(); } /* @@ -2047,25 +2042,23 @@ cpu_fsgs_reload(struct lwp *l, int fssel struct pcb *pcb; KASSERT(l->l_proc->p_flag & PK_32); + KASSERT(l == curlwp); + tf = l->l_md.md_regs; - if (l == curlwp) { - pcb = lwp_getpcb(l); - kpreempt_disable(); - update_descriptor(()->ci_gdt[GUFS_SEL], >pcb_fs); - update_descriptor(()->ci_gdt[GUGS_SEL], >pcb_gs); - setfs(fssel); + + pcb = lwp_getpcb(l); + kpreempt_disable(); + update_descriptor(()->ci_gdt[GUFS_SEL], >pcb_fs); + update_descriptor(()->ci_gdt[GUGS_SEL], >pcb_gs); + setfs(fssel); #ifndef XEN - setusergs(gssel); + setusergs(gssel); #else - HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gssel); + HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gssel); #endif - tf->tf_fs = fssel; - tf->tf_gs = gssel; - kpreempt_enable(); - } else { - tf->tf_fs = fssel; - tf->tf_gs = gssel; - } + tf->tf_fs = fssel; + tf->tf_gs = gssel; + kpreempt_enable(); }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Jul 2 09:02:51 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: Hide the computation in a macro. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.38 src/sys/arch/amd64/amd64/gdt.c:1.39 --- src/sys/arch/amd64/amd64/gdt.c:1.38 Sat Mar 25 15:05:16 2017 +++ src/sys/arch/amd64/amd64/gdt.c Sun Jul 2 09:02:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.38 2017/03/25 15:05:16 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.39 2017/07/02 09:02:51 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.38 2017/03/25 15:05:16 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.39 2017/07/02 09:02:51 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -57,8 +57,10 @@ __KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.38 #include #endif -#define NDYNSLOTS \ - ((MAXGDTSIZ - DYNSEL_START) / sizeof(struct sys_segment_descriptor)) +#define NSLOTS(sz) \ + ((sz - DYNSEL_START) / sizeof(struct sys_segment_descriptor)) + +#define NDYNSLOTS NSLOTS(MAXGDTSIZ) typedef struct { bool busy[NDYNSLOTS]; @@ -131,8 +133,7 @@ gdt_init(void) /* Initialize the global values */ gdt_size = MINGDTSIZ; memset(_bitmap.busy, 0, sizeof(gdt_bitmap.busy)); - gdt_bitmap.nslots = - (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); + gdt_bitmap.nslots = NSLOTS(gdt_size); old_gdt = gdtstore; @@ -234,8 +235,7 @@ gdt_grow(void) gdt_size *= 2; if (gdt_size > MAXGDTSIZ) gdt_size = MAXGDTSIZ; - gdt_bitmap.nslots = - (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); + gdt_bitmap.nslots = NSLOTS(gdt_size); for (CPU_INFO_FOREACH(cii, ci)) { for (va = (vaddr_t)(ci->ci_gdt) + old_size;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: chs Date: Mon Apr 24 17:03:43 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: restore the ability to run netbsd 1.0 32-bit executables by checking for the relevant lcall instruction in the trap handler and treating it as a syscall. To generate a diff of this commit: cvs rdiff -u -r1.95 -r1.96 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.95 src/sys/arch/amd64/amd64/trap.c:1.96 --- src/sys/arch/amd64/amd64/trap.c:1.95 Thu Mar 23 17:25:51 2017 +++ src/sys/arch/amd64/amd64/trap.c Mon Apr 24 17:03:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.95 2017/03/23 17:25:51 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.96 2017/04/24 17:03:43 chs Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -68,12 +68,14 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.95 2017/03/23 17:25:51 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.96 2017/04/24 17:03:43 chs Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" #include "opt_xen.h" #include "opt_dtrace.h" +#include "opt_compat_netbsd.h" +#include "opt_compat_netbsd32.h" #include #include @@ -90,6 +92,11 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.9 #include +#ifdef COMPAT_NETBSD32 +#include +#include +#endif + #include #include #include @@ -403,6 +410,27 @@ kernelfault: #endif case T_PROTFLT|T_USER: /* protection fault */ +#if defined(COMPAT_NETBSD32) && defined(COMPAT_10) + { + static const char lcall[7] = { 0x9a, 0, 0, 0, 0, 7, 0 }; + const size_t sz = sizeof(lcall); + char tmp[sz]; + + /* Check for the oosyscall lcall instruction. */ + if (p->p_emul == _netbsd32 && + frame->tf_rip < VM_MAXUSER_ADDRESS32 - sz && + copyin((void *)frame->tf_rip, tmp, sz) == 0 && + memcmp(tmp, lcall, sz) == 0) { + + /* Advance past the lcall. */ + frame->tf_rip += sz; + + /* Do the syscall. */ + p->p_md.md_syscall(frame); + goto out; + } + } +#endif case T_TSSFLT|T_USER: case T_SEGNPFLT|T_USER: case T_STKFLT|T_USER:
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Mar 25 15:07:21 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Don't need gdtstore here. To generate a diff of this commit: cvs rdiff -u -r1.122 -r1.123 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.122 src/sys/arch/amd64/amd64/locore.S:1.123 --- src/sys/arch/amd64/amd64/locore.S:1.122 Thu Mar 23 17:25:51 2017 +++ src/sys/arch/amd64/amd64/locore.S Sat Mar 25 15:07:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.122 2017/03/23 17:25:51 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.123 2017/03/25 15:07:21 maxv Exp $ */ /* * Copyright-o-rama! @@ -329,7 +329,6 @@ .globl _C_LABEL(bootinfo) .globl _C_LABEL(biosbasemem) .globl _C_LABEL(biosextmem) - .globl _C_LABEL(gdtstore) .type _C_LABEL(tablesize), @object _C_LABEL(tablesize): .long TABLESIZE
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Mar 25 15:05:16 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: Use a bitmap-based allocator, will be easier to share with i386. To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.37 src/sys/arch/amd64/amd64/gdt.c:1.38 --- src/sys/arch/amd64/amd64/gdt.c:1.37 Wed Feb 8 18:50:51 2017 +++ src/sys/arch/amd64/amd64/gdt.c Sat Mar 25 15:05:16 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.37 2017/02/08 18:50:51 kre Exp $ */ +/* $NetBSD: gdt.c,v 1.38 2017/03/25 15:05:16 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.37 2017/02/08 18:50:51 kre Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.38 2017/03/25 15:05:16 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -57,16 +57,20 @@ __KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.37 #include #endif -int gdt_size; /* size of GDT in bytes */ -int gdt_dyncount; /* number of dyn. allocated GDT entries in use */ -int gdt_dynavail; -int gdt_next; /* next available slot for sweeping */ -int gdt_free; /* next free slot; terminated with GNULL_SEL */ +#define NDYNSLOTS \ + ((MAXGDTSIZ - DYNSEL_START) / sizeof(struct sys_segment_descriptor)) + +typedef struct { + bool busy[NDYNSLOTS]; + size_t nslots; +} gdt_bitmap_t; + +size_t gdt_size; /* size of GDT in bytes */ +static gdt_bitmap_t gdt_bitmap; /* bitmap of busy slots */ #if defined(USER_LDT) || !defined(XEN) static void set_sys_gdt(int, void *, size_t, int, int, int); #endif -void gdt_init(void); void update_descriptor(void *tp, void *ep) @@ -83,7 +87,7 @@ update_descriptor(void *tp, void *ep) if (!pmap_extract_ma(pmap_kernel(), (vaddr_t)table, ) || HYPERVISOR_update_descriptor(pa, *entry)) - panic("HYPERVISOR_update_descriptor failed\n"); + panic("HYPERVISOR_update_descriptor failed"); #endif } @@ -124,11 +128,10 @@ gdt_init(void) vaddr_t va; struct cpu_info *ci = _info_primary; + /* Initialize the global values */ gdt_size = MINGDTSIZ; - gdt_dyncount = 0; - gdt_next = 0; - gdt_free = GNULL_SEL; - gdt_dynavail = + memset(_bitmap.busy, 0, sizeof(gdt_bitmap.busy)); + gdt_bitmap.nslots = (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); old_gdt = gdtstore; @@ -228,10 +231,10 @@ gdt_grow(void) vaddr_t va; old_size = gdt_size; - gdt_size <<= 1; + gdt_size *= 2; if (gdt_size > MAXGDTSIZ) gdt_size = MAXGDTSIZ; - gdt_dynavail = + gdt_bitmap.nslots = (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); for (CPU_INFO_FOREACH(cii, ci)) { @@ -250,57 +253,34 @@ gdt_grow(void) pmap_update(pmap_kernel()); } -/* - * Allocate a GDT slot as follows: - * 1) If there are entries on the free list, use those. - * 2) If there are fewer than gdt_dynavail entries in use, there are free slots - *near the end that we can sweep through. - * 3) As a last resort, we increase the size of the GDT, and sweep through - *the new slots. - */ static int gdt_get_slot(void) { - int slot; - struct sys_segment_descriptor *gdt; - - gdt = (struct sys_segment_descriptor *)[DYNSEL_START]; + size_t i; KASSERT(mutex_owned(_lock)); - if (gdt_free != GNULL_SEL) { - slot = gdt_free; - gdt_free = gdt[slot].sd_xx3; /* XXXfvdl res. field abuse */ - } else { - KASSERT(gdt_next == gdt_dyncount); - if (gdt_next >= gdt_dynavail) { - if (gdt_size >= MAXGDTSIZ) -panic("gdt_get_slot: out of memory"); - gdt_grow(); + while (1) { + for (i = 0; i < gdt_bitmap.nslots; i++) { + if (!gdt_bitmap.busy[i]) { +gdt_bitmap.busy[i] = true; +return (int)i; + } } - slot = gdt_next++; + if (gdt_size >= MAXGDTSIZ) + panic("gdt_get_slot: out of memory"); + gdt_grow(); } - - gdt_dyncount++; - return slot; + /* NOTREACHED */ + return 0; } -/* - * Deallocate a GDT slot, putting it on the free list. - */ static void gdt_put_slot(int slot) { - struct sys_segment_descriptor *gdt; - KASSERT(mutex_owned(_lock)); - - gdt = (struct sys_segment_descriptor *)[DYNSEL_START]; - - gdt_dyncount--; - gdt[slot].sd_type = SDT_SYSNULL; - gdt[slot].sd_xx3 = gdt_free; - gdt_free = slot; + KASSERT(slot < gdt_bitmap.nslots); + gdt_bitmap.busy[slot] = false; } #endif @@ -319,7 +299,7 @@ tss_alloc(struct x86_64_tss *tss) mutex_exit(_lock); return GDYNSEL(slot, SEL_KPL); -#else /* XEN */ +#else /* TSS, what for? */ return GSEL(GNULL_SEL, SEL_KPL); #endif @@ -338,9 +318,6 @@ tss_free(int sel) } #ifdef USER_LDT -/* - * XXX: USER_LDT is not implemented on amd64. - */ int ldt_alloc(void *ldtp, size_t len) { @@ -380,25 +357,19 @@ lgdt(struct region_descriptor *desc) * Zero out
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Mar 24 18:03:32 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S Log Message: Unconditionnally save the segment registers - because we could have a kernel %gs and a userland %es/%ds -, and explain why T_NMI is a special case. Note that checking %gs directly is not a good idea: recent CPUs have the FSGSBASE instruction set, which allows userland to directly modify %gs without going through the kernel. If we ever enable this set, we will have to change this function, since we won't be able to test %gs against VM_MIN_KERNEL_ADDRESS anymore. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/amd64/amd64/amd64_trap.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.4 src/sys/arch/amd64/amd64/amd64_trap.S:1.5 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.4 Sun Aug 7 09:04:55 2016 +++ src/sys/arch/amd64/amd64/amd64_trap.S Fri Mar 24 18:03:32 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: amd64_trap.S,v 1.4 2016/08/07 09:04:55 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.5 2017/03/24 18:03:32 maxv Exp $ */ /*- * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ #if 0 #include -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.4 2016/08/07 09:04:55 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.5 2017/03/24 18:03:32 maxv Exp $"); #endif /* @@ -103,39 +103,54 @@ IDTVEC(trap01) ZTRAP(T_TRCTRAP) IDTVEC_END(trap01) +/* + * Non Maskable Interrupts are a special case: they can be triggered even + * with interrupts disabled, and once triggered they block further NMIs + * until an 'iret' instruction is executed. + * + * Therefore we don't enable interrupts, because the CPU could switch to + * another LWP, call 'iret' and unintentionally leave the NMI mode. + * + * We need to be careful about %gs too, because it is possible that we were + * running in kernel mode with a userland %gs. + */ IDTVEC(trap02) #if defined(XEN) ZTRAP(T_NMI) -#else /* defined(XEN) */ - pushq $0 - pushq $T_NMI +#else + pushq $0 + pushq $T_NMI subq $TF_REGSIZE,%rsp INTR_SAVE_GPRS - movl $MSR_GSBASE,%ecx - rdmsr - cmpl $VM_MIN_KERNEL_ADDRESS_HIGH32,%edx - jae 1f - swapgs movw %gs,TF_GS(%rsp) movw %fs,TF_FS(%rsp) movw %es,TF_ES(%rsp) movw %ds,TF_DS(%rsp) + + movl $MSR_GSBASE,%ecx + rdmsr + cmpl $VM_MIN_KERNEL_ADDRESS_HIGH32,%edx + jae noswapgs + + swapgs movq %rsp,%rdi incq CPUVAR(NTRAP) call _C_LABEL(trap) - movw TF_ES(%rsp),%es - movw TF_DS(%rsp),%ds swapgs - jmp 2f -1: + jmp nmileave + +noswapgs: movq %rsp,%rdi incq CPUVAR(NTRAP) call _C_LABEL(trap) -2: + +nmileave: + movw TF_ES(%rsp),%es + movw TF_DS(%rsp),%ds INTR_RESTORE_GPRS addq $TF_REGSIZE+16,%rsp iretq -#endif /* defined(XEN) */ +#endif IDTVEC_END(trap02) IDTVEC(trap03)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Mar 23 17:25:51 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S machdep.c trap.c Log Message: Remove this call gate on amd64, it is useless and vulnerable. Call gates do not modify %rflags, so interrupts are not disabled when entering the gate. There is a small window where we are in kernel mode and with a userland %gs, and if an interrupt happens here we will rejump into the kernel but not switch to the kernel TLS. Userland can simply perform a gate call in a loop, and hope that at some point an interrupt will be received in this window - which necessarily will be the case. With a specially-crafted %gs it is certainly enough to escalate privileges. To generate a diff of this commit: cvs rdiff -u -r1.121 -r1.122 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.253 -r1.254 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.94 -r1.95 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.121 src/sys/arch/amd64/amd64/locore.S:1.122 --- src/sys/arch/amd64/amd64/locore.S:1.121 Thu Feb 9 19:30:56 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Mar 23 17:25:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.121 2017/02/09 19:30:56 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.122 2017/03/23 17:25:51 maxv Exp $ */ /* * Copyright-o-rama! @@ -1399,27 +1399,6 @@ NENTRY(lwp_trampoline) END(lwp_trampoline) /* - * oosyscall() - * - * Old call gate entry for syscall. only needed if we're - * going to support running old i386 NetBSD 1.0 or ibcs2 binaries, etc, - * on NetBSD/amd64. - * The 64bit call gate can't request that arguments be copied from the - * user stack (which the i386 code uses to get a gap for the flags). - * push/pop are :: cycles. - */ -IDTVEC(oosyscall) - /* Set rflags in trap frame. */ - pushq (%rsp) /* move user's %eip */ - pushq 16(%rsp) /* and %cs */ - popq 8(%rsp) - pushfq - popq 16(%rsp) - pushq $7 /* size of instruction for restart */ - jmp osyscall1 -IDTVEC_END(oosyscall) - -/* * osyscall() * * Trap gate entry for int $80 syscall, also used by sigreturn. Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.253 src/sys/arch/amd64/amd64/machdep.c:1.254 --- src/sys/arch/amd64/amd64/machdep.c:1.253 Fri Mar 10 14:54:12 2017 +++ src/sys/arch/amd64/amd64/machdep.c Thu Mar 23 17:25:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.253 2017/03/10 14:54:12 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.254 2017/03/23 17:25:51 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.253 2017/03/10 14:54:12 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.254 2017/03/23 17:25:51 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1452,7 +1452,6 @@ typedef void (vector)(void); extern vector IDTVEC(syscall); extern vector IDTVEC(syscall32); extern vector IDTVEC(osyscall); -extern vector IDTVEC(oosyscall); extern vector *IDTVEC(exceptions)[]; static void @@ -1642,11 +1641,8 @@ init_x86_64(paddr_t first_avail) #endif /* - * Make LDT gates and memory segments. + * Make LDT memory segments. */ - setgate((struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL), - (oosyscall), 0, SDT_SYS386CGT, SEL_UPL, - GSEL(GCODE_SEL, SEL_KPL)); *(struct mem_segment_descriptor *)(ldtstore + LUCODE_SEL) = *GDT_ADDR_MEM(gdtstore, GUCODE_SEL); *(struct mem_segment_descriptor *)(ldtstore + LUDATA_SEL) = @@ -1677,16 +1673,6 @@ init_x86_64(paddr_t first_avail) set_mem_segment(ldt_segp, 0, x86_btop(VM_MAXUSER_ADDRESS32) - 1, SDT_MEMRWA, SEL_UPL, 1, 1, 0); - /* - * Other LDT entries. - */ - memcpy((struct gate_descriptor *)(ldtstore + LSOL26CALLS_SEL), - (struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL), - sizeof (struct gate_descriptor)); - memcpy((struct gate_descriptor *)(ldtstore + LBSDICALLS_SEL), - (struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL), - sizeof (struct gate_descriptor)); - /* CPU-specific IDT exceptions. */ for (x = 0; x < NCPUIDT; x++) { #ifndef XEN Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.94 src/sys/arch/amd64/amd64/trap.c:1.95 --- src/sys/arch/amd64/amd64/trap.c:1.94 Sat Mar 18 13:39:23 2017 +++ src/sys/arch/amd64/amd64/trap.c Thu Mar 23 17:25:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.94 2017/03/18 13:39:23 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.95 2017/03/23 17:25:51 maxv Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.94 2017/03/18 13:39:23 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.95 2017/03/23 17:25:51 maxv Exp $"); #include "opt_ddb.h" #include
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: chs Date: Thu Mar 9 00:16:07 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: improve readability of TRAP_SIGDEBUG info and add fsbase/gsbase. To generate a diff of this commit: cvs rdiff -u -r1.92 -r1.93 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.92 src/sys/arch/amd64/amd64/trap.c:1.93 --- src/sys/arch/amd64/amd64/trap.c:1.92 Thu Feb 23 03:34:22 2017 +++ src/sys/arch/amd64/amd64/trap.c Thu Mar 9 00:16:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.92 2017/02/23 03:34:22 kamil Exp $ */ +/* $NetBSD: trap.c,v 1.93 2017/03/09 00:16:07 chs Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.92 2017/02/23 03:34:22 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.93 2017/03/09 00:16:07 chs Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -154,7 +154,7 @@ int trapdebug = 0; #define IDTVEC(name) __CONCAT(X, name) #ifdef TRAP_SIGDEBUG -static void frame_dump(struct trapframe *); +static void frame_dump(struct trapframe *, struct pcb *); #endif static void * @@ -194,8 +194,8 @@ trap_print(const struct trapframe *frame } printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor"); - printf("trap type %d code %lx rip %lx cs %lx rflags %lx cr2 %lx " - "ilevel %x rsp %lx\n", + printf("trap type %d code %#lx rip %#lx cs %#lx rflags %#lx cr2 %#lx " + "ilevel %#x rsp %#lx\n", type, frame->tf_err, (u_long)frame->tf_rip, frame->tf_cs, frame->tf_rflags, rcr2(), curcpu()->ci_ilevel, frame->tf_rsp); @@ -408,9 +408,9 @@ kernelfault: case T_STKFLT|T_USER: case T_ALIGNFLT|T_USER: #ifdef TRAP_SIGDEBUG - printf("pid %d.%d (%s): BUS/SEGV (%x) at rip %lx addr %lx\n", + printf("pid %d.%d (%s): BUS/SEGV (%#x) at rip %#lx addr %#lx\n", p->p_pid, l->l_lid, p->p_comm, type, frame->tf_rip, rcr2()); - frame_dump(frame); + frame_dump(frame, pcb); #endif KSI_INIT_TRAP(); ksi.ksi_trap = type & ~T_USER; @@ -442,9 +442,9 @@ kernelfault: case T_PRIVINFLT|T_USER: /* privileged instruction fault */ case T_FPOPFLT|T_USER: /* coprocessor operand fault */ #ifdef TRAP_SIGDEBUG - printf("pid %d.%d (%s): ILL at rip %lx addr %lx\n", + printf("pid %d.%d (%s): ILL at rip %#lx addr %#lx\n", p->p_pid, l->l_lid, p->p_comm, frame->tf_rip, rcr2()); - frame_dump(frame); + frame_dump(frame, pcb); #endif KSI_INIT_TRAP(); ksi.ksi_signo = SIGILL; @@ -670,7 +670,7 @@ faultcommon: "error %d trap %d cr2 %p\n", p->p_pid, l->l_lid, p->p_comm, ksi.ksi_signo, frame->tf_rip, va, error, ksi.ksi_trap, ksi.ksi_addr); - frame_dump(frame); + frame_dump(frame, pcb); #endif (*p->p_emul->e_trapsignal)(l, ); break; @@ -763,32 +763,36 @@ startlwp(void *arg) } #ifdef TRAP_SIGDEBUG -static void -frame_dump(struct trapframe *tf) +void +frame_dump(struct trapframe *tf, struct pcb *pcb) { int i; unsigned long *p; - printf("rip %p rsp %p rfl %p\n", - (void *)tf->tf_rip, (void *)tf->tf_rsp, (void *)tf->tf_rflags); - printf("rdi %p rsi %p rdx %p\n", - (void *)tf->tf_rdi, (void *)tf->tf_rsi, (void *)tf->tf_rdx); - printf("rcx %p r8 %p r9 %p\n", - (void *)tf->tf_rcx, (void *)tf->tf_r8, (void *)tf->tf_r9); - printf("r10 %p r11 %p r12 %p\n", - (void *)tf->tf_r10, (void *)tf->tf_r11, (void *)tf->tf_r12); - printf("r13 %p r14 %p r15 %p\n", - (void *)tf->tf_r13, (void *)tf->tf_r14, (void *)tf->tf_r15); - printf("rbp %p rbx %p rax %p\n", - (void *)tf->tf_rbp, (void *)tf->tf_rbx, (void *)tf->tf_rax); - printf("cs %lx ds %lx es %lx fs %lx gs %lx ss %lx\n", + printf("trapframe %p\n", tf); + printf("rip 0x%016lx rsp 0x%016lx rfl 0x%016lx\n", + tf->tf_rip, tf->tf_rsp, tf->tf_rflags); + printf("rdi 0x%016lx rsi 0x%016lx rdx 0x%016lx\n", + tf->tf_rdi, tf->tf_rsi, tf->tf_rdx); + printf("rcx 0x%016lx r8 0x%016lx r9 0x%016lx\n", + tf->tf_rcx, tf->tf_r8, tf->tf_r9); + printf("r10 0x%016lx r11 0x%016lx r12 0x%016lx\n", + tf->tf_r10, tf->tf_r11, tf->tf_r12); + printf("r13 0x%016lx r14 0x%016lx r15 0x%016lx\n", + tf->tf_r13, tf->tf_r14, tf->tf_r15); + printf("rbp 0x%016lx rbx 0x%016lx rax 0x%016lx\n", + tf->tf_rbp, tf->tf_rbx, tf->tf_rax); + printf("cs 0x%04lx ds 0x%04lx es 0x%04lx " + "fs 0x%04lx gs 0x%04lx ss 0x%04lx\n", tf->tf_cs & 0x, tf->tf_ds & 0x, tf->tf_es & 0x, tf->tf_fs & 0x, tf->tf_gs & 0x, tf->tf_ss & 0x); - + printf("fsbase 0x%016lx gsbase 0x%016lx\n", + pcb->pcb_fs, pcb->pcb_gs); printf("\n"); printf("Stack dump:\n"); for (i = 0, p = (unsigned long *) tf; i < 20; i ++, p += 4) - printf(" 0x%.16lx 0x%.16lx 0x%.16lx 0x%.16lx\n", *p, p[1], p[2],
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Feb 14 09:03:48 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: Check %eip with USER_LDT too. To generate a diff of this commit: cvs rdiff -u -r1.102 -r1.103 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.102 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.103 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.102 Thu Feb 9 08:38:25 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Tue Feb 14 09:03:48 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.102 2017/02/09 08:38:25 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.103 2017/02/14 09:03:48 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.102 2017/02/09 08:38:25 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.103 2017/02/14 09:03:48 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1064,10 +1064,11 @@ cpu_mcontext32_validate(struct lwp *l, c if (!VALID_USER_DSEL32(gr[_REG32_DS]) || !VALID_USER_DSEL32(gr[_REG32_SS])) return EINVAL; - if (gr[_REG32_EIP] >= VM_MAXUSER_ADDRESS32) - return EINVAL; } + if (gr[_REG32_EIP] >= VM_MAXUSER_ADDRESS32) + return EINVAL; + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Feb 9 19:30:56 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: If the preloaded modules cannot be mapped with the initial amount of VA, discard the associated bootinfo entry. Otherwise the machine faults and reboots immediately. I spotted this bug more than a year ago, but I recently saw that there is already PR/42645 (7 years old), so just fix it. The size has been increased in the meantime, so the limit is unlikely to be reached anyway. To generate a diff of this commit: cvs rdiff -u -r1.120 -r1.121 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.120 src/sys/arch/amd64/amd64/locore.S:1.121 --- src/sys/arch/amd64/amd64/locore.S:1.120 Thu Feb 9 08:23:46 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Feb 9 19:30:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.120 2017/02/09 08:23:46 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.121 2017/02/09 19:30:56 maxv Exp $ */ /* * Copyright-o-rama! @@ -211,6 +211,10 @@ ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ * PAGE_SIZE) +/* Amount of VA used to map the kernel, the syms and the preloaded modules */ +#define BOOTMAP_VA_SIZE \ + (NKL2_KIMG_ENTRIES * (1 << L2_SHIFT) - TABLESIZE - IOM_SIZE) + /* * fillkpt - Fill in a kernel page table * eax = pte (page frame | control | status) @@ -443,7 +447,7 @@ ENTRY(start) testl %eax,%eax /* bootinfo = NULL? */ jz bootinfo_finished - movl (%eax),%ebx /* number of entries */ + movl (%eax),%ebx /* bootinfo::bi_nentries */ movl $RELOC(bootinfo),%ebp movl %ebp,%edx addl $BOOTINFO_MAXSIZE,%ebp @@ -462,7 +466,7 @@ bootinfo_entryloop: movl (%ecx),%eax /* btinfo_common::len (size of entry) */ movl %edx,%edi - addl (%ecx),%edx /* update dest pointer */ + addl %eax,%edx /* update dest pointer */ cmpl %ebp,%edx /* beyond bootinfo+BOOTINFO_MAXSIZE? */ jg bootinfo_overflow @@ -470,20 +474,31 @@ bootinfo_entryloop: movl %eax,%ecx /* - * If any modules were loaded, record where they end. We'll need to - * skip over them. + * If any modules were loaded, record where they end. 'eblob' is used + * later to compute the initial bootstrap tables. */ cmpl $BTINFO_MODULELIST,4(%esi) /* btinfo_common::type */ - jne 0f + jne bootinfo_copy - pushl 12(%esi) /* btinfo_modulelist::endpa */ - popl RELOC(eblob) + /* Skip the modules if we won't have enough VA to map them */ + movl 12(%esi),%eax /* btinfo_modulelist::endpa */ + addl $PGOFSET,%eax /* roundup to a page */ + andl $~PGOFSET,%eax + cmpl $BOOTMAP_VA_SIZE,%eax + jg bootinfo_skip + movl %eax,RELOC(eblob) addl $KERNBASE_LO,RELOC(eblob) adcl $KERNBASE_HI,RELOC(eblob)+4 -0: +bootinfo_copy: rep movsb/* copy esi -> edi */ + jmp bootinfo_next + +bootinfo_skip: + subl %ecx,%edx /* revert dest pointer */ + +bootinfo_next: popl %eax popl %esi popl %edi @@ -501,8 +516,8 @@ bootinfo_overflow: movl $RELOC(bootinfo),%ebp movl %ebp,%edx subl %ebx,(%edx) /* correct the number of entries */ - bootinfo_finished: + /* Load 'esym' */ movl 16(%esp),%eax testl %eax,%eax /* esym = NULL? */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Feb 9 08:38:25 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: No, do not just copy code from i386 and expect it to work on amd64. There are several structural differences. At least two issues here: segment registers that could fault in kernel mode with userland TLS, and a non- canonical %eip on iret. Not even tested, but just obvious. By the way, I believe this function is still buggy since we don't call cpu_fsgs_reload while %fs/%gs could have been reloaded. To generate a diff of this commit: cvs rdiff -u -r1.101 -r1.102 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.101 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.102 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.101 Mon Feb 6 16:34:37 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Thu Feb 9 08:38:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.101 2017/02/06 16:34:37 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.102 2017/02/09 08:38:25 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.101 2017/02/06 16:34:37 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.102 2017/02/09 08:38:25 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -531,13 +531,31 @@ netbsd32_process_read_fpregs(struct lwp int netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) { - struct trapframe *tf = l->l_md.md_regs; + struct trapframe *tf; + struct pcb *pcb; + + tf = l->l_md.md_regs; + pcb = lwp_getpcb(l); /* - * Check for security violations. Taken from i386/process_machdep.c. + * Check for security violations. */ - if (((regs->r_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || - !VALID_USER_CSEL32(regs->r_cs)) + if (((regs->r_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) + return EINVAL; + if (!VALID_USER_CSEL32(regs->r_cs)) + return EINVAL; + if (regs->r_fs != 0 && !VALID_USER_DSEL32(regs->r_fs) && + !(VALID_USER_FSEL32(regs->r_fs) && pcb->pcb_fs != 0)) + return EINVAL; + if (regs->r_gs != 0 && !VALID_USER_DSEL32(regs->r_gs) && + !(VALID_USER_GSEL32(regs->r_gs) && pcb->pcb_gs != 0)) + return EINVAL; + if (regs->r_es != 0 && !VALID_USER_DSEL32(regs->r_es)) + return EINVAL; + if (!VALID_USER_DSEL32(regs->r_ds) || + !VALID_USER_DSEL32(regs->r_ss)) + return EINVAL; + if (regs->r_eip >= VM_MAXUSER_ADDRESS32) return EINVAL; tf->tf_rax = regs->r_eax;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu Feb 9 08:23:46 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Restore %ds before swapgs. Movs to segment registers are allowed to fault in kernel mode but simply cause a signal to be sent to userland. The thing is, in this case %gs is not restored when entering the trap routine, which means the kernel uses userland's TLS instead of using its own. Which in short makes it easy to escalate privileges. Currently, this bug is triggered only in one place, which I am about to fix too. To generate a diff of this commit: cvs rdiff -u -r1.119 -r1.120 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.119 src/sys/arch/amd64/amd64/locore.S:1.120 --- src/sys/arch/amd64/amd64/locore.S:1.119 Thu Feb 2 19:12:09 2017 +++ src/sys/arch/amd64/amd64/locore.S Thu Feb 9 08:23:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.119 2017/02/02 19:12:09 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.120 2017/02/09 08:23:46 maxv Exp $ */ /* * Copyright-o-rama! @@ -1310,16 +1310,15 @@ do_syscall: testl $(MDL_IRET|MDL_COMPAT32),L_MD_FLAGS(%r14) INTR_RESTORE_GPRS movw TF_ES(%rsp),%es + movw TF_DS(%rsp),%ds SWAPGS jnz 2f #ifndef XEN movq TF_RIP(%rsp),%rcx /* %rip for sysret */ movq TF_RFLAGS(%rsp),%r11 /* %flags for sysret */ - movw TF_DS(%rsp),%ds movq TF_RSP(%rsp),%rsp sysretq #else - movw TF_DS(%rsp),%ds addq $TF_RIP,%rsp pushq $256 /* VGCF_IN_SYSCALL */ jmp HYPERVISOR_iret @@ -1332,7 +1331,6 @@ do_syscall: * then a SIGSEGV will be signalled. */ 2: - movw TF_DS(%rsp),%ds addq $TF_RIP,%rsp iretq
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: kre Date: Wed Feb 8 18:50:52 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: All bow down before the Great Code Compiler. Specifically, it has been commanded that unused-functions is a warning, and, as all should know, all warnings be errors. Hence, since XEN kernels do not call set_sys_gdt(), that function may not be included (and the XEN kernel saves a few tens of bytes.) An alternate fix would be to just remove "static" - but that would be the equivalent to just giving the compiler the finger ... hmm, maybe that would have been a better fix... To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.36 src/sys/arch/amd64/amd64/gdt.c:1.37 --- src/sys/arch/amd64/amd64/gdt.c:1.36 Wed Feb 8 10:08:26 2017 +++ src/sys/arch/amd64/amd64/gdt.c Wed Feb 8 18:50:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.36 2017/02/08 10:08:26 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.37 2017/02/08 18:50:51 kre Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.36 2017/02/08 10:08:26 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.37 2017/02/08 18:50:51 kre Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -63,7 +63,9 @@ int gdt_dynavail; int gdt_next; /* next available slot for sweeping */ int gdt_free; /* next free slot; terminated with GNULL_SEL */ +#if defined(USER_LDT) || !defined(XEN) static void set_sys_gdt(int, void *, size_t, int, int, int); +#endif void gdt_init(void); void @@ -85,6 +87,7 @@ update_descriptor(void *tp, void *ep) #endif } +#if defined(USER_LDT) || !defined(XEN) /* * Called on a newly-allocated GDT slot, so no race between CPUs. */ @@ -107,6 +110,7 @@ set_sys_gdt(int slot, void *base, size_t update_descriptor(>ci_gdt[idx + 1], [1]); } } +#endif /* USER_LDT || !XEN */ /* * Initialize the GDT. We already have a gdtstore, which was temporarily used
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Mon Feb 6 16:34:37 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: In cpu_mcontext32_validate, allow the registers to have different locations if the LDT is user-set. I am intentionally not allowing this in check_sigcontext32, because I don't think Wine uses it. To generate a diff of this commit: cvs rdiff -u -r1.100 -r1.101 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.100 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.101 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.100 Mon Feb 6 16:02:17 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Mon Feb 6 16:34:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.100 2017/02/06 16:02:17 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.101 2017/02/06 16:34:37 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.100 2017/02/06 16:02:17 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.101 2017/02/06 16:34:37 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1016,6 +1016,7 @@ check_sigcontext32(struct lwp *l, const int cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp) { + struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; const __greg32_t *gr; struct trapframe *tf; struct pcb *pcb; @@ -1024,22 +1025,31 @@ cpu_mcontext32_validate(struct lwp *l, c tf = l->l_md.md_regs; pcb = lwp_getpcb(l); - if (((gr[_REG32_EFL] ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || - !VALID_USER_CSEL32(gr[_REG32_CS])) - return EINVAL; - if (gr[_REG32_FS] != 0 && !VALID_USER_DSEL32(gr[_REG32_FS]) && - !(VALID_USER_FSEL32(gr[_REG32_FS]) && pcb->pcb_fs != 0)) - return EINVAL; - if (gr[_REG32_GS] != 0 && !VALID_USER_DSEL32(gr[_REG32_GS]) && - !(VALID_USER_GSEL32(gr[_REG32_GS]) && pcb->pcb_gs != 0)) - return EINVAL; - if (gr[_REG32_ES] != 0 && !VALID_USER_DSEL32(gr[_REG32_ES])) - return EINVAL; - if (!VALID_USER_DSEL32(gr[_REG32_DS]) || - !VALID_USER_DSEL32(gr[_REG32_SS])) - return EINVAL; - if (gr[_REG32_EIP] >= VM_MAXUSER_ADDRESS32) + if (((gr[_REG32_EFL] ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) return EINVAL; + + if (__predict_false(pmap->pm_ldt != NULL)) { + /* Only when the LDT is user-set (with USER_LDT) */ + if (!USERMODE(gr[_REG32_CS], gr[_REG32_EFL])) + return EINVAL; + } else { + if (!VALID_USER_CSEL32(gr[_REG32_CS])) + return EINVAL; + if (gr[_REG32_FS] != 0 && !VALID_USER_DSEL32(gr[_REG32_FS]) && + !(VALID_USER_FSEL32(gr[_REG32_FS]) && pcb->pcb_fs != 0)) + return EINVAL; + if (gr[_REG32_GS] != 0 && !VALID_USER_DSEL32(gr[_REG32_GS]) && + !(VALID_USER_GSEL32(gr[_REG32_GS]) && pcb->pcb_gs != 0)) + return EINVAL; + if (gr[_REG32_ES] != 0 && !VALID_USER_DSEL32(gr[_REG32_ES])) + return EINVAL; + if (!VALID_USER_DSEL32(gr[_REG32_DS]) || + !VALID_USER_DSEL32(gr[_REG32_SS])) + return EINVAL; + if (gr[_REG32_EIP] >= VM_MAXUSER_ADDRESS32) + return EINVAL; + } + return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Feb 5 08:36:08 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Now that valid_user_selector only checks for LDT selectors, remove it. A user may legitimately want to have one register in the GDT, and another in the LDT. Pass 2/2. To generate a diff of this commit: cvs rdiff -u -r1.250 -r1.251 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.250 src/sys/arch/amd64/amd64/machdep.c:1.251 --- src/sys/arch/amd64/amd64/machdep.c:1.250 Sun Feb 5 08:19:05 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Feb 5 08:36:08 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.250 2017/02/05 08:19:05 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.251 2017/02/05 08:36:08 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.250 2017/02/05 08:19:05 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.251 2017/02/05 08:36:08 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -320,8 +320,6 @@ int dumpsys_seg(paddr_t, paddr_t); void init_x86_64(paddr_t); -static int valid_user_selector(struct lwp *, uint64_t); - /* * Machine-dependent startup code */ @@ -1902,12 +1900,11 @@ cpu_setmcontext(struct lwp *l, const mco int cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp) { - const __greg_t *gr; - uint16_t sel; - int error; struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; struct proc *p = l->l_proc; struct trapframe *tf = l->l_md.md_regs; + const __greg_t *gr; + uint16_t sel; gr = mcp->__gregs; @@ -1915,31 +1912,12 @@ cpu_mcontext_validate(struct lwp *l, con return EINVAL; if (__predict_false(pmap->pm_ldt != NULL)) { - error = valid_user_selector(l, gr[_REG_ES]); - if (error != 0) - return error; - - error = valid_user_selector(l, gr[_REG_FS]); - if (error != 0) - return error; - - error = valid_user_selector(l, gr[_REG_GS]); - if (error != 0) - return error; - + /* Only when the LDT is user-set (with USER_LDT) */ if ((gr[_REG_DS] & 0x) == 0) return EINVAL; - error = valid_user_selector(l, gr[_REG_DS]); - if (error != 0) - return error; - #ifndef XEN if ((gr[_REG_SS] & 0x) == 0) return EINVAL; - error = valid_user_selector(l, gr[_REG_SS]); - if (error != 0) - return error; - if (!USERMODE(gr[_REG_CS], gr[_REG_RFLAGS])) return EINVAL; #endif @@ -1991,27 +1969,6 @@ cpu_initclocks(void) (*initclock_func)(); } -/* - * Called only when the LDT is user-set (USER_LDT). - */ -static int -valid_user_selector(struct lwp *l, uint64_t seg) -{ - seg &= 0x; - if (seg == 0) - return 0; - - if (!(seg & SEL_LDT)) { - CTASSERT(GUDATA_SEL & SEL_LDT); - KASSERT(seg != GUDATA_SEL); - CTASSERT(GUDATA32_SEL & SEL_LDT); - KASSERT(seg != GUDATA32_SEL); - return EINVAL; - } - - return 0; -} - int mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) {
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Feb 5 08:19:05 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: In cpu_mcontext_validate, treat %cs differently depending on whether a user LDT is set; just check the permission without checking the location (which may change). In valid_user_selector, don't check the length of the LDT. This is racy because pm_ldt_len could be updated by another thread, and useless since the length is already referenced in ldtr (ldt_alloc), which means that any overflow will fault in userland. Also, don't check the permission of the segment pointed to; this too is racy, and we don't care either since the permissions are checked earlier in x86_set_ldt1. Pass 1/2. To generate a diff of this commit: cvs rdiff -u -r1.249 -r1.250 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.249 src/sys/arch/amd64/amd64/machdep.c:1.250 --- src/sys/arch/amd64/amd64/machdep.c:1.249 Sun Feb 5 06:26:06 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Feb 5 08:19:05 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.249 2017/02/05 06:26:06 maya Exp $ */ +/* $NetBSD: machdep.c,v 1.250 2017/02/05 08:19:05 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.249 2017/02/05 06:26:06 maya Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.250 2017/02/05 08:19:05 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1939,23 +1939,28 @@ cpu_mcontext_validate(struct lwp *l, con error = valid_user_selector(l, gr[_REG_SS]); if (error != 0) return error; + + if (!USERMODE(gr[_REG_CS], gr[_REG_RFLAGS])) + return EINVAL; #endif } else { #define VUD(sel) \ ((p->p_flag & PK_32) ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) +#define VUF(sel) /* XXX: Shouldn't this be FSEL32? */ \ +((p->p_flag & PK_32) ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) +#define VUG(sel) \ +((p->p_flag & PK_32) ? VALID_USER_GSEL32(sel) : VALID_USER_DSEL(sel)) +#define VUC(sel) \ +((p->p_flag & PK_32) ? VALID_USER_CSEL32(sel) : VALID_USER_CSEL(sel)) + sel = gr[_REG_ES] & 0x; if (sel != 0 && !VUD(sel)) return EINVAL; -/* XXX: Shouldn't this be FSEL32? */ -#define VUF(sel) \ -((p->p_flag & PK_32) ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) sel = gr[_REG_FS] & 0x; if (sel != 0 && !VUF(sel)) return EINVAL; -#define VUG(sel) \ -((p->p_flag & PK_32) ? VALID_USER_GSEL32(sel) : VALID_USER_DSEL(sel)) sel = gr[_REG_GS] & 0x; if (sel != 0 && !VUG(sel)) return EINVAL; @@ -1968,17 +1973,12 @@ cpu_mcontext_validate(struct lwp *l, con sel = gr[_REG_SS] & 0x; if (!VUD(sel)) return EINVAL; -#endif - - } -#ifndef XEN -#define VUC(sel) \ -((p->p_flag & PK_32) ? VALID_USER_CSEL32(sel) : VALID_USER_CSEL(sel)) - sel = gr[_REG_CS] & 0x; - if (!VUC(sel)) - return EINVAL; + sel = gr[_REG_CS] & 0x; + if (!VUC(sel)) + return EINVAL; #endif + } if (gr[_REG_RIP] >= VM_MAXUSER_ADDRESS) return EINVAL; @@ -1991,34 +1991,17 @@ cpu_initclocks(void) (*initclock_func)(); } +/* + * Called only when the LDT is user-set (USER_LDT). + */ static int valid_user_selector(struct lwp *l, uint64_t seg) { - int off, len; - char *dt; - struct mem_segment_descriptor *sdp; - struct proc *p = l->l_proc; - struct pmap *pmap= p->p_vmspace->vm_map.pmap; - uint64_t base; - seg &= 0x; - if (seg == 0) return 0; - off = (seg & 0xfff8); - if (seg & SEL_LDT) { - if (pmap->pm_ldt != NULL) { - len = pmap->pm_ldt_len; /* XXX broken */ - dt = (char *)pmap->pm_ldt; - } else { - dt = ldtstore; - len = LDT_SIZE; - } - - if (off > (len - 8)) - return EINVAL; - } else { + if (!(seg & SEL_LDT)) { CTASSERT(GUDATA_SEL & SEL_LDT); KASSERT(seg != GUDATA_SEL); CTASSERT(GUDATA32_SEL & SEL_LDT); @@ -2026,17 +2009,6 @@ valid_user_selector(struct lwp *l, uint6 return EINVAL; } - sdp = (struct mem_segment_descriptor *)(dt + off); - if (sdp->sd_type < SDT_MEMRO || sdp->sd_p == 0) - return EINVAL; - - base = ((uint64_t)sdp->sd_hibase << 32) | ((uint64_t)sdp->sd_lobase); - if (sdp->sd_gran == 1) - base <<= PAGE_SHIFT; - - if (base >= VM_MAXUSER_ADDRESS) - return EINVAL; - return 0; }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maya Date: Sun Feb 5 06:26:07 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Remove duplicate check. uvm_physseg_valid_p(upm) == false is also our for loop exit condition, and will never happen. NFC To generate a diff of this commit: cvs rdiff -u -r1.248 -r1.249 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.248 src/sys/arch/amd64/amd64/machdep.c:1.249 --- src/sys/arch/amd64/amd64/machdep.c:1.248 Sun Feb 5 06:13:53 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Feb 5 06:26:06 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.248 2017/02/05 06:13:53 maya Exp $ */ +/* $NetBSD: machdep.c,v 1.249 2017/02/05 06:26:06 maya Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.248 2017/02/05 06:13:53 maya Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.249 2017/02/05 06:26:06 maya Exp $"); /* #define XENDEBUG_LOW */ @@ -803,9 +803,6 @@ sparse_dump_mark(void) upm = uvm_physseg_get_next(upm)) { paddr_t pfn; - if (uvm_physseg_valid_p(upm) == false) - break; - /* * We assume that seg->start to seg->end are * uvm_page_physload()ed
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maya Date: Sun Feb 5 06:13:53 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Fix off by one. Fixes PR port-amd64/51944: sparse core dumps do not work To generate a diff of this commit: cvs rdiff -u -r1.247 -r1.248 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.247 src/sys/arch/amd64/amd64/machdep.c:1.248 --- src/sys/arch/amd64/amd64/machdep.c:1.247 Sun Feb 5 06:12:33 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Feb 5 06:13:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.247 2017/02/05 06:12:33 maya Exp $ */ +/* $NetBSD: machdep.c,v 1.248 2017/02/05 06:13:53 maya Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.247 2017/02/05 06:12:33 maya Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.248 2017/02/05 06:13:53 maya Exp $"); /* #define XENDEBUG_LOW */ @@ -811,7 +811,7 @@ sparse_dump_mark(void) * uvm_page_physload()ed */ for (pfn = uvm_physseg_get_start(upm); - pfn <= uvm_physseg_get_end(upm); + pfn < uvm_physseg_get_end(upm); pfn++) { pg = PHYS_TO_VM_PAGE(ptoa(pfn));
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maya Date: Sun Feb 5 06:12:33 UTC 2017 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Match the iterator in sys/uvm/uvm_page.c:1866. NFC. No matching KASSERT - this case is covered by the above if (uvm_physseg_valid_p(upm) == false) break; To generate a diff of this commit: cvs rdiff -u -r1.246 -r1.247 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.246 src/sys/arch/amd64/amd64/machdep.c:1.247 --- src/sys/arch/amd64/amd64/machdep.c:1.246 Mon Dec 26 17:54:06 2016 +++ src/sys/arch/amd64/amd64/machdep.c Sun Feb 5 06:12:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.246 2016/12/26 17:54:06 cherry Exp $ */ +/* $NetBSD: machdep.c,v 1.247 2017/02/05 06:12:33 maya Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.246 2016/12/26 17:54:06 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.247 2017/02/05 06:12:33 maya Exp $"); /* #define XENDEBUG_LOW */ @@ -806,17 +806,15 @@ sparse_dump_mark(void) if (uvm_physseg_valid_p(upm) == false) break; - const paddr_t startpfn = uvm_physseg_get_start(upm); - const paddr_t endpfn = uvm_physseg_get_end(upm); - - KASSERT(startpfn != -1 && endpfn != -1); - /* * We assume that seg->start to seg->end are * uvm_page_physload()ed */ - for (pfn = startpfn; pfn <= endpfn; pfn++) { + for (pfn = uvm_physseg_get_start(upm); + pfn <= uvm_physseg_get_end(upm); + pfn++) { pg = PHYS_TO_VM_PAGE(ptoa(pfn)); + if (pg->uanon || (pg->pqflags & PQ_FREE) || (pg->uobject && pg->uobject->pgops)) { p = VM_PAGE_TO_PHYS(pg) / PAGE_SIZE;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: cherry Date: Mon Dec 26 13:55:13 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: remove spurious printf() To generate a diff of this commit: cvs rdiff -u -r1.244 -r1.245 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.244 src/sys/arch/amd64/amd64/machdep.c:1.245 --- src/sys/arch/amd64/amd64/machdep.c:1.244 Mon Dec 26 12:54:42 2016 +++ src/sys/arch/amd64/amd64/machdep.c Mon Dec 26 13:55:13 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.244 2016/12/26 12:54:42 cherry Exp $ */ +/* $NetBSD: machdep.c,v 1.245 2016/12/26 13:55:13 cherry Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.244 2016/12/26 12:54:42 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.245 2016/12/26 13:55:13 cherry Exp $"); /* #define XENDEBUG_LOW */ @@ -1485,8 +1485,6 @@ init_x86_64_msgbuf(void) if (uvm_physseg_valid_p(x) == false) panic("init_x86_64: can't find end of memory"); - printf("uvm_physseg_find(atop(avail_end), NULL) == %d\n", - uvm_physseg_find(atop(avail_end), NULL)); /* Shrink so it'll fit in the last segment. */ if (uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x) < atop(sz)) sz = ctob(uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x));
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: cherry Date: Mon Dec 26 12:54:42 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Make the msgbuf initialisation track closer to the original pre-uvm_physseg.h one. To see the exact changes with the original, line for line, do: cvs diff -u -r 1.241 sys/arch/amd64/amd64/machdep.c To generate a diff of this commit: cvs rdiff -u -r1.243 -r1.244 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.243 src/sys/arch/amd64/amd64/machdep.c:1.244 --- src/sys/arch/amd64/amd64/machdep.c:1.243 Fri Dec 23 07:15:27 2016 +++ src/sys/arch/amd64/amd64/machdep.c Mon Dec 26 12:54:42 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.243 2016/12/23 07:15:27 cherry Exp $ */ +/* $NetBSD: machdep.c,v 1.244 2016/12/26 12:54:42 cherry Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.243 2016/12/23 07:15:27 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.244 2016/12/26 12:54:42 cherry Exp $"); /* #define XENDEBUG_LOW */ @@ -1468,30 +1468,49 @@ extern vector *IDTVEC(exceptions)[]; static void init_x86_64_msgbuf(void) { -/* Message buffer is located at end of core. */ - psize_t reqsz = round_page(MSGBUFSIZE); - psize_t sz = 0; + /* Message buffer is located at end of core. */ + psize_t sz = round_page(MSGBUFSIZE); + psize_t reqsz = sz; + uvm_physseg_t x; + + search_again: +for (x = uvm_physseg_get_first(); + uvm_physseg_valid_p(x); + x = uvm_physseg_get_next(x)) { - for (sz = 0; sz < reqsz; sz += PAGE_SIZE) { - paddr_t stolenpa; - - if (!uvm_page_physget()) + if (ctob(uvm_physseg_get_avail_end(x)) == avail_end) break; + } - if (stolenpa == (msgbuf_p_seg[msgbuf_p_cnt].paddr - + PAGE_SIZE)) { - /* contiguous: append it to current buf alloc */ - msgbuf_p_seg[msgbuf_p_cnt].sz += PAGE_SIZE; - } else { - /* non-contiguous: start a new msgbuf seg */ - msgbuf_p_seg[msgbuf_p_cnt].sz = PAGE_SIZE; - msgbuf_p_seg[msgbuf_p_cnt++].paddr = stolenpa; - } + if (uvm_physseg_valid_p(x) == false) + panic("init_x86_64: can't find end of memory"); + + printf("uvm_physseg_find(atop(avail_end), NULL) == %d\n", + uvm_physseg_find(atop(avail_end), NULL)); + /* Shrink so it'll fit in the last segment. */ + if (uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x) < atop(sz)) + sz = ctob(uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x)); + + uvm_physseg_unplug(uvm_physseg_get_end(x) - atop(sz), atop(sz)); + msgbuf_p_seg[msgbuf_p_cnt].sz = sz; +msgbuf_p_seg[msgbuf_p_cnt++].paddr = ctob(uvm_physseg_get_avail_end(x)); + + /* Now find where the new avail_end is. */ + avail_end = ctob(uvm_physseg_get_avail_end(x)); + + if (sz == reqsz) + return; + + reqsz -= sz; + if (msgbuf_p_cnt == VM_PHYSSEG_MAX) { + /* No more segments available, bail out. */ + printf("WARNING: MSGBUFSIZE (%zu) too large, using %zu.\n", + (size_t)MSGBUFSIZE, (size_t)(MSGBUFSIZE - reqsz)); + return; } - if (sz != reqsz) - printf("%s: could only allocate %ld bytes of requested %ld bytes\n", - __func__, sz, reqsz); + sz = reqsz; + goto search_again; } static void
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Dec 17 13:49:05 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Fix the name of the labels. I think I got confused by jne, so while here replace it by jnz, which is more explicit. To generate a diff of this commit: cvs rdiff -u -r1.117 -r1.118 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.117 src/sys/arch/amd64/amd64/locore.S:1.118 --- src/sys/arch/amd64/amd64/locore.S:1.117 Fri Dec 16 19:52:22 2016 +++ src/sys/arch/amd64/amd64/locore.S Sat Dec 17 13:49:05 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.117 2016/12/16 19:52:22 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.118 2016/12/17 13:49:05 maxv Exp $ */ /* * Copyright-o-rama! @@ -1141,9 +1141,9 @@ skip_CR0: /* The 32bit LWPs are handled differently. */ testl $PCB_COMPAT32,PCB_FLAGS(%r14) - jne lwp_64bit + jnz lwp_32bit -lwp_32bit: +lwp_64bit: /* Zero out %fs/%gs registers. */ xorq %rax,%rax movw %ax,%fs @@ -1170,7 +1170,7 @@ lwp_32bit: jmp switch_return -lwp_64bit: +lwp_32bit: /* Reload %fs/%gs GDT descriptors. */ movq CPUVAR(GDT),%rcx movq PCB_FS(%r14),%rax
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Dec 16 20:16:50 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: This can actually be enabled in Xen; my rev1.235 fixed the issue. Before that kern_end was pointing to DUMMY PAGE, which was already kentered earlier in xen_locore, causing pmap to panic. This change adds support for kernel modules in Xen. To generate a diff of this commit: cvs rdiff -u -r1.238 -r1.239 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.238 src/sys/arch/amd64/amd64/machdep.c:1.239 --- src/sys/arch/amd64/amd64/machdep.c:1.238 Thu Dec 15 12:04:17 2016 +++ src/sys/arch/amd64/amd64/machdep.c Fri Dec 16 20:16:50 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.238 2016/12/15 12:04:17 kamil Exp $ */ +/* $NetBSD: machdep.c,v 1.239 2016/12/16 20:16:50 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.238 2016/12/15 12:04:17 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.239 2016/12/16 20:16:50 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1616,11 +1616,9 @@ init_x86_64(paddr_t first_avail) /* End of the virtual space we have created so far. */ kern_end = (vaddr_t)atdevbase + IOM_SIZE; -#ifndef XEN /* The area for the module map. */ module_start = kern_end; module_end = KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2; -#endif /* * Call pmap initialization to make new kernel address space.
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: pgoyette Date: Mon Dec 12 02:51:24 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Make kernels w/o ACPICA compile. (Same "fix" as Martin made to i386...) cvs: -- To generate a diff of this commit: cvs rdiff -u -r1.236 -r1.237 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.236 src/sys/arch/amd64/amd64/machdep.c:1.237 --- src/sys/arch/amd64/amd64/machdep.c:1.236 Sun Dec 11 08:31:53 2016 +++ src/sys/arch/amd64/amd64/machdep.c Mon Dec 12 02:51:24 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.236 2016/12/11 08:31:53 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.237 2016/12/12 02:51:24 pgoyette Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.236 2016/12/11 08:31:53 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.237 2016/12/12 02:51:24 pgoyette Exp $"); /* #define XENDEBUG_LOW */ @@ -207,6 +207,8 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v #include #define ACPI_MACHDEP_PRIVATE #include +#else +#include #endif #include "isa.h"
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Dec 9 17:57:24 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S machdep.c Log Message: On amd64 we try to guarantee that VA = PA + KERNBASE in the bootstrap memory. But we have a problem with the ISA I/O MEM, because its va is located above the kernel and its pa below it, so it does not respect the rule. To compensate for that we make the map look like the ISA stuff is above the kernel by applying an offset on the pa. The issue with this design is that we systematically lose 96 pages of physical memory. Fix this by applying the offset on the va instead. Now these 96 pages are internalized into uvm, and the rule is respected until kern_end. To generate a diff of this commit: cvs rdiff -u -r1.115 -r1.116 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.234 -r1.235 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.115 src/sys/arch/amd64/amd64/locore.S:1.116 --- src/sys/arch/amd64/amd64/locore.S:1.115 Tue Dec 6 15:05:07 2016 +++ src/sys/arch/amd64/amd64/locore.S Fri Dec 9 17:57:24 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.115 2016/12/06 15:05:07 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.116 2016/12/09 17:57:24 maxv Exp $ */ /* * Copyright-o-rama! @@ -592,6 +592,8 @@ no_NOX: * * (PROC0 STK + L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. * + * ISA I/O MEM has no physical page allocated here, just virtual addresses. + * * Important note: the kernel segments are properly 4k-aligned * (see kern.ldscript), so there's no need to enforce alignment. */ @@ -864,8 +866,8 @@ longmode_hi: movw %ax,%gs movw %ax,%fs - /* XXX merge these */ - leaq (TABLESIZE+IOM_SIZE)(%rsi),%rdi + /* The first physical page available. */ + leaq (TABLESIZE)(%rsi),%rdi #else /* XEN */ /* First, reset the PSL. */ Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.234 src/sys/arch/amd64/amd64/machdep.c:1.235 --- src/sys/arch/amd64/amd64/machdep.c:1.234 Fri Nov 25 11:57:36 2016 +++ src/sys/arch/amd64/amd64/machdep.c Fri Dec 9 17:57:24 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.234 2016/11/25 11:57:36 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.235 2016/12/09 17:57:24 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.234 2016/11/25 11:57:36 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.235 2016/12/09 17:57:24 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1608,7 +1608,7 @@ init_x86_64(paddr_t first_avail) #endif /* !XEN */ /* End of the virtual space we have created so far. */ - kern_end = KERNBASE + first_avail; + kern_end = (vaddr_t)atdevbase + IOM_SIZE; #ifndef XEN /* The area for the module map. */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: kamil Date: Sun Nov 27 02:32:56 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: cpufunc.S Log Message: Fix rdr6() function on amd64 According to the AMD64 SysV ABI the first returned value is passed in RAX, not in RDI. Actually RDI is used for the first argument passed to a function. So far this function was dead code, it will be used for a ptrace(2) feature to support CPU watchpoints. The rdr6() function reads state of the DR6 register and returns its value. Sponsored by To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/arch/amd64/amd64/cpufunc.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/cpufunc.S diff -u src/sys/arch/amd64/amd64/cpufunc.S:1.25 src/sys/arch/amd64/amd64/cpufunc.S:1.26 --- src/sys/arch/amd64/amd64/cpufunc.S:1.25 Wed Feb 12 23:24:09 2014 +++ src/sys/arch/amd64/amd64/cpufunc.S Sun Nov 27 02:32:56 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.S,v 1.25 2014/02/12 23:24:09 dsl Exp $ */ +/* $NetBSD: cpufunc.S,v 1.26 2016/11/27 02:32:56 kamil Exp $ */ /*- * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -163,7 +163,7 @@ ENTRY(ldr6) ret ENTRY(rdr6) - movq %dr6, %rdi + movq %dr6, %rax ret ENTRY(x86_disable_intr)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Tue Nov 15 15:26:59 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: I actually came across the solution to this issue in the Intel SDM for a totally unrelated reason a few weeks ago. The reason we need a particular module_map on amd64 is because gcc makes us use RIP-relative addressing. The offset field of the associated opcodes is a 32bit signed displacement, which means we can access only up to 2GB around the current instruction. And given that kernel_map is too far away from the kernel .text, it is not RIP-addressable. Hence the module_map embedded into the bootstrap memory, which is right above the kernel image. To generate a diff of this commit: cvs rdiff -u -r1.231 -r1.232 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.231 src/sys/arch/amd64/amd64/machdep.c:1.232 --- src/sys/arch/amd64/amd64/machdep.c:1.231 Tue Nov 15 15:00:56 2016 +++ src/sys/arch/amd64/amd64/machdep.c Tue Nov 15 15:26:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.231 2016/11/15 15:00:56 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.232 2016/11/15 15:26:59 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.231 2016/11/15 15:00:56 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.232 2016/11/15 15:26:59 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -377,12 +377,14 @@ cpu_startup(void) /* * Create the module map. * - * XXX: the module map is taken as what is left of the bootstrap memory - * created in locore.S, which is not big enough if we want to load many - * modules dynamically. We really should be using kernel_map instead. + * The kernel uses RIP-relative addressing with a maximum offset of + * 2GB. The problem is, kernel_map is too far away in memory from + * the kernel .text. So we cannot use it, and have to create a + * special module_map. * - * But the modules must be located above the kernel image, and that - * wouldn't be guaranteed if we were using kernel_map. + * The module map is taken as what is left of the bootstrap memory + * created in locore.S. This memory is right above the kernel + * image, so this is the best place to put our modules. */ uvm_map_setup(_map_store, module_start, module_end, 0); module_map_store.pmap = pmap_kernel();
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Nov 11 11:31:26 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Mmh, I mistakenly removed the lapic page (which is part of another diff), put it back in. To generate a diff of this commit: cvs rdiff -u -r1.111 -r1.112 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.111 src/sys/arch/amd64/amd64/locore.S:1.112 --- src/sys/arch/amd64/amd64/locore.S:1.111 Fri Nov 11 10:40:00 2016 +++ src/sys/arch/amd64/amd64/locore.S Fri Nov 11 11:31:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.111 2016/11/11 10:40:00 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.112 2016/11/11 11:31:26 maxv Exp $ */ /* * Copyright-o-rama! @@ -313,6 +313,16 @@ */ .data +#if NLAPIC > 0 + .align PAGE_SIZE + .globl _C_LABEL(local_apic) + + .type _C_LABEL(local_apic), @object +LABEL(local_apic) + .space PAGE_SIZE +END(local_apic) +#endif + .globl _C_LABEL(tablesize) .globl _C_LABEL(nox_flag) .globl _C_LABEL(cputype)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Nov 11 10:40:00 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: KNF and simplify Xen To generate a diff of this commit: cvs rdiff -u -r1.110 -r1.111 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.110 src/sys/arch/amd64/amd64/locore.S:1.111 --- src/sys/arch/amd64/amd64/locore.S:1.110 Sun Oct 16 10:51:31 2016 +++ src/sys/arch/amd64/amd64/locore.S Fri Nov 11 10:40:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.110 2016/10/16 10:51:31 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.111 2016/11/11 10:40:00 maxv Exp $ */ /* * Copyright-o-rama! @@ -313,16 +313,6 @@ */ .data -#if NLAPIC > 0 - .align PAGE_SIZE - .globl _C_LABEL(local_apic) - - .type _C_LABEL(local_apic), @object -LABEL(local_apic) - .space PAGE_SIZE -END(local_apic) -#endif - .globl _C_LABEL(tablesize) .globl _C_LABEL(nox_flag) .globl _C_LABEL(cputype) @@ -887,10 +877,9 @@ longmode_hi: /* * Xen info: * - %rsi -> start_info struct - * - %rsp -> stack, *theoretically* the last used page - * by Xen bootstrap + * - %rsp -> stack, *theoretically* the last used page by Xen bootstrap */ - movq %rsi, %rbx + movq %rsi,%rbx /* Clear BSS. */ xorq %rax,%rax @@ -900,7 +889,7 @@ longmode_hi: rep stosb - /* Copy start_info to a safe place */ + /* Copy start_info to a safe place. */ movq %rbx,%rsi movq $_C_LABEL(start_info_union),%rdi movq $64,%rcx @@ -924,45 +913,40 @@ longmode_hi: */ /* - * We want our own page tables, let's rebuild them - * We will reclaim xen space afterward INCLUDING stack - * so let's change it to a temporary one - */ - - movq $tmpstk, %rax - subq $8, %rax - movq %rax, %rsp + * We want our own page tables, and will rebuild them. We will reclaim + * the Xen space later, INCLUDING the stack. So we need to switch to a + * temporary one now. + */ + movq $tmpstk,%rax + subq $8,%rax + movq %rax,%rsp xorl %eax,%eax cpuid movl %eax,_C_LABEL(cpuid_level) - movq $cpu_info_primary, %rdi - movq %rdi, CPU_INFO_SELF(%rdi) /* ci->ci_self = ci */ - movq $1, %rsi + movq $cpu_info_primary,%rdi + movq %rdi,CPU_INFO_SELF(%rdi) /* ci->ci_self = ci */ + movq $1,%rsi call cpu_init_msrs /* cpu_init_msrs(ci, true); */ call xen_pmap_bootstrap /* - * First avail returned by xen_pmap_bootstrap in %rax + * The first VA available is returned by xen_pmap_bootstrap in %rax. We + * use it as the UAREA, and set up the stack here. */ - movq %rax, %rsi + movq %rax,%rsi movq %rsi,(_C_LABEL(lwp0)+L_PCB) /* XXX L_PCB != uarea */ - - /* - * Set new stack and clear segments - */ leaq (USPACE-FRAMESIZE)(%rsi),%rsp xorq %rbp,%rbp + /* Clear segment registers. */ xorw %ax,%ax movw %ax,%gs movw %ax,%fs - /* - * Set first_avail after proc0 - */ + /* Set first_avail after the UAREA. */ movq %rsi,%rdi addq $USPACE,%rdi subq $KERNBASE,%rdi /* init_x86_64 wants a physical address */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: christos Date: Wed Oct 26 22:02:14 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: print some more stuff To generate a diff of this commit: cvs rdiff -u -r1.86 -r1.87 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.86 src/sys/arch/amd64/amd64/trap.c:1.87 --- src/sys/arch/amd64/amd64/trap.c:1.86 Sun Sep 25 08:53:24 2016 +++ src/sys/arch/amd64/amd64/trap.c Wed Oct 26 18:02:14 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.86 2016/09/25 12:53:24 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.87 2016/10/26 22:02:14 christos Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.86 2016/09/25 12:53:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.87 2016/10/26 22:02:14 christos Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -662,9 +662,10 @@ faultcommon: } #ifdef TRAP_SIGDEBUG - printf("pid %d.%d (%s): signal %d at rip %lx addr %lx " - "error %d\n", p->p_pid, l->l_lid, p->p_comm, ksi.ksi_signo, - frame->tf_rip, va, error); + printf("pid %d.%d (%s): signal %d at rip %#lx addr %#lx " + "error %d trap %d cr2 %p\n", p->p_pid, l->l_lid, p->p_comm, + ksi.ksi_signo, frame->tf_rip, va, error, ksi.ksi_trap, + ksi.ksi_addr); frame_dump(frame); #endif (*p->p_emul->e_trapsignal)(l, );
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Aug 27 16:17:16 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Don't protect the second page, since it is not part of the IDT. To generate a diff of this commit: cvs rdiff -u -r1.229 -r1.230 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.229 src/sys/arch/amd64/amd64/machdep.c:1.230 --- src/sys/arch/amd64/amd64/machdep.c:1.229 Sat Aug 27 16:07:26 2016 +++ src/sys/arch/amd64/amd64/machdep.c Sat Aug 27 16:17:16 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.229 2016/08/27 16:07:26 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.230 2016/08/27 16:17:16 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.229 2016/08/27 16:07:26 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.230 2016/08/27 16:17:16 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1828,8 +1828,6 @@ cpu_reset(void) */ kpreempt_disable(); pmap_changeprot_local(idt_vaddr, VM_PROT_READ|VM_PROT_WRITE); - pmap_changeprot_local(idt_vaddr + PAGE_SIZE, - VM_PROT_READ|VM_PROT_WRITE); memset((void *)idt, 0, NIDT * sizeof(idt[0])); kpreempt_enable(); breakpoint();
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 21 10:42:33 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: Simplify gdt_grow, and make sure we don't kenter more than has been virtually allocated. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.33 src/sys/arch/amd64/amd64/gdt.c:1.34 --- src/sys/arch/amd64/amd64/gdt.c:1.33 Sun Aug 21 10:20:21 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sun Aug 21 10:42:33 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.33 2016/08/21 10:20:21 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.34 2016/08/21 10:42:33 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.33 2016/08/21 10:20:21 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.34 2016/08/21 10:42:33 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -228,21 +228,22 @@ gdt_reload_cpu(struct cpu_info *ci) static void gdt_grow(void) { - size_t old_len, new_len; + size_t old_size; CPU_INFO_ITERATOR cii; struct cpu_info *ci; struct vm_page *pg; vaddr_t va; - old_len = gdt_size; + old_size = gdt_size; gdt_size <<= 1; - new_len = old_len << 1; + if (gdt_size > MAXGDTSIZ) + gdt_size = MAXGDTSIZ; gdt_dynavail = (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); for (CPU_INFO_FOREACH(cii, ci)) { - for (va = (vaddr_t)(ci->ci_gdt) + old_len; - va < (vaddr_t)(ci->ci_gdt) + new_len; + for (va = (vaddr_t)(ci->ci_gdt) + old_size; + va < (vaddr_t)(ci->ci_gdt) + gdt_size; va += PAGE_SIZE) { while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) == NULL) {
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 21 10:20:22 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: Use KASSERT, and panic by default instead of allowing the area to overflow. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.32 src/sys/arch/amd64/amd64/gdt.c:1.33 --- src/sys/arch/amd64/amd64/gdt.c:1.32 Sun Aug 21 10:07:15 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sun Aug 21 10:20:21 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.32 2016/08/21 10:07:15 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.33 2016/08/21 10:20:21 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.32 2016/08/21 10:07:15 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.33 2016/08/21 10:20:21 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -278,22 +278,17 @@ gdt_get_slot(void) slot = gdt_free; gdt_free = gdt[slot].sd_xx3; /* XXXfvdl res. field abuse */ } else { -#ifdef DIAGNOSTIC - if (gdt_next != gdt_dyncount) - panic("gdt_get_slot botch 1"); -#endif + KASSERT(gdt_next == gdt_dyncount); if (gdt_next >= gdt_dynavail) { -#ifdef DIAGNOSTIC if (gdt_size >= MAXGDTSIZ) -panic("gdt_get_slot botch 2"); -#endif +panic("gdt_get_slot: out of memory"); gdt_grow(); } slot = gdt_next++; } gdt_dyncount++; - return (slot); + return slot; } /*
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 21 10:07:15 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: Explain a little what we are doing. Also, make sure gdt_init_cpu is called on the currently running CPU. Theoretically, we could put the same KASSERT in gdt_reload_cpu, but the associated IPI is never sent, which is another issue. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.31 src/sys/arch/amd64/amd64/gdt.c:1.32 --- src/sys/arch/amd64/amd64/gdt.c:1.31 Sun Aug 21 08:30:22 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sun Aug 21 10:07:15 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.31 2016/08/21 08:30:22 christos Exp $ */ +/* $NetBSD: gdt.c,v 1.32 2016/08/21 10:07:15 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.31 2016/08/21 08:30:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.32 2016/08/21 10:07:15 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -105,7 +105,8 @@ set_sys_gdt(int slot, void *base, size_t } /* - * Initialize the GDT. + * Initialize the GDT. We already have a gdtstore, which was temporarily used + * by the bootstrap code. Now, we allocate a new gdtstore, and put it in cpu0. */ void gdt_init(void) @@ -120,11 +121,18 @@ gdt_init(void) gdt_next = 0; gdt_free = GNULL_SEL; gdt_dynavail = - (gdt_size - DYNSEL_START) / sizeof (struct sys_segment_descriptor); + (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); old_gdt = gdtstore; + + /* Allocate MAXGDTSIZ bytes of virtual memory. */ gdtstore = (char *)uvm_km_alloc(kernel_map, MAXGDTSIZ, 0, UVM_KMF_VAONLY); + + /* + * Allocate only MINGDTSIZ bytes of physical memory. We will grow this + * area in gdt_grow at run-time if needed. + */ for (va = (vaddr_t)gdtstore; va < (vaddr_t)gdtstore + MINGDTSIZ; va += PAGE_SIZE) { pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); @@ -135,17 +143,21 @@ gdt_init(void) VM_PROT_READ | VM_PROT_WRITE, 0); } pmap_update(pmap_kernel()); + + /* Copy the initial bootstrap GDT into the new area. */ memcpy(gdtstore, old_gdt, DYNSEL_START); ci->ci_gdt = (void *)gdtstore; #ifndef XEN set_sys_segment(GDT_ADDR_SYS(gdtstore, GLDT_SEL), ldtstore, LDT_SIZE - 1, SDT_SYSLDT, SEL_KPL, 0); #endif + gdt_init_cpu(ci); } /* - * Allocate shadow GDT for a slave CPU. + * Allocate shadow GDT for a secondary CPU. It contains the same values as the + * GDT present in cpu0 (gdtstore). */ void gdt_alloc_cpu(struct cpu_info *ci) @@ -157,6 +169,7 @@ gdt_alloc_cpu(struct cpu_info *ci) ci->ci_gdt = (union descriptor *)uvm_km_alloc(kernel_map, max_len, 0, UVM_KMF_VAONLY); + for (va = (vaddr_t)ci->ci_gdt; va < (vaddr_t)ci->ci_gdt + min_len; va += PAGE_SIZE) { while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) @@ -167,20 +180,22 @@ gdt_alloc_cpu(struct cpu_info *ci) VM_PROT_READ | VM_PROT_WRITE, 0); } pmap_update(pmap_kernel()); + memset(ci->ci_gdt, 0, min_len); memcpy(ci->ci_gdt, gdtstore, gdt_size); } - /* - * Load appropriate gdt descriptor; we better be running on *ci - * (for the most part, this is how a CPU knows who it is). + * Load appropriate GDT descriptor into the currently running CPU, which must + * be ci. */ void gdt_init_cpu(struct cpu_info *ci) { struct region_descriptor region; + KASSERT(curcpu() == ci); + #ifndef XEN setregion(, ci->ci_gdt, (uint16_t)(MAXGDTSIZ - 1)); #else @@ -206,7 +221,9 @@ gdt_reload_cpu(struct cpu_info *ci) #if !defined(XEN) || defined(USER_LDT) /* - * Grow the GDT. + * Grow the GDT. The GDT is present on each CPU, so we need to iterate over all + * of them. We already have the virtual memory, we only need to grow the + * physical memory. */ static void gdt_grow(void) @@ -305,10 +322,13 @@ tss_alloc(struct x86_64_tss *tss) int slot; mutex_enter(_lock); + slot = gdt_get_slot(); - set_sys_gdt(slot, tss, sizeof (struct x86_64_tss) - 1, - SDT_SYS386TSS, SEL_KPL, 0); + set_sys_gdt(slot, tss, sizeof(struct x86_64_tss) - 1, SDT_SYS386TSS, + SEL_KPL, 0); + mutex_exit(_lock); + return GDYNSEL(slot, SEL_KPL); #else /* XEN */ /* TSS, what for? */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 21 09:53:25 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Simplify. To generate a diff of this commit: cvs rdiff -u -r1.108 -r1.109 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.108 src/sys/arch/amd64/amd64/locore.S:1.109 --- src/sys/arch/amd64/amd64/locore.S:1.108 Mon Jul 25 16:03:38 2016 +++ src/sys/arch/amd64/amd64/locore.S Sun Aug 21 09:53:25 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.108 2016/07/25 16:03:38 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.109 2016/08/21 09:53:25 maxv Exp $ */ /* * Copyright-o-rama! @@ -1247,7 +1247,7 @@ IDTVEC_END(syscall32) IDTVEC(syscall) #ifndef XEN /* - * The user %rip is in %rcx and the user %flags in %r11. The kernel %cs + * The user %rip is in %rcx and the user %rflags in %r11. The kernel %cs * and %ss are loaded, but nothing else is. * * The 'swapgs' instruction gives us access to cpu-specific memory where @@ -1266,12 +1266,11 @@ IDTVEC(syscall) /* Make stack look like an 'int nn' frame */ #define SP(x) (x)-(TF_SS+8)(%r15) - movq $(LSEL(LUDATA_SEL, SEL_UPL)),SP(TF_SS) /* user %ss */ - movq %rsp,SP(TF_RSP) /* User space rsp */ - - movq %r11,SP(TF_RFLAGS) /* old rflags from syscall insn */ - movq $(LSEL(LUCODE_SEL, SEL_UPL)),SP(TF_CS) - movq %rcx,SP(TF_RIP) /* syscall saves rip in rcx */ + movq $(LSEL(LUDATA_SEL, SEL_UPL)),SP(TF_SS) /* user %ss */ + movq %rsp,SP(TF_RSP)/* user %rsp */ + movq %r11,SP(TF_RFLAGS) /* user %rflags */ + movq $(LSEL(LUCODE_SEL, SEL_UPL)),SP(TF_CS) /* user %cs */ + movq %rcx,SP(TF_RIP)/* user %rip */ leaq SP(0),%rsp /* %rsp now valid after frame */ movq CPUVAR(SCRATCH),%r15
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: christos Date: Sun Aug 21 08:30:22 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: fix the build. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.30 src/sys/arch/amd64/amd64/gdt.c:1.31 --- src/sys/arch/amd64/amd64/gdt.c:1.30 Sat Aug 20 14:31:06 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sun Aug 21 04:30:22 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.30 2016/08/20 18:31:06 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.31 2016/08/21 08:30:22 christos Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.30 2016/08/20 18:31:06 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.31 2016/08/21 08:30:22 christos Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -64,7 +64,6 @@ int gdt_next; /* next available slot fo int gdt_free; /* next free slot; terminated with GNULL_SEL */ void gdt_init(void); -static void gdt_grow(void); void update_descriptor(void *tp, void *ep) @@ -205,6 +204,7 @@ gdt_reload_cpu(struct cpu_info *ci) } #endif +#if !defined(XEN) || defined(USER_LDT) /* * Grow the GDT. */ @@ -239,7 +239,6 @@ gdt_grow(void) pmap_update(pmap_kernel()); } -#if !defined(XEN) || defined(USER_LDT) /* * Allocate a GDT slot as follows: * 1) If there are entries on the free list, use those.
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Aug 20 18:04:04 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: The GDT needs to be grown on each CPU, and not just gdtstore (cpu0). Otherwise, if the caller gets switched to another CPU, the kernel will end up accessing unallocated memory. Currently, it never happens. The same is done in i386. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.28 src/sys/arch/amd64/amd64/gdt.c:1.29 --- src/sys/arch/amd64/amd64/gdt.c:1.28 Sat Aug 20 17:34:23 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sat Aug 20 18:04:04 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $ */ +/* $NetBSD: gdt.c,v 1.29 2016/08/20 18:04:04 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.29 2016/08/20 18:04:04 maxv Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -206,12 +206,14 @@ gdt_reload_cpu(struct cpu_info *ci) #endif /* - * Grow or shrink the GDT. + * Grow the GDT. */ static void gdt_grow(void) { size_t old_len, new_len; + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; struct vm_page *pg; vaddr_t va; @@ -221,15 +223,19 @@ gdt_grow(void) gdt_dynavail = (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor); - for (va = (vaddr_t)gdtstore + old_len; va < (vaddr_t)gdtstore + new_len; - va += PAGE_SIZE) { - while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) == - NULL) { - uvm_wait("gdt_grow"); + for (CPU_INFO_FOREACH(cii, ci)) { + for (va = (vaddr_t)(ci->ci_gdt) + old_len; + va < (vaddr_t)(ci->ci_gdt) + new_len; + va += PAGE_SIZE) { + while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) == + NULL) { +uvm_wait("gdt_grow"); + } + pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), + VM_PROT_READ | VM_PROT_WRITE, 0); } - pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), - VM_PROT_READ | VM_PROT_WRITE, 0); } + pmap_update(pmap_kernel()); }
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: christos Date: Sat Aug 20 17:34:24 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: gdt.c Log Message: fix the build. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/arch/amd64/amd64/gdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/gdt.c diff -u src/sys/arch/amd64/amd64/gdt.c:1.27 src/sys/arch/amd64/amd64/gdt.c:1.28 --- src/sys/arch/amd64/amd64/gdt.c:1.27 Sat Aug 20 12:05:48 2016 +++ src/sys/arch/amd64/amd64/gdt.c Sat Aug 20 13:34:23 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: gdt.c,v 1.27 2016/08/20 16:05:48 maxv Exp $ */ +/* $NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $ */ /*- * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.27 2016/08/20 16:05:48 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $"); #include "opt_multiprocessor.h" #include "opt_xen.h" @@ -65,8 +65,6 @@ int gdt_free; /* next free slot; termin void gdt_init(void); static void gdt_grow(void); -static int gdt_get_slot(void); -static void gdt_put_slot(int); void update_descriptor(void *tp, void *ep) @@ -235,6 +233,7 @@ gdt_grow(void) pmap_update(pmap_kernel()); } +#if !defined(XEN) || defined(USER_LDT) /* * Allocate a GDT slot as follows: * 1) If there are entries on the free list, use those. @@ -292,6 +291,7 @@ gdt_put_slot(int slot) gdt[slot].sd_xx3 = gdt_free; gdt_free = slot; } +#endif int tss_alloc(struct x86_64_tss *tss)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Aug 19 19:04:57 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: vector.S Log Message: Unused. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/sys/arch/amd64/amd64/vector.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/vector.S diff -u src/sys/arch/amd64/amd64/vector.S:1.46 src/sys/arch/amd64/amd64/vector.S:1.47 --- src/sys/arch/amd64/amd64/vector.S:1.46 Sun Aug 7 10:17:32 2016 +++ src/sys/arch/amd64/amd64/vector.S Fri Aug 19 19:04:57 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: vector.S,v 1.46 2016/08/07 10:17:32 maxv Exp $ */ +/* $NetBSD: vector.S,v 1.47 2016/08/19 19:04:57 maxv Exp $ */ /*- * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -109,13 +109,6 @@ * segment registers. */ -/* XXX See comment in locore.s */ -#ifdef __ELF__ -#define XINTR(name,num) Xintr_ ## name ## num -#else -#define XINTR(name,num) _Xintr_ ## name ## num -#endif - #if NLAPIC > 0 #ifdef MULTIPROCESSOR IDTVEC(recurse_lapic_ipi)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun Aug 7 09:04:55 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S Log Message: Explain a little. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/amd64/amd64/amd64_trap.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.3 src/sys/arch/amd64/amd64/amd64_trap.S:1.4 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.3 Sun Nov 22 13:41:24 2015 +++ src/sys/arch/amd64/amd64/amd64_trap.S Sun Aug 7 09:04:55 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: amd64_trap.S,v 1.3 2015/11/22 13:41:24 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.4 2016/08/07 09:04:55 maxv Exp $ */ /*- * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ #if 0 #include -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.3 2015/11/22 13:41:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.4 2016/08/07 09:04:55 maxv Exp $"); #endif /* @@ -229,28 +229,36 @@ IDTVEC_END(trap0a) IDTVEC(trap0b) /* #NP() Segment not present */ TRAP_NJ(T_SEGNPFLT) jmp check_swapgs -IDTVEC_END(trap0b) /* #NP() Segment not present */ +IDTVEC_END(trap0b) IDTVEC(trap0c) /* #SS() Stack exception */ TRAP_NJ(T_STKFLT) jmp check_swapgs -IDTVEC_END(trap0c) /* #SS() Stack exception */ +IDTVEC_END(trap0c) IDTVEC(trap0d) /* #GP() General protection */ TRAP_NJ(T_PROTFLT) #ifdef check_swapgs jmp check_swapgs #else -/* We need to worry about traps while the kernel %gs_base isn't loaded. - * These are either loads to %gs (only 32bit) or faults on iret during - * return to user. */ +/* + * We need to worry about traps in kernel mode while the kernel %gs isn't + * loaded. These are either faults on iretq during return to user or loads to + * %gs. + * + * When such traps happen, we have CPL=0 and %gs=userland, and we must perform + * an additional swapgs to get %gs=kernel. + */ check_swapgs: INTRENTRY_L(3f,1:) -2: sti +2: + sti jmp calltrap 3: - /* Trap in kernel mode. */ - /* If faulting instruction is 'iret' we may need to do a 'swapgs'. */ + /* + * Trap in kernel mode. + */ + /* Case 1: fault on iretq? */ movq TF_RIP(%rsp),%rax cmpw $0xcf48,(%rax) /* Faulting instruction is iretq ? */ jne 5f /* Jump if not */ @@ -259,7 +267,8 @@ check_swapgs: je 2b /* jump if iret was to kernel */ jmp 1b /* to user - must restore %gs */ 5: - /* Not 'iret', all moves to %gs also need a swapgs */ + + /* Case 2: move to %gs? */ movw (%rax),%ax andb $070,%ah /* mask mod/rm from mod/reg/rm */ cmpw $0x8e+050*256,%ax /* Any move to %gs (reg 5) */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Mon Jul 25 15:29:06 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: mptramp.S Log Message: Unused. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/arch/amd64/amd64/mptramp.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/mptramp.S diff -u src/sys/arch/amd64/amd64/mptramp.S:1.22 src/sys/arch/amd64/amd64/mptramp.S:1.23 --- src/sys/arch/amd64/amd64/mptramp.S:1.22 Thu May 12 09:40:23 2016 +++ src/sys/arch/amd64/amd64/mptramp.S Mon Jul 25 15:29:06 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: mptramp.S,v 1.22 2016/05/12 09:40:23 maxv Exp $ */ +/* $NetBSD: mptramp.S,v 1.23 2016/07/25 15:29:06 maxv Exp $ */ /* * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. @@ -116,7 +116,6 @@ .global _C_LABEL(cpu_spinup_trampoline_end) .global _C_LABEL(cpu_hatch) .global _C_LABEL(mp_pdirpa) - .global _C_LABEL(local_apic) .text .align 4,0x0
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Jul 20 13:49:18 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: This comment is wrong. In fact, we are in low physical memory, but in high virtual memory, and only the latter matters. I'm not exactly sure why, but it appears that the kernel modules must be placed above the kernel image. Just make this comment more ambiguous, in case the next passer-by gets inspired. To generate a diff of this commit: cvs rdiff -u -r1.224 -r1.225 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.224 src/sys/arch/amd64/amd64/machdep.c:1.225 --- src/sys/arch/amd64/amd64/machdep.c:1.224 Sat Jul 16 17:02:34 2016 +++ src/sys/arch/amd64/amd64/machdep.c Wed Jul 20 13:49:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.224 2016/07/16 17:02:34 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.225 2016/07/20 13:49:17 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.224 2016/07/16 17:02:34 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.225 2016/07/20 13:49:17 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -377,9 +377,8 @@ cpu_startup(void) * created in locore.S, which is not big enough if we want to load many * modules dynamically. We really should be using kernel_map instead. * - * But because of the R_X86_64_32 relocations that are usually present - * in dynamic modules, the module map must be in low memory, and this - * wouldn't been guaranteed if we were using kernel_map. + * But the modules must be located above the kernel image, and that + * wouldn't be guaranteed if we were using kernel_map. */ uvm_map_setup(_map_store, module_start, module_end, 0); module_map_store.pmap = pmap_kernel();
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Mon Jul 11 14:52:54 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: KNF and simplify. To generate a diff of this commit: cvs rdiff -u -r1.106 -r1.107 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.106 src/sys/arch/amd64/amd64/locore.S:1.107 --- src/sys/arch/amd64/amd64/locore.S:1.106 Sat Jul 9 06:58:06 2016 +++ src/sys/arch/amd64/amd64/locore.S Mon Jul 11 14:52:54 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.106 2016/07/09 06:58:06 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.107 2016/07/11 14:52:54 maxv Exp $ */ /* * Copyright-o-rama! @@ -985,10 +985,9 @@ longmode_hi: movq %rsi,%rdi addq $USPACE,%rdi subq $KERNBASE,%rdi /* init_x86_64 wants a physical address */ - #endif /* XEN */ - call _C_LABEL(init_x86_64) + call _C_LABEL(init_x86_64) call _C_LABEL(main) END(start) @@ -1175,9 +1174,10 @@ skip_CR0: /* The 32bit LWPs are handled differently. */ testl $PCB_COMPAT32,PCB_FLAGS(%r14) - jne 32f + jne lwp_64bit - /* Zero out %fs/%gs registers and GDT descriptors. */ +lwp_32bit: + /* Zero out %fs/%gs registers. */ xorq %rax,%rax movw %ax,%fs CLI(cx) @@ -1186,6 +1186,7 @@ skip_CR0: SWAPGS STI(cx) + /* Zero out GDT descriptors. */ movq CPUVAR(GDT),%rcx movq %rax,(GUFS_SEL*8)(%rcx) movq %rax,(GUGS_SEL*8)(%rcx) @@ -1199,9 +1200,10 @@ skip_CR0: movl PCB_GS(%r14),%eax movl 4+PCB_GS(%r14),%edx wrmsr + jmp switch_return -32: +lwp_64bit: /* Reload %fs/%gs GDT descriptors. */ movq CPUVAR(GDT),%rcx movq PCB_FS(%r14),%rax @@ -1259,14 +1261,16 @@ IDTVEC_END(syscall32) IDTVEC(syscall) #ifndef XEN /* - * The user %rip is in %rcx and the user %flags in %r11. - * The kernel %cs and %ss are loaded, but nothing else is. - * The 'swapgs' gives us access to cpu-specific memory where - * we can save a user register and then read the lwps - * kernel stack pointer, - * This code doesn't seem to set %ds, this may not matter since it - * is ignored in 64bit mode, OTOH the syscall instruction sets %ss - * and that is ignored as well. + * The user %rip is in %rcx and the user %flags in %r11. The kernel %cs + * and %ss are loaded, but nothing else is. + * + * The 'swapgs' instruction gives us access to cpu-specific memory where + * we can save a user register and then read the LWP's kernel stack + * pointer. + * + * This code doesn't seem to set %ds, this may not matter since it is + * ignored in 64bit mode, OTOH the syscall instruction sets %ss and that + * is ignored as well. */ swapgs movq %r15,CPUVAR(SCRATCH) @@ -1276,19 +1280,19 @@ IDTVEC(syscall) /* Make stack look like an 'int nn' frame */ #define SP(x) (x)-(TF_SS+8)(%r15) - movq $(LSEL(LUDATA_SEL, SEL_UPL)), SP(TF_SS) /* user %ss */ - movq %rsp, SP(TF_RSP) /* User space rsp */ + movq $(LSEL(LUDATA_SEL, SEL_UPL)),SP(TF_SS) /* user %ss */ + movq %rsp,SP(TF_RSP) /* User space rsp */ - movq %r11, SP(TF_RFLAGS) /* old rflags from syscall insn */ - movq $(LSEL(LUCODE_SEL, SEL_UPL)), SP(TF_CS) - movq %rcx, SP(TF_RIP) /* syscall saves rip in rcx */ + movq %r11,SP(TF_RFLAGS) /* old rflags from syscall insn */ + movq $(LSEL(LUCODE_SEL, SEL_UPL)),SP(TF_CS) + movq %rcx,SP(TF_RIP) /* syscall saves rip in rcx */ leaq SP(0),%rsp /* %rsp now valid after frame */ movq CPUVAR(SCRATCH),%r15 #undef SP movq $2,TF_ERR(%rsp) /* syscall instruction size */ - movq $T_ASTFLT, TF_TRAPNO(%rsp) + movq $T_ASTFLT,TF_TRAPNO(%rsp) movw %es,TF_ES(%rsp) sti @@ -1328,27 +1332,29 @@ do_syscall: */ CLI(si) /* Check for ASTs on exit to user mode. */ - movl L_MD_ASTPENDING(%r14), %eax - orl CPUVAR(WANT_PMAPLOAD), %eax + movl L_MD_ASTPENDING(%r14),%eax + orl CPUVAR(WANT_PMAPLOAD),%eax jnz 9f + #ifdef DIAGNOSTIC cmpl $IPL_NONE,CPUVAR(ILEVEL) - jne 3f + jne spl_error #endif - testl $(MDL_IRET | MDL_COMPAT32), L_MD_FLAGS(%r14) + + testl $(MDL_IRET|MDL_COMPAT32),L_MD_FLAGS(%r14) INTR_RESTORE_GPRS movw TF_ES(%rsp),%es SWAPGS jnz 2f #ifndef XEN - movq TF_RIP(%rsp), %rcx /* %rip for sysret */ - movq TF_RFLAGS(%rsp), %r11 /* %flags for sysret */ - movw TF_DS(%rsp), %ds - movq TF_RSP(%rsp), %rsp + movq TF_RIP(%rsp),%rcx /* %rip for sysret */ + movq TF_RFLAGS(%rsp),%r11 /* %flags for sysret */ + movw TF_DS(%rsp),%ds + movq TF_RSP(%rsp),%rsp sysretq #else - movw TF_DS(%rsp), %ds - addq $TF_RIP, %rsp + movw TF_DS(%rsp),%ds + addq $TF_RIP,%rsp pushq $256 /* VGCF_IN_SYSCALL */ jmp HYPERVISOR_iret #endif @@ -1360,13 +1366,14 @@ do_syscall: * then a SIGSEGV will be signalled. */ 2: - movw TF_DS(%rsp), %ds - addq $TF_RIP, %rsp + movw TF_DS(%rsp),%ds + addq $TF_RIP,%rsp iretq -/* Report SPL error */ #ifdef DIAGNOSTIC -3: movabsq $4f, %rdi + /* Report SPL error */ +spl_error: + movabsq $4f,%rdi
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat Jul 2 07:22:10 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Explain why we should use kernel_map instead of module_map, and why we can't. We should probably add some GCC flags in the modules makefiles to make sure the relocations generated are not 32bit. Related to PR/43438. To generate a diff of this commit: cvs rdiff -u -r1.219 -r1.220 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.219 src/sys/arch/amd64/amd64/machdep.c:1.220 --- src/sys/arch/amd64/amd64/machdep.c:1.219 Fri Jul 1 12:41:28 2016 +++ src/sys/arch/amd64/amd64/machdep.c Sat Jul 2 07:22:09 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.219 2016/07/01 12:41:28 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.220 2016/07/02 07:22:09 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.219 2016/07/01 12:41:28 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.220 2016/07/02 07:22:09 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -371,11 +371,22 @@ cpu_startup(void) minaddr = 0; /* - * Allocate a submap for physio + * Allocate a submap for physio. */ phys_map = uvm_km_suballoc(kernel_map, , , - VM_PHYS_SIZE, 0, false, NULL); + VM_PHYS_SIZE, 0, false, NULL); + /* + * Create the module map. + * + * XXX: the module map is taken as what is left of the bootstrap memory + * created in locore.S, which is not big enough if we want to load many + * modules dynamically. We really should be using kernel_map instead. + * + * But because of the R_X86_64_32 relocations that are usually present + * in dynamic modules, the module map must be in low memory, and this + * wouldn't been guaranteed if we were using kernel_map. + */ uvm_map_setup(_map_store, module_start, module_end, 0); module_map_store.pmap = pmap_kernel(); module_map = _map_store;
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Fri Jul 1 12:41:28 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Don't confuse between VM_PROT and UVM_PROT. This should be VM_PROT. To generate a diff of this commit: cvs rdiff -u -r1.218 -r1.219 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.218 src/sys/arch/amd64/amd64/machdep.c:1.219 --- src/sys/arch/amd64/amd64/machdep.c:1.218 Fri Jul 1 10:20:10 2016 +++ src/sys/arch/amd64/amd64/machdep.c Fri Jul 1 12:41:28 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.218 2016/07/01 10:20:10 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.219 2016/07/01 12:41:28 maxv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.218 2016/07/01 10:20:10 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.219 2016/07/01 12:41:28 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -361,7 +361,7 @@ cpu_startup(void) for (x = 0; x < btoc(msgbuf_p_seg[y].sz); x++, sz += PAGE_SIZE) pmap_kenter_pa((vaddr_t)msgbuf_vaddr + sz, msgbuf_p_seg[y].paddr + x * PAGE_SIZE, - VM_PROT_READ | UVM_PROT_WRITE, 0); + VM_PROT_READ | VM_PROT_WRITE, 0); } pmap_update(pmap_kernel());
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun May 29 09:04:20 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Revert rev1.94. It apparently raises a page fault from SMEP. I need to investigate the whole kernel mappings anyway, so I'll recommit this patch later. To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.96 src/sys/arch/amd64/amd64/locore.S:1.97 --- src/sys/arch/amd64/amd64/locore.S:1.96 Sat May 28 09:03:16 2016 +++ src/sys/arch/amd64/amd64/locore.S Sun May 29 09:04:19 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.96 2016/05/28 09:03:16 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.97 2016/05/29 09:04:19 maxv Exp $ */ /* * Copyright-o-rama! @@ -203,11 +203,12 @@ #endif #define PROC0_PML4_OFF 0 -#define PROC0_PTP3_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) +#define PROC0_STK_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) +#define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) #define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) #define PROC0_PTP1_OFF (PROC0_PTP2_OFF + TABLE_L3_ENTRIES * PAGE_SIZE) #define TABLESIZE \ - ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1) \ + ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ * PAGE_SIZE) /* @@ -321,7 +322,6 @@ _C_LABEL(lapic_isr): END(lapic_isr) #endif /* NLAPIC > 0 */ - .globl _C_LABEL(proc0stack) .globl _C_LABEL(nox_flag) .globl _C_LABEL(cpuid_level) .globl _C_LABEL(esym) @@ -335,9 +335,6 @@ END(lapic_isr) .globl _C_LABEL(gdtstore) .globl _C_LABEL(cputype) - .type _C_LABEL(proc0stack), @object -LABEL(proc0stack) .quad 0 /* physical address of proc0's stack */ -END(proc0stack) .type _C_LABEL(nox_flag), @object LABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ END(nox_flag) @@ -585,17 +582,20 @@ no_NOX: * be referred to as: L4 -> L3 -> L2 -> L1. * * Virtual address space of the kernel: - * +--++--+-++-+---+- - * | TEXT | RODATA | DATA | BSS | [SYMS] | [PRELOADED MODULES] | PROC0 STK | - * +--++--+-++-+---+- - * (1) (2) (3) (4) - * - * -+-+-+++ - * L4 -> L3 -> L2 -> L1 | ISA IO MEM | - * -+-+-+++ - * (5) + * +--++--+-++-+-- + * | TEXT | RODATA | DATA | BSS | [SYMS] | [PRELOADED MODULES] | L4 -> + * +--++--+-++-+-- + * (1) (2) (3) + * + * --+-+-+++ + * -> PROC0 STK -> L3 -> L2 -> L1 | ISA IO MEM | + * --+-+-+++ + * (4) * - * (L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. + * PROC0 STK is obviously not linked as a page level. It just happens to be + * caught between L4 and L3. + * + * (PROC0 STK + L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. * * Important note: the kernel segments are properly 4k-aligned * (see kern.ldscript), so there's no need to enforce alignment. @@ -621,17 +621,11 @@ no_NOX: movl %eax,%edi 1: - /* We are on (3). Align up for PROC0 STK. */ + /* We are on (3). Align up for BOOTSTRAP TABLES. */ movl %edi,%esi addl $PGOFSET,%esi andl $~PGOFSET,%esi - /* Save proc0's stack pa, and allocate it. Brings us on (4). */ - movl $RELOC(proc0stack),%ebp - movl %esi,(%ebp) - movl $0,4(%ebp) - addl $USPACE,%esi - /* We are on the BOOTSTRAP TABLES. Save L4's physical address. */ movl $RELOC(PDPpaddr),%ebp movl %esi,(%ebp) @@ -687,19 +681,11 @@ no_NOX: /* Map [SYMS]+[PRELOADED MODULES] RWX. */ movl $RELOC(__kernel_end),%eax - movl RELOC(proc0stack),%ecx /* start of PROC0 STK */ - subl %eax,%ecx - shrl $PGSHIFT,%ecx - orl $(PG_V|PG_KW),%eax - fillkpt - - /* Map PROC0 STK RW. */ - movl RELOC(proc0stack),%eax /* start of PROC0 STK */ movl %esi,%ecx /* start of BOOTSTRAP TABLES */ subl %eax,%ecx shrl $PGSHIFT,%ecx orl $(PG_V|PG_KW),%eax - fillkpt_nox + fillkpt /* Map the BOOTSTRAP TABLES RW. */ movl %esi,%eax /* start of BOOTSTRAP TABLES */ @@ -708,7 +694,7 @@ no_NOX: orl $(PG_V|PG_KW),%eax fillkpt_nox - /* We are on (5). Map ISA I/O mem (later atdevbase) RWX. */ + /* We are on (4). Map ISA I/O mem (later atdevbase) RWX. */ movl $(IOM_BEGIN|PG_V|PG_KW/*|PG_N*/),%eax movl $(IOM_SIZE>>PGSHIFT),%ecx fillkpt @@ -870,7 +856,7 @@ longmode_hi: movq %rdx,_C_LABEL(atdevbase)(%rip) /* Set up bootstrap stack. */ - movq _C_LABEL(proc0stack),%rax + leaq
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat May 28 09:03:16 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Define fillkpt_blank, which creates blank entries in a page table. Use it to map the first MB. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.95 -r1.96 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.95 src/sys/arch/amd64/amd64/locore.S:1.96 --- src/sys/arch/amd64/amd64/locore.S:1.95 Sat May 28 08:43:16 2016 +++ src/sys/arch/amd64/amd64/locore.S Sat May 28 09:03:16 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.95 2016/05/28 08:43:16 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.96 2016/05/28 09:03:16 maxv Exp $ */ /* * Copyright-o-rama! @@ -245,6 +245,20 @@ 2: ; /* + * fillkpt_blank - Fill in a kernel page table with blank entries + * ebx = page table address + * ecx = number of pages to map + */ +#define fillkpt_blank \ + cmpl $0,%ecx ; /* zero-sized? */ \ + je 2f ; \ +1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ + movl $0,(%ebx) ; /* lower 32 bits: 0 */ \ + addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ + loop 1b ; \ +2: ; + +/* * killkpt - Destroy a kernel page table (long mode) * rbx = page table address * rcx = number of pages to destroy @@ -643,12 +657,12 @@ no_NOX: leal (PROC0_PTP1_OFF)(%esi),%ebx /* Skip the first MB. */ - movl $(KERNTEXTOFF_LO - KERNBASE_LO),%eax - movl %eax,%ecx - shrl $(PGSHIFT-3),%ecx /* ((n >> PGSHIFT) << 3) for # PDEs */ - addl %ecx,%ebx + movl $(KERNTEXTOFF_LO - KERNBASE_LO),%ecx + shrl $PGSHIFT,%ecx + fillkpt_blank /* Map the kernel text RX. */ + movl $(KERNTEXTOFF_LO - KERNBASE_LO),%eax /* start of TEXT */ movl $RELOC(__rodata_start),%ecx subl %eax,%ecx shrl $PGSHIFT,%ecx
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat May 28 08:43:17 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Move proc0's stack out of the BOOTSTRAP TABLES, and map it independently with RW permissions. Reduces the impact of a stack overflow. To generate a diff of this commit: cvs rdiff -u -r1.94 -r1.95 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.94 src/sys/arch/amd64/amd64/locore.S:1.95 --- src/sys/arch/amd64/amd64/locore.S:1.94 Thu May 26 07:24:55 2016 +++ src/sys/arch/amd64/amd64/locore.S Sat May 28 08:43:16 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.94 2016/05/26 07:24:55 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.95 2016/05/28 08:43:16 maxv Exp $ */ /* * Copyright-o-rama! @@ -203,12 +203,11 @@ #endif #define PROC0_PML4_OFF 0 -#define PROC0_STK_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) -#define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) +#define PROC0_PTP3_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) #define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) #define PROC0_PTP1_OFF (PROC0_PTP2_OFF + TABLE_L3_ENTRIES * PAGE_SIZE) #define TABLESIZE \ - ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ + ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1) \ * PAGE_SIZE) /* @@ -308,6 +307,7 @@ _C_LABEL(lapic_isr): END(lapic_isr) #endif /* NLAPIC > 0 */ + .globl _C_LABEL(proc0stack) .globl _C_LABEL(nox_flag) .globl _C_LABEL(cpuid_level) .globl _C_LABEL(esym) @@ -321,6 +321,9 @@ END(lapic_isr) .globl _C_LABEL(gdtstore) .globl _C_LABEL(cputype) + .type _C_LABEL(proc0stack), @object +LABEL(proc0stack) .quad 0 /* physical address of proc0's stack */ +END(proc0stack) .type _C_LABEL(nox_flag), @object LABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ END(nox_flag) @@ -568,20 +571,17 @@ no_NOX: * be referred to as: L4 -> L3 -> L2 -> L1. * * Virtual address space of the kernel: - * +--++--+-++-+-- - * | TEXT | RODATA | DATA | BSS | [SYMS] | [PRELOADED MODULES] | L4 -> - * +--++--+-++-+-- - * (1) (2) (3) - * - * --+-+-+++ - * -> PROC0 STK -> L3 -> L2 -> L1 | ISA IO MEM | - * --+-+-+++ - * (4) + * +--++--+-++-+---+- + * | TEXT | RODATA | DATA | BSS | [SYMS] | [PRELOADED MODULES] | PROC0 STK | + * +--++--+-++-+---+- + * (1) (2) (3) (4) + * + * -+-+-+++ + * L4 -> L3 -> L2 -> L1 | ISA IO MEM | + * -+-+-+++ + * (5) * - * PROC0 STK is obviously not linked as a page level. It just happens to be - * caught between L4 and L3. - * - * (PROC0 STK + L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. + * (L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. * * Important note: the kernel segments are properly 4k-aligned * (see kern.ldscript), so there's no need to enforce alignment. @@ -607,11 +607,17 @@ no_NOX: movl %eax,%edi 1: - /* We are on (3). Align up for BOOTSTRAP TABLES. */ + /* We are on (3). Align up for PROC0 STK. */ movl %edi,%esi addl $PGOFSET,%esi andl $~PGOFSET,%esi + /* Save proc0's stack pa, and allocate it. Brings us on (4). */ + movl $RELOC(proc0stack),%ebp + movl %esi,(%ebp) + movl $0,4(%ebp) + addl $USPACE,%esi + /* We are on the BOOTSTRAP TABLES. Save L4's physical address. */ movl $RELOC(PDPpaddr),%ebp movl %esi,(%ebp) @@ -667,12 +673,20 @@ no_NOX: /* Map [SYMS]+[PRELOADED MODULES] RWX. */ movl $RELOC(__kernel_end),%eax - movl %esi,%ecx /* start of BOOTSTRAP TABLES */ + movl RELOC(proc0stack),%ecx /* start of PROC0 STK */ subl %eax,%ecx shrl $PGSHIFT,%ecx orl $(PG_V|PG_KW),%eax fillkpt + /* Map PROC0 STK RW. */ + movl RELOC(proc0stack),%eax /* start of PROC0 STK */ + movl %esi,%ecx /* start of BOOTSTRAP TABLES */ + subl %eax,%ecx + shrl $PGSHIFT,%ecx + orl $(PG_V|PG_KW),%eax + fillkpt_nox + /* Map the BOOTSTRAP TABLES RW. */ movl %esi,%eax /* start of BOOTSTRAP TABLES */ movl $TABLESIZE,%ecx /* length of BOOTSTRAP TABLES */ @@ -680,7 +694,7 @@ no_NOX: orl $(PG_V|PG_KW),%eax fillkpt_nox - /* We are on (4). Map ISA I/O mem (later atdevbase) RWX. */ + /* We are on (5). Map ISA I/O mem (later atdevbase) RWX. */ movl $(IOM_BEGIN|PG_V|PG_KW/*|PG_N*/),%eax movl $(IOM_SIZE>>PGSHIFT),%ecx fillkpt @@ -842,7 +856,7 @@ longmode_hi: movq %rdx,_C_LABEL(atdevbase)(%rip)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun May 22 10:11:55 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Save L4's physical address earlier. Also, PDE_SIZE has nothing to do here, we are just zeroing out the upper 32bits of the 64bit pointer. To generate a diff of this commit: cvs rdiff -u -r1.92 -r1.93 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.92 src/sys/arch/amd64/amd64/locore.S:1.93 --- src/sys/arch/amd64/amd64/locore.S:1.92 Sun May 15 07:17:53 2016 +++ src/sys/arch/amd64/amd64/locore.S Sun May 22 10:11:55 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.92 2016/05/15 07:17:53 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.93 2016/05/22 10:11:55 maxv Exp $ */ /* * Copyright-o-rama! @@ -606,6 +606,11 @@ no_NOX: addl $PGOFSET,%esi andl $~PGOFSET,%esi + /* We are on the BOOTSTRAP TABLES. Save L4's physical address. */ + movl $RELOC(PDPpaddr),%ebp + movl %esi,(%ebp) + movl $0,4(%ebp) + /* Now, zero out the BOOTSTRAP TABLES (before filling them in). */ movl %esi,%edi xorl %eax,%eax @@ -733,11 +738,6 @@ no_NOX: movl %eax,(%ebx) movl $0,(PDE_SIZE-4)(%ebx) - /* Save physical address of L4. */ - movl $RELOC(PDPpaddr),%ebp - movl %esi,(%ebp) - movl $0,(PDE_SIZE-4)(%ebp) - /* * Startup checklist: * 1. Enable PAE (and SSE while here).
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Thu May 12 07:51:10 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Define fillkpt_nox, which sets up a set of pages and puts the NOX bit on them by using nox_flag. Use fillkpt_nox to map the rodata segment without X permissions. To generate a diff of this commit: cvs rdiff -u -r1.88 -r1.89 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.88 src/sys/arch/amd64/amd64/locore.S:1.89 --- src/sys/arch/amd64/amd64/locore.S:1.88 Thu May 12 07:21:18 2016 +++ src/sys/arch/amd64/amd64/locore.S Thu May 12 07:51:09 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.88 2016/05/12 07:21:18 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.89 2016/05/12 07:51:09 maxv Exp $ */ /* * Copyright-o-rama! @@ -227,6 +227,19 @@ loop 1b ; /* + * fillkpt_nox - Same as fillkpt, but sets the NX/XD bit. + */ +#define fillkpt_nox \ + pushl %ebp ; \ + movl RELOC(nox_flag),%ebp ; \ +1: movl %eax,(%ebx) ; /* store phys addr */ \ + movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \ + addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ + addl $PAGE_SIZE,%eax ; /* next phys page */ \ + loop 1b ; \ + popl %ebp ; + +/* * killkpt - Destroy a kernel page table (long mode) * rbx = page table address * rcx = number of pages to destroy @@ -625,13 +638,13 @@ no_NOX: orl $(PG_V|PG_KR),%eax fillkpt - /* Map the kernel rodata ROX. */ + /* Map the kernel rodata RO. */ movl $RELOC(__rodata_start),%eax movl $RELOC(__data_start),%ecx subl %eax,%ecx shrl $PGSHIFT,%ecx orl $(PG_V|PG_KR),%eax - fillkpt + fillkpt_nox /* * We actually have to be careful here. The memory layout is as
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed May 11 19:35:08 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S mptramp.S Log Message: There is a bug in the way the secondary CPUs are launched on amd64. When CPU0 is launched, EFER_NXE is enabled in it, and it allows it to handle pages that have the NOX bit. When the secondary CPUs are launched, however, EFER_NXE is enabled only after paging is set in their %cr0. And therefore, between the moment when paging is enabled and the moment when EFER_NXE is enabled, the secondary CPUs cannot access pages that have the NOX bit - they crash if they try to. The funny thing is that in order to enable EFER_NXE, the secondary CPUs give a look at cpu_feature[2], which is in the DATA segment, which in turn could have the NOX bit. In other words, the secondary CPUs crash if the DATA segment is mapped with the NOX bit. Fix this by enabling EFER_NXE in the secondary CPUs before enabling paging. CPU0 initializes nox_flag to the 32bit version of PG_NX if NOX is supported; the secondary CPUs then use nox_flag to know whether NOX is supported. nox_flag will be used for other purposes soon. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.20 -r1.21 src/sys/arch/amd64/amd64/mptramp.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.85 src/sys/arch/amd64/amd64/locore.S:1.86 --- src/sys/arch/amd64/amd64/locore.S:1.85 Sun May 8 08:22:58 2016 +++ src/sys/arch/amd64/amd64/locore.S Wed May 11 19:35:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.85 2016/05/08 08:22:58 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.86 2016/05/11 19:35:08 maxv Exp $ */ /* * Copyright-o-rama! @@ -187,6 +187,9 @@ #define _RELOC(x) ((x) - KERNBASE) #define RELOC(x) _RELOC(_C_LABEL(x)) +/* 32bit version of PG_NX */ +#define PG_NX32 0x8000 + #if L2_SLOT_KERNBASE > 0 #define TABLE_L2_ENTRIES (2 * (NKL2_KIMG_ENTRIES + 1)) #else @@ -286,6 +289,7 @@ _C_LABEL(lapic_isr): END(lapic_isr) #endif /* NLAPIC > 0 */ + .globl _C_LABEL(nox_flag) .globl _C_LABEL(cpuid_level) .globl _C_LABEL(esym) .globl _C_LABEL(eblob) @@ -298,6 +302,9 @@ END(lapic_isr) .globl _C_LABEL(gdtstore) .globl _C_LABEL(cputype) + .type _C_LABEL(nox_flag), @object +LABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ +END(nox_flag) .type _C_LABEL(cputype), @object LABEL(cputype) .long 0 /* are we 80486, Pentium, or.. */ END(cputype) @@ -527,6 +534,16 @@ biosbasemem_finished: */ movl $RELOC(tmpstk),%esp + /* + * Retrieve the NX/XD flag. We use the 32bit version of PG_NX. + */ + movl $0x8001,%eax + cpuid + andl $CPUID_NOX,%edx + jz no_NOX + movl $PG_NX32,RELOC(nox_flag) +no_NOX: + /* * There are four levels of pages in amd64: PML4 -> PDP -> PD -> PT. They will * be referred to as: L4 -> L3 -> L2 -> L1. @@ -707,13 +724,18 @@ biosbasemem_finished: movl %eax,%cr4 /* - * 2. Set Long Mode Enable in EFER. Also enable the - *syscall extensions. + * 2. Set Long Mode Enable in EFER. Also enable the syscall extensions, + *and NOX if available. */ movl $MSR_EFER,%ecx rdmsr xorl %eax,%eax /* XXX */ orl $(EFER_LME|EFER_SCE),%eax + movl RELOC(nox_flag),%ebx + cmpl $0,%ebx + je skip_NOX + orl $(EFER_NXE),%eax +skip_NOX: wrmsr /* Index: src/sys/arch/amd64/amd64/mptramp.S diff -u src/sys/arch/amd64/amd64/mptramp.S:1.20 src/sys/arch/amd64/amd64/mptramp.S:1.21 --- src/sys/arch/amd64/amd64/mptramp.S:1.20 Sat May 7 13:08:30 2016 +++ src/sys/arch/amd64/amd64/mptramp.S Wed May 11 19:35:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: mptramp.S,v 1.20 2016/05/07 13:08:30 maxv Exp $ */ +/* $NetBSD: mptramp.S,v 1.21 2016/05/11 19:35:08 maxv Exp $ */ /*- * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. @@ -170,10 +170,19 @@ _TRMP_LABEL(mp_startup) no_PSE: movl %eax,%cr4 + /* + * Set Long Mode Enable in EFER. Also enable the syscall extensions, + * and NOX if available. + */ movl $MSR_EFER,%ecx rdmsr xorl %eax,%eax orl $(EFER_LME|EFER_SCE),%eax + movl RELOC(nox_flag),%ebx + cmpl $0,%ebx + je no_NOX + orl $(EFER_NXE),%eax +no_NOX: wrmsr /* Load %cr3. */ @@ -227,17 +236,6 @@ _TRMP_LABEL(mptramp_longmode) _C_LABEL(cpu_spinup_trampoline_end): /* end of code copied to MP_TRAMPOLINE */ - /* - * If EFER_NXE is not enabled, fetching a page with a NX bit set - * will raise a #GP. Avoid that by setting the NXE feature now. - */ - movl _C_LABEL(cpu_feature)+2*4,%eax /* cpu_feature[2] */ - andl $CPUID_NOX,%eax - jz 1f - movl $MSR_EFER,%ecx - rdmsr - orl $EFER_NXE,%eax /* enable No-Execute feature */ - wrmsr 1: /* Don't touch lapic until BP has done init sequence. */
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sun May 8 08:22:58 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Use killkpt for the PML4 entries as well. To generate a diff of this commit: cvs rdiff -u -r1.84 -r1.85 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.84 src/sys/arch/amd64/amd64/locore.S:1.85 --- src/sys/arch/amd64/amd64/locore.S:1.84 Sat May 7 11:49:21 2016 +++ src/sys/arch/amd64/amd64/locore.S Sun May 8 08:22:58 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.84 2016/05/07 11:49:21 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.85 2016/05/08 08:22:58 maxv Exp $ */ /* * Copyright-o-rama! @@ -783,9 +783,7 @@ longmode_hi: movq $NKL4_KIMG_ENTRIES,%rcx leaq (PROC0_PML4_OFF)(%rsi),%rbx /* old, phys address of PML4 */ addq %r8,%rbx /* new, virt address of PML4 */ -1: movq $0,(%rbx) - addq $8,%rbx - loop 1b + killkpt /* Relocate atdevbase. */ movq $(TABLESIZE+KERNBASE),%rdx
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat May 7 13:08:30 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: mptramp.S Log Message: clarify To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/arch/amd64/amd64/mptramp.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/mptramp.S diff -u src/sys/arch/amd64/amd64/mptramp.S:1.19 src/sys/arch/amd64/amd64/mptramp.S:1.20 --- src/sys/arch/amd64/amd64/mptramp.S:1.19 Wed Dec 9 16:55:18 2015 +++ src/sys/arch/amd64/amd64/mptramp.S Sat May 7 13:08:30 2016 @@ -1,13 +1,11 @@ -/* $NetBSD: mptramp.S,v 1.19 2015/12/09 16:55:18 maxv Exp $ */ +/* $NetBSD: mptramp.S,v 1.20 2016/05/07 13:08:30 maxv Exp $ */ /*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by RedBack Networks Inc. - * - * Author: Bill Sommerfeld + * by RedBack Networks Inc. (Author: Bill Sommerfeld), and Maxime Villard. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +28,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - + /* * Copyright (c) 1999 Stefan Grefen * @@ -62,10 +60,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + /* * MP startup ... - * the stuff from cpu_spinup_trampoline to mp_startup - * is copied into the first 640 KB + * the stuff from cpu_spinup_trampoline to mp_startup is copied into the + * first 640 KB. * * We startup the processors now when the kthreads become ready. * The steps are: @@ -74,9 +73,9 @@ * 2) halt the processors waiting for them to be enabled *by a idle-thread */ - + #include "opt_mpbios.h" /* for MPDEBUG */ - + #include "assym.h" #include #include @@ -91,22 +90,27 @@ #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE #ifdef MPDEBUG - /* * Debug code to stop aux. processors in various stages based on the * value in cpu_trace. * - * %edi points at cpu_trace; cpu_trace[0] is the "hold point"; - * cpu_trace[1] is the point which the CPU has reached. + * %edi points at cpu_trace; + * cpu_trace[0] is the "hold point"; + * cpu_trace[1] is the point which the CPU has reached; * cpu_trace[2] is the last value stored by HALTT. */ - -#define HALT(x) 1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi) -#define HALTT(x,y) movl y,8(%edi); HALT(x) +#define HALT(x) \ +1: movl (%edi),%ebx ; \ + cmpl $x,%ebx ; \ + jle 1b ; \ + movl $x,4(%edi) ; +#define HALTT(x,y) \ + movl y,8(%edi) ; \ + HALT(x) ; #else -#define HALT(x) /**/ -#define HALTT(x,y) /**/ -#endif +#define HALT(x) +#define HALTT(x,y) +#endif /* MPDEBUG */ .global _C_LABEL(cpu_spinup_trampoline) .global _C_LABEL(cpu_spinup_trampoline_end) @@ -156,13 +160,14 @@ _TRMP_LABEL(mp_startup) pushl $PSL_MBO popfl + /* Enable PAE, SSE, and PSE if available */ movl %cr4,%eax orl $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT),%eax movl RELOC(pmap_largepages),%ecx orl %ecx,%ecx - jz 1f + jz no_PSE orl $CR4_PSE,%eax -1: +no_PSE: movl %eax,%cr4 movl $MSR_EFER,%ecx @@ -171,12 +176,15 @@ _TRMP_LABEL(mp_startup) orl $(EFER_LME|EFER_SCE),%eax wrmsr + /* Load %cr3. */ movl RELOC(mp_pdirpa),%ecx /* guaranteed < 4G */ - movl %ecx,%cr3 /* load ptd addr into mmu */ + movl %ecx,%cr3 /* load PTD addr into MMU */ - movl %cr0,%eax /* get control word */ + /* Enable paging and the rest of it. */ + movl %cr0,%eax orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM),%eax movl %eax,%cr0 + jmp mptramp_compat mptramp_compat: @@ -194,22 +202,23 @@ _TRMP_LABEL(mptramp_jmp64) .long mptramp_longmode .word GSEL(GCODE_SEL, SEL_KPL) +#define GDT_LIMIT 0x17 /* 23 = 3 * 8 - 1 */ _TRMP_LABEL(mptramp_gdt32) .quad 0x - .quad 0x00cf9f00 - .quad 0x00cf9300 + .quad 0x00cf9f00 /* CS */ + .quad 0x00cf9300 /* DS */ _TRMP_LABEL(mptramp_gdt32_desc) - .word 0x17 + .word GDT_LIMIT .long mptramp_gdt32 _TRMP_LABEL(mptramp_gdt64) .quad 0x - .quad 0x00af9a00 - .quad 0x00cf9200 + .quad 0x00af9a00 /* CS */ + .quad 0x00cf9200 /* DS */ _TRMP_LABEL(mptramp_gdt64_desc) - .word 0x17 + .word GDT_LIMIT .long mptramp_gdt64 - +#undef GDT_LIMIT _TRMP_LABEL(mptramp_longmode) .code64
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Sat May 7 11:49:21 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: clarify To generate a diff of this commit: cvs rdiff -u -r1.83 -r1.84 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.83 src/sys/arch/amd64/amd64/locore.S:1.84 --- src/sys/arch/amd64/amd64/locore.S:1.83 Wed Nov 25 16:00:09 2015 +++ src/sys/arch/amd64/amd64/locore.S Sat May 7 11:49:21 2016 @@ -1,10 +1,39 @@ -/* $NetBSD: locore.S,v 1.83 2015/11/25 16:00:09 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.84 2016/05/07 11:49:21 maxv Exp $ */ /* * Copyright-o-rama! */ /* + * Copyright (c) 1998, 2000, 2007, 2008, 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum and Maxime Villard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Copyright (c) 2007 Manuel Bouyer. * * Redistribution and use in source and binary forms, with or without @@ -80,36 +109,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ - -/*- - * Copyright (c) 1998, 2000, 2007, 2008 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *notice, this list of conditions and the following disclaimer in the - *documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -144,9 +143,7 @@ * @(#)locore.s 7.3 (Berkeley) 5/13/91 */ -/* - * override user-land alignment before including asm.h - */ +/* Override user-land alignment before including asm.h */ #define ALIGN_DATA .align 8 #define ALIGN_TEXT .align 16,0x90 #define _ALIGN_TEXT ALIGN_TEXT @@ -184,7 +181,6 @@ #include #endif -/* XXX temporary kluge; these should not be here */ /* Get definitions for IOM_BEGIN, IOM_END, and IOM_SIZE */ #include @@ -204,7 +200,7 @@ #endif #define PROC0_PML4_OFF 0 -#define PROC0_STK_OFF (PROC0_PML4_OFF + PAGE_SIZE) +#define PROC0_STK_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) #define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) #define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) #define PROC0_PTP1_OFF
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: bouyer Date: Mon Apr 11 14:14:27 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: lock_stubs.S Log Message: __cpu_simple_unlock() is called from _mcount(), so don't call mcount() from __cpu_simple_unlock(). Kernel profiling should work again To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/arch/amd64/amd64/lock_stubs.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/lock_stubs.S diff -u src/sys/arch/amd64/amd64/lock_stubs.S:1.25 src/sys/arch/amd64/amd64/lock_stubs.S:1.26 --- src/sys/arch/amd64/amd64/lock_stubs.S:1.25 Sat Jun 22 06:23:28 2013 +++ src/sys/arch/amd64/amd64/lock_stubs.S Mon Apr 11 14:14:27 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: lock_stubs.S,v 1.25 2013/06/22 06:23:28 uebayasi Exp $ */ +/* $NetBSD: lock_stubs.S,v 1.26 2016/04/11 14:14:27 bouyer Exp $ */ /*- * Copyright (c) 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -319,7 +319,7 @@ NENTRY(__cpu_simple_lock) jmp 2b END(__cpu_simple_lock) -ENTRY(__cpu_simple_unlock) +NENTRY(__cpu_simple_unlock) movb $0, (%rdi) ret END(__cpu_simple_unlock)
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: shm Date: Fri Mar 25 10:14:43 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: db_disasm.c Log Message: Add support for clac and stac instructions. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/arch/amd64/amd64/db_disasm.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/db_disasm.c diff -u src/sys/arch/amd64/amd64/db_disasm.c:1.22 src/sys/arch/amd64/amd64/db_disasm.c:1.23 --- src/sys/arch/amd64/amd64/db_disasm.c:1.22 Tue May 12 23:16:47 2015 +++ src/sys/arch/amd64/amd64/db_disasm.c Fri Mar 25 10:14:43 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: db_disasm.c,v 1.22 2015/05/12 23:16:47 christos Exp $ */ +/* $NetBSD: db_disasm.c,v 1.23 2016/03/25 10:14:43 shm Exp $ */ /* * Mach Operating System @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.22 2015/05/12 23:16:47 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.23 2016/03/25 10:14:43 shm Exp $"); #ifndef _KERNEL #include @@ -1317,6 +1317,12 @@ db_disasm(db_addr_t loc, bool altfmt) if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xf8) { i_name = "swapgs"; i_mode = 0; + } else if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xcb) { + i_name = "stac"; + i_mode = 0; + } else if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xca) { + i_name = "clac"; + i_mode = 0; } else { i_name = ((const char * const *)ip->i_extra) [f_reg(rex, regmodrm)];
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: riastradh Date: Mon Feb 15 20:35:59 UTC 2016 Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: Use KASSERTs supported by CTASSERTs, not __builtin_unreachable. pcc has no __builtin_unreachable, and this is clearer anyway. To generate a diff of this commit: cvs rdiff -u -r1.214 -r1.215 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.214 src/sys/arch/amd64/amd64/machdep.c:1.215 --- src/sys/arch/amd64/amd64/machdep.c:1.214 Sun Nov 22 13:41:24 2015 +++ src/sys/arch/amd64/amd64/machdep.c Mon Feb 15 20:35:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.214 2015/11/22 13:41:24 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.215 2016/02/15 20:35:59 riastradh Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.214 2015/11/22 13:41:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.215 2016/02/15 20:35:59 riastradh Exp $"); /* #define XENDEBUG_LOW */ @@ -2073,9 +2073,11 @@ valid_user_selector(struct lwp *l, uint6 if (off > (len - 8)) return EINVAL; } else { - if (seg != GUDATA_SEL || seg != GUDATA32_SEL) - return EINVAL; - __builtin_unreachable(); + CTASSERT(GUDATA_SEL & SEL_LDT); + KASSERT(seg != GUDATA_SEL); + CTASSERT(GUDATA32_SEL & SEL_LDT); + KASSERT(seg != GUDATA32_SEL); + return EINVAL; } sdp = (struct mem_segment_descriptor *)(dt + off);
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Dec 9 16:55:18 UTC 2015 Modified Files: src/sys/arch/amd64/amd64: copy.S mptramp.S Log Message: KNF, and use C-style comments. Also, remove fusword/susword. To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/arch/amd64/amd64/copy.S cvs rdiff -u -r1.18 -r1.19 src/sys/arch/amd64/amd64/mptramp.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/copy.S diff -u src/sys/arch/amd64/amd64/copy.S:1.19 src/sys/arch/amd64/amd64/copy.S:1.20 --- src/sys/arch/amd64/amd64/copy.S:1.19 Sat Nov 21 12:34:48 2015 +++ src/sys/arch/amd64/amd64/copy.S Wed Dec 9 16:55:18 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: copy.S,v 1.19 2015/11/21 12:34:48 maxv Exp $ */ +/* $NetBSD: copy.S,v 1.20 2015/12/09 16:55:18 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -119,7 +119,7 @@ ENTRY(do_pmap_load) * Also note that the setup time for 'rep movs' is horrid - especially on P4 * netburst - but on my AMD X2 it manages one copy (read+write) per clock * which can be achieved with a code loop, but is probably impossible to beat. - * Howver the use of 'rep movsb' for the final bytes should be killed. + * However the use of 'rep movsb' for the final bytes should be killed. * * Newer Intel cpus have a much lower setup time, and may (someday) * be ably to do cache-line size copies @@ -131,35 +131,37 @@ ENTRY(kcopy) .Lkcopy_start: movq %rdi,%rax subq %rsi,%rax - cmpq %rcx,%rax # overlapping? + cmpq %rcx,%rax /* overlapping? */ jb 1f - # nope, copy forward - shrq $3,%rcx # copy by 64-bit words + /* nope, copy forward */ + shrq $3,%rcx /* copy by 64-bit words */ rep movsq movq %rdx,%rcx - andl $7,%ecx # any bytes left? + andl $7,%ecx /* any bytes left? */ rep movsb xorq %rax,%rax ret -# Using 'rep movs' to copy backwards is not as fast as for forwards copies -# and ought not be done when the copy doesn't acually overlap. -# However kcopy() isn't used any that looks even vaguely used often. -# I'm also not sure it is ever asked to do overlapping copies! +/* + * Using 'rep movs' to copy backwards is not as fast as for forwards copies + * and ought not be done when the copy doesn't acually overlap. + * However kcopy() isn't used any that looks even vaguely used often. + * I'm also not sure it is ever asked to do overlapping copies! + */ -1: addq %rcx,%rdi # copy backward +1: addq %rcx,%rdi /* copy backward */ addq %rcx,%rsi std - andq $7,%rcx # any fractional bytes? + andq $7,%rcx /* any fractional bytes? */ decq %rdi decq %rsi rep movsb - movq %rdx,%rcx # copy remainder by 64-bit words + movq %rdx,%rcx /* copy remainder by 64-bit words */ shrq $3,%rcx subq $7,%rsi subq $7,%rdi @@ -173,24 +175,24 @@ ENTRY(kcopy) ENTRY(copyout) DEFERRED_SWITCH_CHECK - xchgq %rdi,%rsi # kernel address to %rsi, user to %rdi - movq %rdx,%rax # save transfer length (bytes) + xchgq %rdi,%rsi /* kernel address to %rsi, user to %rdi */ + movq %rdx,%rax /* save transfer length (bytes) */ - addq %rdi,%rdx # end address to %rdx - jc _C_LABEL(copy_efault) # jump if wraps + addq %rdi,%rdx /* end address to %rdx */ + jc _C_LABEL(copy_efault) /* jump if wraps */ movq $VM_MAXUSER_ADDRESS,%r8 cmpq %r8,%rdx - ja _C_LABEL(copy_efault) # jump if end in kernel space + ja _C_LABEL(copy_efault) /* jump if end in kernel space */ .Lcopyout_start: - movq %rax,%rcx # length - shrq $3,%rcx # count of 8-byte words + movq %rax,%rcx /* length */ + shrq $3,%rcx /* count of 8-byte words */ rep - movsq# copy from %rsi to %rdi + movsq/* copy from %rsi to %rdi */ movb %al,%cl - andb $7,%cl # remaining number of bytes + andb $7,%cl /* remaining number of bytes */ rep - movsb# copy remaining bytes + movsb/* copy remaining bytes */ .Lcopyout_end: xorl %eax,%eax ret @@ -202,11 +204,11 @@ ENTRY(copyin) xchgq %rdi,%rsi movq %rdx,%rax - addq %rsi,%rdx # Check source address not wrapped + addq %rsi,%rdx /* check source address not wrapped */ jc _C_LABEL(copy_efault) - movq $VM_MAXUSER_ADDRESS,%r8 + movq $VM_MAXUSER_ADDRESS,%r8 cmpq %r8,%rdx - ja _C_LABEL(copy_efault) # j if end in kernel space + ja _C_LABEL(copy_efault) /* j if end in kernel space */ .Lcopyin_start: 3: /* bcopy(%rsi, %rdi, %rax); */ @@ -359,19 +361,7 @@ ENTRY(copystr) 7: ret -ENTRY(fusword) - DEFERRED_SWITCH_CHECK - movq $VM_MAXUSER_ADDRESS-2,%r11 - cmpq %r11,%rdi - ja _C_LABEL(fusuaddrfault) - GET_CURPCB(%rcx) - leaq _C_LABEL(fusufailure)(%rip),%r11 - movq %r11,PCB_ONFAULT(%rcx) - movzwl (%rdi),%eax - movq $0,PCB_ONFAULT(%rcx) - ret - DEFERRED_SWITCH_CALL - + ENTRY(fuswintr) cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE) jnz _C_LABEL(fusuaddrfault) @@ -384,7 +374,7 @@ ENTRY(fuswintr) movzwl (%rdi),%eax movq $0,PCB_ONFAULT(%rcx) ret - + ENTRY(fubyte) DEFERRED_SWITCH_CHECK
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: dholland Date: Sat Nov 28 15:06:55 UTC 2015 Modified Files: src/sys/arch/amd64/amd64: trap.c Log Message: If the kernel jumps to NULL, print where it came from instead of trying to dereference and faulting again. To generate a diff of this commit: cvs rdiff -u -r1.81 -r1.82 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.81 src/sys/arch/amd64/amd64/trap.c:1.82 --- src/sys/arch/amd64/amd64/trap.c:1.81 Sun Nov 22 13:41:24 2015 +++ src/sys/arch/amd64/amd64/trap.c Sat Nov 28 15:06:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.81 2015/11/22 13:41:24 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.82 2015/11/28 15:06:55 dholland Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.81 2015/11/22 13:41:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.82 2015/11/28 15:06:55 dholland Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -342,6 +342,16 @@ kernelfault: /* Get %rsp value before fault - there may be a pad word * below the trap frame. */ vframe = (void *)frame->tf_rsp; + if (frame->tf_rip == 0) { + /* + * Assume that if we jumped to null we + * probably did it via a null function + * pointer, so print the return address. + */ + printf("kernel jumped to null; return addr was %p\n", + *(void **)frame->tf_rsp); + goto we_re_toast; + } switch (*(uint16_t *)frame->tf_rip) { case 0xcf48: /* iretq */ /*
CVS commit: src/sys/arch/amd64/amd64
Module Name:src Committed By: maxv Date: Wed Nov 25 16:00:10 UTC 2015 Modified Files: src/sys/arch/amd64/amd64: locore.S Log Message: Cosmetic changes. To generate a diff of this commit: cvs rdiff -u -r1.82 -r1.83 src/sys/arch/amd64/amd64/locore.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.82 src/sys/arch/amd64/amd64/locore.S:1.83 --- src/sys/arch/amd64/amd64/locore.S:1.82 Sun Nov 22 14:06:08 2015 +++ src/sys/arch/amd64/amd64/locore.S Wed Nov 25 16:00:09 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.82 2015/11/22 14:06:08 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.83 2015/11/25 16:00:09 maxv Exp $ */ /* * Copyright-o-rama! @@ -191,6 +191,43 @@ #define _RELOC(x) ((x) - KERNBASE) #define RELOC(x) _RELOC(_C_LABEL(x)) +#if L2_SLOT_KERNBASE > 0 +#define TABLE_L2_ENTRIES (2 * (NKL2_KIMG_ENTRIES + 1)) +#else +#define TABLE_L2_ENTRIES (NKL2_KIMG_ENTRIES + 1) +#endif + +#if L3_SLOT_KERNBASE > 0 +#define TABLE_L3_ENTRIES (2 * NKL3_KIMG_ENTRIES) +#else +#define TABLE_L3_ENTRIES NKL3_KIMG_ENTRIES +#endif + +#define PROC0_PML4_OFF 0 +#define PROC0_STK_OFF (PROC0_PML4_OFF + PAGE_SIZE) +#define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) +#define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) +#define PROC0_PTP1_OFF (PROC0_PTP2_OFF + TABLE_L3_ENTRIES * PAGE_SIZE) +#define TABLESIZE \ + ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ +* PAGE_SIZE) + +/* + * fillkpt - Fill in a kernel page table + * eax = pte (page frame | control | status) + * ebx = page table address + * ecx = number of pages to map + * + * Each entry is 8 (PDE_SIZE) bytes long: we must set the 4 upper bytes to 0. + */ +#define fillkpt \ +1: movl %eax,(%ebx) ; /* store phys addr */ \ + movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits 0 */ \ + addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ + addl $PAGE_SIZE,%eax ; /* next phys page */ \ + loop 1b ; + + #ifdef XEN /* @@ -358,7 +395,7 @@ ENTRY(start) /* * Load parameters from the stack (32 bits): - * boothowto, [bootdev], bootinfo, esym, basemem, extmem + * boothowto, [bootdev], bootinfo, esym, biosbasemem, biosextmem * We are not interested in 'bootdev'. */ @@ -443,24 +480,29 @@ bootinfo_finished: movl %eax,(%ebp) movl $KERNBASE_HI,4(%ebp) + /* Load 'biosextmem' */ movl $RELOC(biosextmem),%ebp movl (%ebp),%eax - testl %eax,%eax - jnz 1f + testl %eax,%eax /* already set? */ + jnz biosextmem_finished movl 20(%esp),%eax movl %eax,(%ebp) -1: +biosextmem_finished: + /* Load 'biosbasemem' */ movl $RELOC(biosbasemem),%ebp movl (%ebp),%eax - testl %eax,%eax - jnz 1f + testl %eax,%eax /* already set? */ + jnz biosbasemem_finished + movl 24(%esp),%eax movl %eax,(%ebp) -1: - /* First, reset the PSL. */ +biosbasemem_finished: + /* + * Done with the parameters. First, reset the PSL. + */ pushl $PSL_MBO popfl @@ -489,45 +531,9 @@ bootinfo_finished: *0 1 2 3 */ -#if L2_SLOT_KERNBASE > 0 -#define TABLE_L2_ENTRIES (2 * (NKL2_KIMG_ENTRIES + 1)) -#else -#define TABLE_L2_ENTRIES (NKL2_KIMG_ENTRIES + 1) -#endif - -#if L3_SLOT_KERNBASE > 0 -#define TABLE_L3_ENTRIES (2 * NKL3_KIMG_ENTRIES) -#else -#define TABLE_L3_ENTRIES NKL3_KIMG_ENTRIES -#endif - -#define PROC0_PML4_OFF 0 -#define PROC0_STK_OFF (PROC0_PML4_OFF + PAGE_SIZE) -#define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) -#define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) -#define PROC0_PTP1_OFF (PROC0_PTP2_OFF + TABLE_L3_ENTRIES * PAGE_SIZE) -#define TABLESIZE \ - ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ -* PAGE_SIZE) - -/* - * fillkpt - Fill in a kernel page table - * eax = pte (page frame | control | status) - * ebx = page table address - * ecx = number of pages to map - * - * Each entry is 8 (PDE_SIZE) bytes long: we must set the 4 upper bytes to 0. - */ - -#define fillkpt \ -1: movl %eax,(%ebx) ; /* store phys addr */ \ - movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits 0 */ \ - addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ - addl $PAGE_SIZE,%eax ; /* next phys page */ \ - loop 1b ; - /* Find end of kernel image. */ movl $RELOC(end),%edi + #if (NKSYMS || defined(DDB) || defined(MODULAR)) && !defined(makeoptions_COPY_SYMTAB) /* Save the symbols (if loaded). */ movl RELOC(esym),%eax @@ -551,17 +557,18 @@ bootinfo_finished: andl $~PGOFSET,%esi movl %esi,%edi + /* Clear the tables */ xorl %eax,%eax cld movl $TABLESIZE,%ecx shrl $2,%ecx rep - stosl + stosl/* copy eax -> edi */ /* * Build initial page tables. */ - leal (PROC0_PTP1_OFF)(%esi), %ebx + leal (PROC0_PTP1_OFF)(%esi),%ebx /* Skip the first MB */ movl $(KERNTEXTOFF_LO - KERNBASE_LO),%eax @@ -570,9 +577,9 @@