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);