Module Name: src Committed By: cherry Date: Sun Sep 23 15:28:49 UTC 2018
Modified Files: src/sys/arch/i386/i386: cpufunc.S machdep.c src/sys/arch/i386/include: segments.h src/sys/arch/x86/x86: idt.c src/sys/arch/xen/x86: xenfunc.c Log Message: Fix for i386, functionality intended in: http://mail-index.netbsd.org/source-changes/2018/09/23/msg099357.html This should fix the build for both GENERIC and XEN3PAE_DOM0 This has not been boot tested on native or xen3pae Notes: pmap_changeprot_local() seems to be x86_64 only. I was a bit surprised by this initially, but I suspect that the table protections are enforced via ring0/ring1 fencing rather than page protections the gdt registration code in i386 is still messy. I will leave it as is for now - to avoid a rabbit hole. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/arch/i386/i386/cpufunc.S cvs rdiff -u -r1.809 -r1.810 src/sys/arch/i386/i386/machdep.c cvs rdiff -u -r1.66 -r1.67 src/sys/arch/i386/include/segments.h cvs rdiff -u -r1.7 -r1.8 src/sys/arch/x86/x86/idt.c cvs rdiff -u -r1.20 -r1.21 src/sys/arch/xen/x86/xenfunc.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/i386/i386/cpufunc.S diff -u src/sys/arch/i386/i386/cpufunc.S:1.23 src/sys/arch/i386/i386/cpufunc.S:1.24 --- src/sys/arch/i386/i386/cpufunc.S:1.23 Sat Jul 21 16:21:27 2018 +++ src/sys/arch/i386/i386/cpufunc.S Sun Sep 23 15:28:48 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.S,v 1.23 2018/07/21 16:21:27 maxv Exp $ */ +/* $NetBSD: cpufunc.S,v 1.24 2018/09/23 15:28:48 cherry Exp $ */ /*- * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/errno.h> #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.23 2018/07/21 16:21:27 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.24 2018/09/23 15:28:48 cherry Exp $"); #include "opt_xen.h" @@ -65,11 +65,13 @@ ENTRY(x86_mfence) ret END(x86_mfence) -ENTRY(lidt) +#ifndef XEN + ENTRY(lidt) movl 4(%esp), %eax lidt (%eax) ret END(lidt) +#endif /* XEN */ ENTRY(rcr3) movl %cr3, %eax Index: src/sys/arch/i386/i386/machdep.c diff -u src/sys/arch/i386/i386/machdep.c:1.809 src/sys/arch/i386/i386/machdep.c:1.810 --- src/sys/arch/i386/i386/machdep.c:1.809 Sun Sep 23 00:59:59 2018 +++ src/sys/arch/i386/i386/machdep.c Sun Sep 23 15:28:48 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.809 2018/09/23 00:59:59 cherry Exp $ */ +/* $NetBSD: machdep.c,v 1.810 2018/09/23 15:28:48 cherry Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009, 2017 @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.809 2018/09/23 00:59:59 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.810 2018/09/23 15:28:48 cherry Exp $"); #include "opt_beep.h" #include "opt_compat_freebsd.h" @@ -1360,19 +1360,20 @@ init386(paddr_t first_avail) default: break; } - set_istgate(&idt[x], IDTVEC(exceptions)[x], 0, SDT_SYS386IGT, + set_idtgate(&idt[x], IDTVEC(exceptions)[x], 0, SDT_SYS386IGT, sel, GSEL(GCODE_SEL, SEL_KPL)); } /* new-style interrupt gate for syscalls */ idt_vec_reserve(128); - set_istgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386IGT, SEL_UPL, + set_idtgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386IGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); +#ifndef XEN setregion(®ion, gdtstore, NGDT * sizeof(gdtstore[0]) - 1); lgdt(®ion); - - cpu_init_idt(); +#endif + lldt(GSEL(GLDT_SEL, SEL_KPL)); cpu_init_idt(); Index: src/sys/arch/i386/include/segments.h diff -u src/sys/arch/i386/include/segments.h:1.66 src/sys/arch/i386/include/segments.h:1.67 --- src/sys/arch/i386/include/segments.h:1.66 Sun Sep 23 07:54:42 2018 +++ src/sys/arch/i386/include/segments.h Sun Sep 23 15:28:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: segments.h,v 1.66 2018/09/23 07:54:42 cherry Exp $ */ +/* $NetBSD: segments.h,v 1.67 2018/09/23 15:28:49 cherry Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -200,7 +200,7 @@ extern idt_descriptor_t *idt; extern union descriptor *gdtstore, *ldtstore; void setgate(struct gate_descriptor *, void *, int, int, int, int); -void set_idtgate(idt_descriptor_t *, void *, int, int, int); +void set_idtgate(idt_descriptor_t *, void *, int, int, int, int); void unset_idtgate(idt_descriptor_t *); void setregion(struct region_descriptor *, void *, size_t); void setsegment(struct segment_descriptor *, const void *, size_t, int, int, Index: src/sys/arch/x86/x86/idt.c diff -u src/sys/arch/x86/x86/idt.c:1.7 src/sys/arch/x86/x86/idt.c:1.8 --- src/sys/arch/x86/x86/idt.c:1.7 Sun Sep 23 00:59:59 2018 +++ src/sys/arch/x86/x86/idt.c Sun Sep 23 15:28:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: idt.c,v 1.7 2018/09/23 00:59:59 cherry Exp $ */ +/* $NetBSD: idt.c,v 1.8 2018/09/23 15:28:49 cherry Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2009 The NetBSD Foundation, Inc. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: idt.c,v 1.7 2018/09/23 00:59:59 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: idt.c,v 1.8 2018/09/23 15:28:49 cherry Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -107,9 +107,10 @@ set_idtgate(idt_descriptor_t *xen_idd, v vaddr_t xen_idt_vaddr = ((vaddr_t) xen_idd) & ~PAGE_MASK; //kpreempt_disable(); +#if defined(__x86_64__) /* Make it writeable, so we can update the values. */ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ|VM_PROT_WRITE); - +#endif /* __x86_64 */ xen_idd->cs = sel; xen_idd->address = (unsigned long) function; xen_idd->flags = dpl; @@ -122,24 +123,30 @@ set_idtgate(idt_descriptor_t *xen_idd, v xen_idd->vector = xen_idd - (idt_descriptor_t *)xen_idt_vaddr; /* Back to read-only, as it should be. */ +#if defined(__x86_64__) pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ); +#endif /* __x86_64 */ //kpreempt_enable(); } void unset_idtgate(idt_descriptor_t *xen_idd) { +#if defined(__x86_64__) vaddr_t xen_idt_vaddr = ((vaddr_t) xen_idd) & PAGE_MASK; /* Make it writeable, so we can update the values. */ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ|VM_PROT_WRITE); - +#endif /* __x86_64 */ + /* Zero it */ memset(xen_idd, 0, sizeof (*xen_idd)); +#if defined(__x86_64__) /* Back to read-only, as it should be. */ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ); +#endif /* __x86_64 */ } -#else +#else /* XEN */ void set_idtgate(idt_descriptor_t *idd, void *function, int ist, int type, int dpl, int sel) { @@ -150,7 +157,7 @@ unset_idtgate(idt_descriptor_t *idd) { unsetgate(idd); } -#endif +#endif /* XEN */ /* * Allocate an IDT vector slot within the given range. Index: src/sys/arch/xen/x86/xenfunc.c diff -u src/sys/arch/xen/x86/xenfunc.c:1.20 src/sys/arch/xen/x86/xenfunc.c:1.21 --- src/sys/arch/xen/x86/xenfunc.c:1.20 Sun Sep 23 00:59:59 2018 +++ src/sys/arch/xen/x86/xenfunc.c Sun Sep 23 15:28:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: xenfunc.c,v 1.20 2018/09/23 00:59:59 cherry Exp $ */ +/* $NetBSD: xenfunc.c,v 1.21 2018/09/23 15:28:49 cherry Exp $ */ /* * Copyright (c) 2004 Christian Limpach. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.20 2018/09/23 00:59:59 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.21 2018/09/23 15:28:49 cherry Exp $"); #include <sys/param.h> @@ -80,15 +80,19 @@ lidt(struct region_descriptor *rd) xen_idt[xen_idt_idx++] = idd[i]; } +#if defined(__x86_64__) /* page needs to be r/o */ pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ); +#endif /* __x86_64 */ /* Hook it up in the hypervisor */ if (HYPERVISOR_set_trap_table(xen_idt)) panic("HYPERVISOR_set_trap_table() failed"); +#if defined(__x86_64__) /* reset */ pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE); +#endif /* __x86_64 */ } void