Module Name:    src
Committed By:   maxv
Date:           Thu Jan 18 07:25:34 UTC 2018

Modified Files:
        src/sys/arch/amd64/amd64: amd64_trap.S genassym.cf locore.S machdep.c
        src/sys/arch/amd64/include: frameasm.h
        src/sys/arch/x86/include: cpu.h pmap.h
        src/sys/arch/x86/x86: vm_machdep.c

Log Message:
Unmap the kernel heap from the user page tables (SVS).

This implementation is optimized and organized in such a way that we
don't need to copy the kernel stack to a safe place during user<->kernel
transitions. We create two VAs that point to the same physical page; one
will be mapped in userland and is offset in order to contain only the
trapframe, the other is mapped in the kernel and maps the entire stack.

Sent on tech-kern@ a week ago.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/amd64/amd64/amd64_trap.S
cvs rdiff -u -r1.66 -r1.67 src/sys/arch/amd64/amd64/genassym.cf
cvs rdiff -u -r1.146 -r1.147 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.290 -r1.291 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/amd64/include/frameasm.h
cvs rdiff -u -r1.88 -r1.89 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.74 -r1.75 src/sys/arch/x86/include/pmap.h
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/x86/x86/vm_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/amd64_trap.S
diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.17 src/sys/arch/amd64/amd64/amd64_trap.S:1.18
--- src/sys/arch/amd64/amd64/amd64_trap.S:1.17	Sun Jan  7 16:10:16 2018
+++ src/sys/arch/amd64/amd64/amd64_trap.S	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: amd64_trap.S,v 1.17 2018/01/07 16:10:16 maxv Exp $	*/
+/*	$NetBSD: amd64_trap.S,v 1.18 2018/01/18 07:25:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
 
 #if 0
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.17 2018/01/07 16:10:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.18 2018/01/18 07:25:34 maxv Exp $");
 #endif
 
 /*
@@ -120,8 +120,8 @@ IDTVEC(trap02)
 #else
 	ZTRAP_NJ(T_NMI)
 	subq	$TF_REGSIZE,%rsp
-	SVS_ENTER
 	INTR_SAVE_GPRS
+	SVS_ENTER_ALTSTACK
 	cld
 	SMAP_ENABLE
 	movw	%gs,TF_GS(%rsp)
@@ -138,7 +138,7 @@ IDTVEC(trap02)
 	movq	%rsp,%rdi
 	incq	CPUVAR(NTRAP)
 	call	_C_LABEL(nmitrap)
-	SVS_LEAVE
+	SVS_LEAVE_ALTSTACK
 	swapgs
 	jmp	.Lnmileave
 

Index: src/sys/arch/amd64/amd64/genassym.cf
diff -u src/sys/arch/amd64/amd64/genassym.cf:1.66 src/sys/arch/amd64/amd64/genassym.cf:1.67
--- src/sys/arch/amd64/amd64/genassym.cf:1.66	Sun Jan  7 16:47:22 2018
+++ src/sys/arch/amd64/amd64/genassym.cf	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.66 2018/01/07 16:47:22 christos Exp $
+#	$NetBSD: genassym.cf,v 1.67 2018/01/18 07:25:34 maxv Exp $
 
 #
 # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -239,6 +239,9 @@ define	CPU_INFO_TSS		offsetof(struct cpu
 ifdef SVS
 define	CPU_INFO_UPDIRPA	offsetof(struct cpu_info, ci_svs_updirpa)
 define	CPU_INFO_KPDIRPA	offsetof(struct cpu_info, ci_svs_kpdirpa)
+define	CPU_INFO_RSP0		offsetof(struct cpu_info, ci_svs_rsp0)
+define	CPU_INFO_URSP0		offsetof(struct cpu_info, ci_svs_ursp0)
+define	CPU_INFO_KRSP0		offsetof(struct cpu_info, ci_svs_krsp0)
 endif
 define	CPU_INFO_NSYSCALL	offsetof(struct cpu_info, ci_data.cpu_nsyscall)
 define	CPU_INFO_NTRAP		offsetof(struct cpu_info, ci_data.cpu_ntrap)

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.146 src/sys/arch/amd64/amd64/locore.S:1.147
--- src/sys/arch/amd64/amd64/locore.S:1.146	Thu Jan 11 09:00:04 2018
+++ src/sys/arch/amd64/amd64/locore.S	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.146 2018/01/11 09:00:04 maxv Exp $	*/
+/*	$NetBSD: locore.S,v 1.147 2018/01/18 07:25:34 maxv Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -1112,7 +1112,11 @@ ENTRY(cpu_switchto)
 	jnz	.Lswitch_return
 
 	/* Switch ring0 stack */
-#ifndef XEN
+#ifdef SVS
+	movq	CPUVAR(RSP0),%rax
+	movq	CPUVAR(TSS),%rdi
+	movq	%rax,TSS_RSP0(%rdi)
+#elif !defined(XEN)
 	movq	PCB_RSP0(%r14),%rax
 	movq	CPUVAR(TSS),%rdi
 	movq	%rax,TSS_RSP0(%rdi)
@@ -1268,14 +1272,20 @@ IDTVEC(syscall)
 	 * is ignored as well.
 	 */
 	swapgs
-	SVS_ENTER_NOSTACK
+
+#ifdef SVS
+	movq	%rax,SVS_UTLS+UTLS_SCRATCH
+	movq	SVS_UTLS+UTLS_RSP0,%rax
+#define SP(x)	(x)-(TF_SS+8)(%rax)
+#else
 	movq	%r15,CPUVAR(SCRATCH)
 	movq	CPUVAR(CURLWP),%r15
 	movq	L_PCB(%r15),%r15
 	movq	PCB_RSP0(%r15),%r15	/* LWP's kernel stack pointer */
+#define SP(x)	(x)-(TF_SS+8)(%r15)
+#endif
 
 	/* 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 %rsp */
 	movq	%r11,SP(TF_RFLAGS)			/* user %rflags */
@@ -1283,8 +1293,11 @@ IDTVEC(syscall)
 	movq	%rcx,SP(TF_RIP)				/* user %rip */
 
 	leaq	SP(0),%rsp		/* %rsp now valid after frame */
+#ifdef SVS
+	movq	SVS_UTLS+UTLS_SCRATCH,%rax
+#else
 	movq	CPUVAR(SCRATCH),%r15
-#undef SP
+#endif
 
 	movq	$2,TF_ERR(%rsp)		/* syscall instruction size */
 	movq	$T_ASTFLT,TF_TRAPNO(%rsp)
@@ -1301,6 +1314,7 @@ IDTVEC(syscall)
 	movw	$GSEL(GUDATA_SEL, SEL_UPL),TF_ES(%rsp)
 	movw	$0,TF_FS(%rsp)
 	movw	$0,TF_GS(%rsp)
+	SVS_ENTER
 	STI(si)
 
 .Ldo_syscall:
@@ -1339,8 +1353,8 @@ IDTVEC(syscall)
 	testl	$(MDL_IRET|MDL_COMPAT32),L_MD_FLAGS(%r14)
 	jnz	intrfastexit
 
-	INTR_RESTORE_GPRS
 	SVS_LEAVE
+	INTR_RESTORE_GPRS
 	SWAPGS
 #ifndef XEN
 	movq	TF_RIP(%rsp),%rcx	/* %rip for sysret */
@@ -1483,6 +1497,8 @@ ENTRY(pagezero)
 END(pagezero)
 
 ENTRY(intrfastexit)
+	NOT_XEN(cli;)
+	SVS_LEAVE
 	INTR_RESTORE_GPRS
 	testw	$SEL_UPL,TF_CS(%rsp)	/* interrupted %cs */
 	jz	.Lkexit
@@ -1513,7 +1529,6 @@ do_mov_gs:
 
 .Luexit64:
 	NOT_XEN(cli;)
-	SVS_LEAVE
 	SWAPGS
 
 .Lkexit:

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.290 src/sys/arch/amd64/amd64/machdep.c:1.291
--- src/sys/arch/amd64/amd64/machdep.c:1.290	Fri Jan 12 09:12:01 2018
+++ src/sys/arch/amd64/amd64/machdep.c	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.290 2018/01/12 09:12:01 maxv Exp $	*/
+/*	$NetBSD: machdep.c,v 1.291 2018/01/18 07:25:34 maxv 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.290 2018/01/12 09:12:01 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.291 2018/01/18 07:25:34 maxv Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -2265,10 +2265,16 @@ mm_md_direct_mapped_phys(paddr_t paddr, 
  *     PTE Space         [OK]
  *     Direct Map        [OK]
  *     Remote PCPU Areas [OK]
- *     Kernel Heap       [TODO]
+ *     Kernel Heap       [OK]
  *     Kernel Image      [TODO]
  */
 
+struct svs_utls {
+	paddr_t kpdirpa;
+	uint64_t scratch;
+	vaddr_t rsp0;
+};
+
 static pd_entry_t *
 svs_tree_add(struct cpu_info *ci, vaddr_t va)
 {
@@ -2334,6 +2340,84 @@ svs_page_add(struct cpu_info *ci, vaddr_
 }
 
 static void
+svs_rsp0_init(struct cpu_info *ci)
+{
+	const cpuid_t cid = cpu_index(ci);
+	vaddr_t va, rsp0;
+	pd_entry_t *pd;
+	size_t pidx;
+
+	rsp0 = (vaddr_t)&pcpuarea->ent[cid].rsp0;
+
+	/* The first page is a redzone. */
+	va = rsp0 + PAGE_SIZE;
+
+	/* Create levels L4, L3 and L2. */
+	pd = svs_tree_add(ci, va);
+
+	/* Get the info for L1. */
+	pidx = pl1_i(va % NBPD_L2);
+	if (pmap_valid_entry(pd[pidx])) {
+		panic("%s: rsp0 page already mapped", __func__);
+	}
+
+	ci->ci_svs_rsp0_pte = (pt_entry_t *)&pd[pidx];
+	ci->ci_svs_rsp0 = rsp0 + PAGE_SIZE + sizeof(struct trapframe);
+	ci->ci_svs_ursp0 = ci->ci_svs_rsp0 - sizeof(struct trapframe);
+	ci->ci_svs_krsp0 = 0;
+}
+
+static void
+svs_utls_init(struct cpu_info *ci)
+{
+	const vaddr_t utlsva = (vaddr_t)&pcpuarea->utls;
+	struct svs_utls *utls;
+	struct vm_page *pg;
+	pd_entry_t *pd;
+	size_t pidx;
+	paddr_t pa;
+	vaddr_t va;
+
+	/* Create levels L4, L3 and L2. */
+	pd = svs_tree_add(ci, utlsva);
+
+	/* Allocate L1. */
+	pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
+	if (pg == 0)
+		panic("%s: failed to allocate PA for CPU %d\n", __func__,
+		    cpu_index(ci));
+	pa = VM_PAGE_TO_PHYS(pg);
+
+	/* Enter L1. */
+	if (pmap_valid_entry(L1_BASE[pl1_i(utlsva)])) {
+		panic("%s: local page already mapped", __func__);
+	}
+	pidx = pl1_i(utlsva % NBPD_L2);
+	if (pmap_valid_entry(pd[pidx])) {
+		panic("%s: L1 page already mapped", __func__);
+	}
+	pd[pidx] = PG_V | PG_RW | pmap_pg_nx | pa;
+
+	/*
+	 * Now, allocate a VA in the kernel map, that points to the UTLS
+	 * page.
+	 */
+	va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+	    UVM_KMF_VAONLY|UVM_KMF_NOWAIT);
+	if (va == 0) {
+		panic("%s: unable to allocate VA\n", __func__);
+	}
+	pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0);
+	pmap_update(pmap_kernel());
+
+	ci->ci_svs_utls = va;
+
+	/* Initialize the constant fields of the UTLS page */
+	utls = (struct svs_utls *)ci->ci_svs_utls;
+	utls->rsp0 = ci->ci_svs_rsp0;
+}
+
+static void
 svs_range_add(struct cpu_info *ci, vaddr_t va, size_t size)
 {
 	size_t i, n;
@@ -2377,7 +2461,10 @@ cpu_svs_init(struct cpu_info *ci)
 	svs_page_add(ci, (vaddr_t)&pcpuarea->idt);
 	svs_page_add(ci, (vaddr_t)&pcpuarea->ldt);
 	svs_range_add(ci, (vaddr_t)&pcpuarea->ent[cid],
-	    sizeof(struct pcpu_entry));
+	    offsetof(struct pcpu_entry, rsp0));
+
+	svs_rsp0_init(ci);
+	svs_utls_init(ci);
 }
 
 void
@@ -2412,7 +2499,43 @@ svs_pmap_sync(struct pmap *pmap, int ind
 void
 svs_lwp_switch(struct lwp *oldlwp, struct lwp *newlwp)
 {
-	/* Switch rsp0 */
+	struct cpu_info *ci = curcpu();
+	struct pcb *pcb;
+	pt_entry_t *pte;
+	uintptr_t rsp0;
+	vaddr_t va;
+
+	if (newlwp->l_flag & LW_SYSTEM) {
+		return;
+	}
+
+#ifdef DIAGNOSTIC
+	if (oldlwp != NULL && !(oldlwp->l_flag & LW_SYSTEM)) {
+		pcb = lwp_getpcb(oldlwp);
+		rsp0 = pcb->pcb_rsp0;
+		va = rounddown(rsp0, PAGE_SIZE);
+		KASSERT(ci->ci_svs_krsp0 == rsp0 - sizeof(struct trapframe));
+		pte = ci->ci_svs_rsp0_pte;
+		KASSERT(*pte == L1_BASE[pl1_i(va)]);
+	}
+#endif
+
+	pcb = lwp_getpcb(newlwp);
+	rsp0 = pcb->pcb_rsp0;
+	va = rounddown(rsp0, PAGE_SIZE);
+
+	/* Update the kernel rsp0 in cpu_info */
+	ci->ci_svs_krsp0 = rsp0 - sizeof(struct trapframe);
+	KASSERT((ci->ci_svs_krsp0 % PAGE_SIZE) ==
+	    (ci->ci_svs_ursp0 % PAGE_SIZE));
+
+	/*
+	 * Enter the user rsp0. We don't need to flush the TLB here, it will
+	 * be implicitly flushed when we reload CR3 next time we return to
+	 * userland.
+	 */
+	pte = ci->ci_svs_rsp0_pte;
+	*pte = L1_BASE[pl1_i(va)];
 }
 
 static inline pt_entry_t
@@ -2433,9 +2556,8 @@ svs_pte_atomic_read(struct pmap *pmap, s
 void
 svs_pdir_switch(struct pmap *pmap)
 {
-	extern size_t pmap_direct_pdpe;
-	extern size_t pmap_direct_npdp;
 	struct cpu_info *ci = curcpu();
+	struct svs_utls *utls;
 	pt_entry_t pte;
 	size_t i;
 
@@ -2444,26 +2566,22 @@ svs_pdir_switch(struct pmap *pmap)
 
 	ci->ci_svs_kpdirpa = pmap_pdirpa(pmap, 0);
 
+	/* Update the info in the UTLS page */
+	utls = (struct svs_utls *)ci->ci_svs_utls;
+	utls->kpdirpa = ci->ci_svs_kpdirpa;
+
 	mutex_enter(&ci->ci_svs_mtx);
 
-	for (i = 0; i < 512; i++) {
-		/*
-		 * This is where we decide what to unmap from the user page
-		 * tables.
-		 */
-		if (i == PDIR_SLOT_PCPU) {
-			/* keep the one created at boot time */
-		} else if (pmap_direct_pdpe <= i &&
-		    i < pmap_direct_pdpe + pmap_direct_npdp) {
-			ci->ci_svs_updir[i] = 0;
-		} else if (i == PDIR_SLOT_PTE) {
-			ci->ci_svs_updir[i] = 0;
-		} else {
-			pte = svs_pte_atomic_read(pmap, i);
-			ci->ci_svs_updir[i] = pte;
-		}
+	/* User slots. */
+	for (i = 0; i < 255; i++) {
+		pte = svs_pte_atomic_read(pmap, i);
+		ci->ci_svs_updir[i] = pte;
 	}
 
+	/* Kernel image. */
+	pte = svs_pte_atomic_read(pmap, 511);
+	ci->ci_svs_updir[511] = pte;
+
 	mutex_exit(&ci->ci_svs_mtx);
 }
 #endif

Index: src/sys/arch/amd64/include/frameasm.h
diff -u src/sys/arch/amd64/include/frameasm.h:1.28 src/sys/arch/amd64/include/frameasm.h:1.29
--- src/sys/arch/amd64/include/frameasm.h:1.28	Thu Jan 11 09:00:04 2018
+++ src/sys/arch/amd64/include/frameasm.h	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: frameasm.h,v 1.28 2018/01/11 09:00:04 maxv Exp $	*/
+/*	$NetBSD: frameasm.h,v 1.29 2018/01/18 07:25:34 maxv Exp $	*/
 
 #ifndef _AMD64_MACHINE_FRAMEASM_H
 #define _AMD64_MACHINE_FRAMEASM_H
@@ -97,31 +97,44 @@
 	movq	TF_RAX(%rsp),%rax
 
 #ifdef SVS
+
+/* XXX: put this somewhere else */
+#define SVS_UTLS		0xffffc00000000000 /* PMAP_PCPU_BASE */
+#define UTLS_KPDIRPA		0
+#define UTLS_SCRATCH		8
+#define UTLS_RSP0		16
+
 #define SVS_ENTER \
-	pushq	%rax			; \
-	movq	CPUVAR(KPDIRPA),%rax	; \
-	movq	%rax,%cr3		; \
-	popq	%rax
+	movq	SVS_UTLS+UTLS_KPDIRPA,%rax	; \
+	movq	%rax,%cr3			; \
+	movq	CPUVAR(KRSP0),%rsp
+
 #define SVS_LEAVE \
-	pushq	%rax			; \
-	movq	CPUVAR(UPDIRPA),%rax	; \
-	movq	%rax,%cr3		; \
-	popq	%rax
-#define SVS_ENTER_NOSTACK \
-	movq	%rax,CPUVAR(SCRATCH)	; \
-	movq	CPUVAR(KPDIRPA),%rax	; \
-	movq	%rax,%cr3		; \
-	movq	CPUVAR(SCRATCH),%rax
-#define SVS_LEAVE_NOSTACK \
-	movq	%rax,CPUVAR(SCRATCH)	; \
-	movq	CPUVAR(UPDIRPA),%rax	; \
-	movq	%rax,%cr3		; \
-	movq	CPUVAR(SCRATCH),%rax
+	testb	$SEL_UPL,TF_CS(%rsp)		; \
+	jz	1234f				; \
+	movq	CPUVAR(URSP0),%rsp		; \
+	movq	CPUVAR(UPDIRPA),%rax		; \
+	movq	%rax,%cr3			; \
+1234:
+
+#define SVS_ENTER_ALTSTACK \
+	testb	$SEL_UPL,TF_CS(%rsp)		; \
+	jz	1234f				; \
+	movq	SVS_UTLS+UTLS_KPDIRPA,%rax	; \
+	movq	%rax,%cr3			; \
+1234:
+
+#define SVS_LEAVE_ALTSTACK \
+	testb	$SEL_UPL,TF_CS(%rsp)		; \
+	jz	1234f				; \
+	movq	CPUVAR(UPDIRPA),%rax		; \
+	movq	%rax,%cr3			; \
+1234:
 #else
 #define SVS_ENTER	/* nothing */
 #define SVS_LEAVE	/* nothing */
-#define SVS_ENTER_NOSTACK	/* nothing */
-#define SVS_LEAVE_NOSTACK	/* nothing */
+#define SVS_ENTER_ALTSTACK	/* nothing */
+#define SVS_LEAVE_ALTSTACK	/* nothing */
 #endif
 
 #define	INTRENTRY_L(kernel_trap, usertrap) \

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.88 src/sys/arch/x86/include/cpu.h:1.89
--- src/sys/arch/x86/include/cpu.h:1.88	Sun Jan  7 16:10:16 2018
+++ src/sys/arch/x86/include/cpu.h	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.88 2018/01/07 16:10:16 maxv Exp $	*/
+/*	$NetBSD: cpu.h,v 1.89 2018/01/18 07:25:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -193,6 +193,11 @@ struct cpu_info {
 	paddr_t		ci_svs_updirpa;
 	paddr_t		ci_svs_kpdirpa;
 	kmutex_t	ci_svs_mtx;
+	pd_entry_t *	ci_svs_rsp0_pte;
+	vaddr_t		ci_svs_rsp0;
+	vaddr_t		ci_svs_ursp0;
+	vaddr_t		ci_svs_krsp0;
+	vaddr_t		ci_svs_utls;
 #endif
 
 #if defined(XEN) && (defined(PAE) || defined(__x86_64__))

Index: src/sys/arch/x86/include/pmap.h
diff -u src/sys/arch/x86/include/pmap.h:1.74 src/sys/arch/x86/include/pmap.h:1.75
--- src/sys/arch/x86/include/pmap.h:1.74	Thu Jan 11 10:38:13 2018
+++ src/sys/arch/x86/include/pmap.h	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.74 2018/01/11 10:38:13 maxv Exp $	*/
+/*	$NetBSD: pmap.h,v 1.75 2018/01/18 07:25:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -163,9 +163,13 @@ struct pcpu_entry {
 	uint8_t ist0[PAGE_SIZE];
 	uint8_t ist1[PAGE_SIZE];
 	uint8_t ist2[PAGE_SIZE];
+	uint8_t rsp0[2 * PAGE_SIZE];
 } __packed;
 
 struct pcpu_area {
+#ifdef SVS
+	uint8_t utls[PAGE_SIZE];
+#endif
 	uint8_t idt[PAGE_SIZE];
 	uint8_t ldt[PAGE_SIZE];
 	struct pcpu_entry ent[MAXCPUS];

Index: src/sys/arch/x86/x86/vm_machdep.c
diff -u src/sys/arch/x86/x86/vm_machdep.c:1.31 src/sys/arch/x86/x86/vm_machdep.c:1.32
--- src/sys/arch/x86/x86/vm_machdep.c:1.31	Thu Jan 11 11:15:34 2018
+++ src/sys/arch/x86/x86/vm_machdep.c	Thu Jan 18 07:25:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.31 2018/01/11 11:15:34 maxv Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.32 2018/01/18 07:25:34 maxv Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986 The Regents of the University of California.
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.31 2018/01/11 11:15:34 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.32 2018/01/18 07:25:34 maxv Exp $");
 
 #include "opt_mtrr.h"
 
@@ -181,7 +181,13 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 	KASSERT(uv % PAGE_SIZE == 0);
 
 #ifdef __x86_64__
+#ifdef SVS
+	pcb2->pcb_rsp0 = (uv + USPACE - PAGE_SIZE +
+	    sizeof(struct trapframe));
+	KASSERT((pcb2->pcb_rsp0 & 0xF) == 0);
+#else
 	pcb2->pcb_rsp0 = (uv + USPACE - 16);
+#endif
 	tf = (struct trapframe *)pcb2->pcb_rsp0 - 1;
 #else
 	pcb2->pcb_esp0 = (uv + USPACE - 16);

Reply via email to