Module Name: src
Committed By: cherry
Date: Sun Sep 23 01:00:00 UTC 2018
Modified Files:
src/sys/arch/amd64/amd64: db_interface.c machdep.c
src/sys/arch/amd64/include: segments.h
src/sys/arch/i386/i386: machdep.c
src/sys/arch/i386/include: segments.h
src/sys/arch/x86/x86: idt.c lapic.c
src/sys/arch/xen/x86: xenfunc.c
Log Message:
Make XEN use the same api as native, for idt vector allocation
and registration.
lidt() placed in xenfunc() on maxv@ suggestion.
There should be no functional change due to this commit.
Tested on amd64 native and XEN.
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/amd64/amd64/db_interface.c
cvs rdiff -u -r1.318 -r1.319 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/amd64/include/segments.h
cvs rdiff -u -r1.808 -r1.809 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.64 -r1.65 src/sys/arch/i386/include/segments.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/x86/x86/idt.c
cvs rdiff -u -r1.66 -r1.67 src/sys/arch/x86/x86/lapic.c
cvs rdiff -u -r1.19 -r1.20 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/amd64/amd64/db_interface.c
diff -u src/sys/arch/amd64/amd64/db_interface.c:1.33 src/sys/arch/amd64/amd64/db_interface.c:1.34
--- src/sys/arch/amd64/amd64/db_interface.c:1.33 Tue Apr 3 07:20:52 2018
+++ src/sys/arch/amd64/amd64/db_interface.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.33 2018/04/03 07:20:52 christos Exp $ */
+/* $NetBSD: db_interface.c,v 1.34 2018/09/23 00:59:59 cherry Exp $ */
/*
* Mach Operating System
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.33 2018/04/03 07:20:52 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.34 2018/09/23 00:59:59 cherry Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -113,7 +113,7 @@ db_machine_init(void)
handler = &Xintr_x2apic_ddbipi;
#endif
ddb_vec = idt_vec_alloc(0xf0, 0xff);
- setgate(&idt[ddb_vec], handler, 1, SDT_SYS386IGT, SEL_KPL,
+ set_idtgate(&idt[ddb_vec], handler, 1, SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
#else
/* Initialised as part of xen_ipi_init() */
Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.318 src/sys/arch/amd64/amd64/machdep.c:1.319
--- src/sys/arch/amd64/amd64/machdep.c:1.318 Wed Aug 29 16:26:25 2018
+++ src/sys/arch/amd64/amd64/machdep.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.318 2018/08/29 16:26:25 maxv Exp $ */
+/* $NetBSD: machdep.c,v 1.319 2018/09/23 00:59:59 cherry Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.318 2018/08/29 16:26:25 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.319 2018/09/23 00:59:59 cherry Exp $");
#include "opt_modular.h"
#include "opt_user_ldt.h"
@@ -1397,11 +1397,6 @@ setregs(struct lwp *l, struct exec_packa
/*
* Initialize segments and descriptor tables
*/
-
-#ifdef XEN
-struct trap_info *xen_idt;
-int xen_idt_idx;
-#endif
char *ldtstore;
char *gdtstore;
@@ -1486,15 +1481,10 @@ set_sys_segment(struct sys_segment_descr
void
cpu_init_idt(void)
{
-#ifndef XEN
struct region_descriptor region;
setregion(®ion, idt, NIDT * sizeof(idt[0]) - 1);
lidt(®ion);
-#else
- if (HYPERVISOR_set_trap_table(xen_idt))
- panic("HYPERVISOR_set_trap_table() failed");
-#endif
}
#define IDTVEC(name) __CONCAT(X, name)
@@ -1681,7 +1671,6 @@ init_x86_64(paddr_t first_avail)
extern vaddr_t lwp0uarea;
#ifndef XEN
extern paddr_t local_apic_pa;
- int ist;
#endif
KASSERT(first_avail % PAGE_SIZE == 0);
@@ -1806,12 +1795,7 @@ init_x86_64(paddr_t first_avail)
pmap_update(pmap_kernel());
-#ifndef XEN
- idt = (struct gate_descriptor *)idt_vaddr;
-#else
- xen_idt = (struct trap_info *)idt_vaddr;
- xen_idt_idx = 0;
-#endif
+ idt = (idt_descriptor_t *)idt_vaddr;
gdtstore = (char *)gdt_vaddr;
ldtstore = (char *)ldt_vaddr;
@@ -1870,8 +1854,14 @@ init_x86_64(paddr_t first_avail)
/* CPU-specific IDT exceptions. */
for (x = 0; x < NCPUIDT; x++) {
-#ifndef XEN
+ int sel, ist;
+
+ /* Reset to default. Special cases below */
+ sel = SEL_KPL;
+ ist = 0;
+
idt_vec_reserve(x);
+
switch (x) {
case 1: /* DB */
ist = 4;
@@ -1879,56 +1869,31 @@ init_x86_64(paddr_t first_avail)
case 2: /* NMI */
ist = 3;
break;
+ case 3:
+ case 4:
+ sel = SEL_UPL;
+ break;
case 8: /* double fault */
ist = 2;
break;
- default:
- ist = 0;
- break;
- }
- setgate(&idt[x], x86_exceptions[x], ist, SDT_SYS386IGT,
- (x == 3 || x == 4) ? SEL_UPL : SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
-#else /* XEN */
- pmap_changeprot_local(idt_vaddr, VM_PROT_READ|VM_PROT_WRITE);
- idt_vec_reserve(x);
- xen_idt[xen_idt_idx].vector = x;
-
- switch (x) {
- case 2: /* NMI */
+#ifdef XEN
case 18: /* MCA */
- TI_SET_IF(&(xen_idt[xen_idt_idx]), 2);
- break;
- case 3:
- case 4:
- xen_idt[xen_idt_idx].flags = SEL_UPL;
+ sel |= 0x4; /* Auto EOI/mask */
break;
+#endif /* XEN */
default:
- xen_idt[xen_idt_idx].flags = SEL_KPL;
break;
}
- xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
- xen_idt[xen_idt_idx].address =
- (unsigned long)x86_exceptions[x];
- xen_idt_idx++;
-#endif /* XEN */
+ set_idtgate(&idt[x], x86_exceptions[x], ist, SDT_SYS386IGT,
+ sel, GSEL(GCODE_SEL, SEL_KPL));
}
/* new-style interrupt gate for syscalls */
-#ifndef XEN
idt_vec_reserve(128);
- setgate(&idt[128], &IDTVEC(osyscall), 0, SDT_SYS386IGT, SEL_UPL,
+ set_idtgate(&idt[128], &IDTVEC(osyscall), 0, SDT_SYS386IGT, SEL_UPL,
GSEL(GCODE_SEL, SEL_KPL));
-#else
- idt_vec_reserve(128);
- xen_idt[xen_idt_idx].vector = 128;
- xen_idt[xen_idt_idx].flags = SEL_KPL;
- xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
- xen_idt[xen_idt_idx].address = (unsigned long) &IDTVEC(osyscall);
- xen_idt_idx++;
- pmap_changeprot_local(idt_vaddr, VM_PROT_READ);
-#endif /* XEN */
+
kpreempt_enable();
setregion(®ion, gdtstore, DYNSEL_START - 1);
Index: src/sys/arch/amd64/include/segments.h
diff -u src/sys/arch/amd64/include/segments.h:1.34 src/sys/arch/amd64/include/segments.h:1.35
--- src/sys/arch/amd64/include/segments.h:1.34 Sun Dec 31 08:29:38 2017
+++ src/sys/arch/amd64/include/segments.h Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: segments.h,v 1.34 2017/12/31 08:29:38 maxv Exp $ */
+/* $NetBSD: segments.h,v 1.35 2018/09/23 00:59:59 cherry Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -234,15 +234,18 @@ struct region_descriptor {
#ifdef _KERNEL
#ifdef XEN
-extern struct trap_info *idt;
+typedef struct trap_info idt_descriptor_t;
#else
-extern struct gate_descriptor *idt;
-#endif
+typedef struct gate_descriptor idt_descriptor_t;
+#endif /* XEN */
+extern idt_descriptor_t *idt;
extern char *gdtstore;
extern char *ldtstore;
void setgate(struct gate_descriptor *, void *, int, int, int, int);
void unsetgate(struct gate_descriptor *);
+void set_idtgate(idt_descriptor_t *, void *, int, int, int, int);
+void unset_idtgate(idt_descriptor_t *);
void setregion(struct region_descriptor *, void *, uint16_t);
void set_sys_segment(struct sys_segment_descriptor *, void *, size_t,
int, int, int);
Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.808 src/sys/arch/i386/i386/machdep.c:1.809
--- src/sys/arch/i386/i386/machdep.c:1.808 Thu Jul 26 09:29:08 2018
+++ src/sys/arch/i386/i386/machdep.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.808 2018/07/26 09:29:08 maxv Exp $ */
+/* $NetBSD: machdep.c,v 1.809 2018/09/23 00:59:59 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.808 2018/07/26 09:29:08 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.809 2018/09/23 00:59:59 cherry Exp $");
#include "opt_beep.h"
#include "opt_compat_freebsd.h"
@@ -580,7 +580,7 @@ cpu_set_tss_gates(struct cpu_info *ci)
SDT_SYS386TSS, SEL_KPL, 0, 0);
ci->ci_gdt[GTRAPTSS_SEL].sd = sd;
- setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
+ set_idtgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
GSEL(GTRAPTSS_SEL, SEL_KPL));
#if defined(DDB) && defined(MULTIPROCESSOR)
@@ -602,7 +602,7 @@ cpu_set_tss_gates(struct cpu_info *ci)
SDT_SYS386TSS, SEL_KPL, 0, 0);
ci->ci_gdt[GIPITSS_SEL].sd = sd;
- setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
+ set_idtgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
GSEL(GIPITSS_SEL, SEL_KPL));
#endif
}
@@ -960,23 +960,15 @@ setsegment(struct segment_descriptor *sd
extern vector IDTVEC(syscall);
extern vector *IDTVEC(exceptions)[];
#ifdef XEN
-#define MAX_XEN_IDT 128
-trap_info_t xen_idt[MAX_XEN_IDT];
-int xen_idt_idx;
extern union descriptor tmpgdt[];
#endif
void
cpu_init_idt(void)
{
-#ifndef XEN
struct region_descriptor region;
setregion(®ion, pentium_idt, NIDT * sizeof(idt[0]) - 1);
lidt(®ion);
-#else
- if (HYPERVISOR_set_trap_table(xen_idt))
- panic("HYPERVISOR_set_trap_table %p failed\n", xen_idt);
-#endif
}
void
@@ -1342,62 +1334,47 @@ init386(paddr_t first_avail)
ldtstore[LUCODEBIG_SEL] = gdtstore[GUCODEBIG_SEL];
ldtstore[LUDATA_SEL] = gdtstore[GUDATA_SEL];
-#ifndef XEN
/* exceptions */
for (x = 0; x < 32; x++) {
- idt_vec_reserve(x);
- setgate(&idt[x], IDTVEC(exceptions)[x], 0, SDT_SYS386IGT,
- (x == 3 || x == 4) ? SEL_UPL : SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- }
-
- /* new-style interrupt gate for syscalls */
- idt_vec_reserve(128);
- setgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386IGT, SEL_UPL,
- GSEL(GCODE_SEL, SEL_KPL));
-
- setregion(®ion, gdtstore, NGDT * sizeof(gdtstore[0]) - 1);
- lgdt(®ion);
+ /* Reset to default. Special cases below */
+ int sel;
+#ifdef XEN
+ sel = SEL_XEN;
+#else
+ sel = SEL_KPL;
+#endif /* XEN */
- cpu_init_idt();
-#else /* !XEN */
- memset(xen_idt, 0, sizeof(trap_info_t) * MAX_XEN_IDT);
- xen_idt_idx = 0;
- for (x = 0; x < 32; x++) {
- KASSERT(xen_idt_idx < MAX_XEN_IDT);
idt_vec_reserve(x);
- xen_idt[xen_idt_idx].vector = x;
- switch (x) {
+ switch (x) {
+#ifdef XEN
case 2: /* NMI */
case 18: /* MCA */
- TI_SET_IF(&(xen_idt[xen_idt_idx]), 2);
+ sel |= 0x4; /* Auto EOI/mask */
break;
+#endif /* XEN */
case 3:
case 4:
- xen_idt[xen_idt_idx].flags = SEL_UPL;
+ sel = SEL_UPL;
break;
default:
- xen_idt[xen_idt_idx].flags = SEL_XEN;
break;
}
-
- xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
- xen_idt[xen_idt_idx].address =
- (uint32_t)IDTVEC(exceptions)[x];
- xen_idt_idx++;
+ set_istgate(&idt[x], IDTVEC(exceptions)[x], 0, SDT_SYS386IGT,
+ sel, GSEL(GCODE_SEL, SEL_KPL));
}
- KASSERT(xen_idt_idx < MAX_XEN_IDT);
+
+ /* new-style interrupt gate for syscalls */
idt_vec_reserve(128);
- xen_idt[xen_idt_idx].vector = 128;
- xen_idt[xen_idt_idx].flags = SEL_UPL;
- xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
- xen_idt[xen_idt_idx].address = (uint32_t)&IDTVEC(syscall);
- xen_idt_idx++;
- KASSERT(xen_idt_idx < MAX_XEN_IDT);
+ set_istgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386IGT, SEL_UPL,
+ GSEL(GCODE_SEL, SEL_KPL));
+
+ setregion(®ion, gdtstore, NGDT * sizeof(gdtstore[0]) - 1);
+ lgdt(®ion);
+
+ cpu_init_idt();
lldt(GSEL(GLDT_SEL, SEL_KPL));
cpu_init_idt();
-#endif /* XEN */
init386_ksyms();
Index: src/sys/arch/i386/include/segments.h
diff -u src/sys/arch/i386/include/segments.h:1.64 src/sys/arch/i386/include/segments.h:1.65
--- src/sys/arch/i386/include/segments.h:1.64 Sun Dec 31 08:29:38 2017
+++ src/sys/arch/i386/include/segments.h Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: segments.h,v 1.64 2017/12/31 08:29:38 maxv Exp $ */
+/* $NetBSD: segments.h,v 1.65 2018/09/23 00:59:59 cherry Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -191,14 +191,23 @@ struct region_descriptor {
#endif
#ifdef _KERNEL
+#ifdef XEN
+typedef struct trap_info idt_descriptor_t;
+#else
+typedef struct gate_descriptor idt_descriptor_t;
+#endif /* XEN */
+extern idt_descriptor_t *idt;
extern union descriptor *gdtstore, *ldtstore;
extern struct gate_descriptor *idt;
void setgate(struct gate_descriptor *, void *, int, int, int, int);
+void set_idtgate(idt_descriptor_t *, void *, 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,
int, int);
void unsetgate(struct gate_descriptor *);
+
void cpu_init_idt(void);
void update_descriptor(union descriptor *, union descriptor *);
Index: src/sys/arch/x86/x86/idt.c
diff -u src/sys/arch/x86/x86/idt.c:1.6 src/sys/arch/x86/x86/idt.c:1.7
--- src/sys/arch/x86/x86/idt.c:1.6 Sat Nov 4 08:50:47 2017
+++ src/sys/arch/x86/x86/idt.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: idt.c,v 1.6 2017/11/04 08:50:47 cherry Exp $ */
+/* $NetBSD: idt.c,v 1.7 2018/09/23 00:59:59 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.6 2017/11/04 08:50:47 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: idt.c,v 1.7 2018/09/23 00:59:59 cherry Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -73,16 +73,85 @@ __KERNEL_RCSID(0, "$NetBSD: idt.c,v 1.6
#include <sys/cpu.h>
#include <sys/atomic.h>
-#include <machine/segments.h>
+#include <uvm/uvm.h>
-/* On xen PV this is just numberspace management - used in x86/intr.c */
-#if !defined(XEN)
+#include <machine/segments.h>
-struct gate_descriptor *idt;
-#endif
+/*
+ * XEN PV and native have a different idea of what idt entries should
+ * look like.
+ */
+idt_descriptor_t *idt;
static char idt_allocmap[NIDT];
+/* Normalise across XEN PV and native */
+#if defined(XEN)
+
+void
+set_idtgate(idt_descriptor_t *xen_idd, void *function, int ist,
+ int type, int dpl, int sel)
+{
+ /*
+ * Find the page boundary in which the descriptor resides.
+ * We make an assumption here, that the descriptor is part of
+ * a table (array), which fits in a page and is page aligned.
+ *
+ * This assumption is from the usecases at early startup in
+ * machine/machdep.c
+ *
+ * Thus this function may not work in the "general" case of a
+ * randomly located idt entry template (for eg:).
+ */
+
+ vaddr_t xen_idt_vaddr = ((vaddr_t) xen_idd) & ~PAGE_MASK;
+
+ //kpreempt_disable();
+ /* Make it writeable, so we can update the values. */
+ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ|VM_PROT_WRITE);
+
+ xen_idd->cs = sel;
+ xen_idd->address = (unsigned long) function;
+ xen_idd->flags = dpl;
+
+ /*
+ * Again we make the assumption that the descriptor is
+ * implicitly part of an idt, which we infer as
+ * xen_idt_vaddr. (See above).
+ */
+ xen_idd->vector = xen_idd - (idt_descriptor_t *)xen_idt_vaddr;
+
+ /* Back to read-only, as it should be. */
+ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ);
+ //kpreempt_enable();
+}
+void
+unset_idtgate(idt_descriptor_t *xen_idd)
+{
+ 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);
+
+ /* Zero it */
+ memset(xen_idd, 0, sizeof (*xen_idd));
+
+ /* Back to read-only, as it should be. */
+ pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ);
+}
+#else
+void
+set_idtgate(idt_descriptor_t *idd, void *function, int ist, int type, int dpl, int sel)
+{
+ setgate(idd, function, ist, type, dpl, sel);
+}
+void
+unset_idtgate(idt_descriptor_t *idd)
+{
+ unsetgate(idd);
+}
+#endif
+
/*
* Allocate an IDT vector slot within the given range.
* cpu_lock will be held unless single threaded during early boot.
@@ -123,10 +192,8 @@ idt_vec_set(int vec, void (*function)(vo
{
KASSERT(idt_allocmap[vec] == 1);
-#if !defined(XEN)
- setgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
-#endif
+ set_idtgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL,
+ GSEL(GCODE_SEL, SEL_KPL));
}
/*
@@ -136,9 +203,7 @@ void
idt_vec_free(int vec)
{
-#if !defined(XEN)
- unsetgate(&idt[vec]);
-#endif
+ unset_idtgate(&idt[vec]);
idt_allocmap[vec] = 0;
}
Index: src/sys/arch/x86/x86/lapic.c
diff -u src/sys/arch/x86/x86/lapic.c:1.66 src/sys/arch/x86/x86/lapic.c:1.67
--- src/sys/arch/x86/x86/lapic.c:1.66 Tue Apr 3 07:20:52 2018
+++ src/sys/arch/x86/x86/lapic.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: lapic.c,v 1.66 2018/04/03 07:20:52 christos Exp $ */
+/* $NetBSD: lapic.c,v 1.67 2018/09/23 00:59:59 cherry Exp $ */
/*-
* Copyright (c) 2000, 2008 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.66 2018/04/03 07:20:52 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.67 2018/09/23 00:59:59 cherry Exp $");
#include "acpica.h"
#include "ioapic.h"
@@ -335,7 +335,7 @@ lapic_setup_bsp(paddr_t lapic_base)
#endif
#if defined(DDB) && defined(MULTIPROCESSOR)
#ifdef __x86_64__
- setgate(&idt[ddb_vec], &Xintr_x2apic_ddbipi, 1, SDT_SYS386IGT,
+ set_idtgate(&idt[ddb_vec], &Xintr_x2apic_ddbipi, 1, SDT_SYS386IGT,
SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#else
/* Set DDB IPI handler in cpu_set_tss_gates() when cpu0 is attached. */
Index: src/sys/arch/xen/x86/xenfunc.c
diff -u src/sys/arch/xen/x86/xenfunc.c:1.19 src/sys/arch/xen/x86/xenfunc.c:1.20
--- src/sys/arch/xen/x86/xenfunc.c:1.19 Thu Jul 26 15:06:14 2018
+++ src/sys/arch/xen/x86/xenfunc.c Sun Sep 23 00:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: xenfunc.c,v 1.19 2018/07/26 15:06:14 maxv Exp $ */
+/* $NetBSD: xenfunc.c,v 1.20 2018/09/23 00:59:59 cherry Exp $ */
/*
* Copyright (c) 2004 Christian Limpach.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.19 2018/07/26 15:06:14 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.20 2018/09/23 00:59:59 cherry Exp $");
#include <sys/param.h>
@@ -52,6 +52,46 @@ invlpg(vaddr_t addr)
}
void
+lidt(struct region_descriptor *rd)
+{
+ /*
+ * We need to do this because we can't assume kmem_alloc(9)
+ * will be available at the boot stage when this is called.
+ */
+ static char xen_idt_page[PAGE_SIZE] __attribute__((__aligned__ (PAGE_SIZE)));
+
+ struct trap_info *xen_idt = (void * )xen_idt_page;
+ int xen_idt_idx = 0;
+
+ struct trap_info * idd = (void *) rd->rd_base;
+ const int nidt = rd->rd_limit / (sizeof *idd);
+
+ int i;
+
+ /*
+ * Sweep in all initialised entries, consolidate them back to
+ * back in the requestor array.
+ */
+ for (i = 0; i < nidt; i++) {
+ if (idd->address == 0) /* Skip gap */
+ continue;
+
+ /* Copy over entry */
+ xen_idt[xen_idt_idx++] = idd[i];
+ }
+
+ /* page needs to be r/o */
+ pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ);
+
+ /* Hook it up in the hypervisor */
+ if (HYPERVISOR_set_trap_table(xen_idt))
+ panic("HYPERVISOR_set_trap_table() failed");
+
+ /* reset */
+ pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE);
+}
+
+void
lldt(u_short sel)
{
#ifndef __x86_64__