summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMike Larkin <mlarkin@cvs.openbsd.org>2018-07-17 13:47:07 +0000
committerMike Larkin <mlarkin@cvs.openbsd.org>2018-07-17 13:47:07 +0000
commit860b7a9355dc4a16133e64f2047736ec442dd9cc (patch)
treee33a8d117faf4a5d7f8c7ffe013c0c3a34469bab /usr.sbin
parent7986f0bd1c619376c0caa35f2fa51062ddafc837 (diff)
vmd(8): fix vmctl -b option for i386 kernels.
ok pd@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/vmd/loadfile_elf.c50
-rw-r--r--usr.sbin/vmd/vm.c12
2 files changed, 47 insertions, 15 deletions
diff --git a/usr.sbin/vmd/loadfile_elf.c b/usr.sbin/vmd/loadfile_elf.c
index 586e4915a32..295852ef82c 100644
--- a/usr.sbin/vmd/loadfile_elf.c
+++ b/usr.sbin/vmd/loadfile_elf.c
@@ -1,5 +1,5 @@
/* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */
-/* $OpenBSD: loadfile_elf.c,v 1.29 2017/11/29 02:46:10 mlarkin Exp $ */
+/* $OpenBSD: loadfile_elf.c,v 1.30 2018/07/17 13:47:06 mlarkin Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -100,6 +100,7 @@
#include <machine/vmmvar.h>
#include <machine/biosvar.h>
#include <machine/segments.h>
+#include <machine/specialreg.h>
#include <machine/pte.h>
#include "loadfile.h"
@@ -124,7 +125,8 @@ static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *);
static uint32_t push_bootargs(bios_memmap_t *, size_t);
static size_t push_stack(uint32_t, uint32_t, uint32_t, uint32_t);
static void push_gdt(void);
-static void push_pt(void);
+static void push_pt_32(void);
+static void push_pt_64(void);
static void marc4random_buf(paddr_t, int);
static void mbzero(paddr_t, int);
static void mbcopy(void *, paddr_t, int);
@@ -217,16 +219,35 @@ push_gdt(void)
}
/*
- * push_pt
+ * push_pt_32
*
* Create an identity-mapped page directory hierarchy mapping the first
- * 1GB of physical memory. This is used during bootstrapping VMs on
+ * 4GB of physical memory. This is used during bootstrapping i386 VMs on
* CPUs without unrestricted guest capability.
*/
static void
-push_pt(void)
+push_pt_32(void)
{
- uint64_t ptes[NPTE_PG], i;
+ uint32_t ptes[1024], i;
+
+ memset(ptes, 0, sizeof(ptes));
+ for (i = 0 ; i < 1024; i++) {
+ ptes[i] = PG_V | PG_RW | PG_u | PG_PS | ((4096 * 1024) * i);
+ }
+ write_mem(PML3_PAGE, ptes, PAGE_SIZE);
+}
+
+/*
+ * push_pt_64
+ *
+ * Create an identity-mapped page directory hierarchy mapping the first
+ * 1GB of physical memory. This is used during bootstrapping 64 bit VMs on
+ * CPUs without unrestricted guest capability.
+ */
+static void
+push_pt_64(void)
+{
+ uint64_t ptes[512], i;
/* PDPDE0 - first 1GB */
memset(ptes, 0, sizeof(ptes));
@@ -240,7 +261,7 @@ push_pt(void)
/* First 1GB (in 2MB pages) */
memset(ptes, 0, sizeof(ptes));
- for (i = 0 ; i < NPTE_PG; i++) {
+ for (i = 0 ; i < 512; i++) {
ptes[i] = PG_V | PG_RW | PG_u | PG_PS | ((2048 * 1024) * i);
}
write_mem(PML2_PAGE, ptes, PAGE_SIZE);
@@ -267,7 +288,7 @@ int
loadfile_elf(FILE *fp, struct vm_create_params *vcp,
struct vcpu_reg_state *vrs, uint32_t bootdev, uint32_t howto)
{
- int r;
+ int r, is_i386 = 0;
uint32_t bootargsz;
size_t n, stacksize;
u_long marks[MARK_MAX];
@@ -280,6 +301,7 @@ loadfile_elf(FILE *fp, struct vm_create_params *vcp,
if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
r = elf32_exec(fp, &hdr.elf32, marks, LOAD_ALL);
+ is_i386 = 1;
} else if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
r = elf64_exec(fp, &hdr.elf64, marks, LOAD_ALL);
@@ -290,7 +312,17 @@ loadfile_elf(FILE *fp, struct vm_create_params *vcp,
return (r);
push_gdt();
- push_pt();
+
+ if (is_i386) {
+ push_pt_32();
+ /* Reconfigure the default flat-64 register set for 32 bit */
+ vrs->vrs_crs[VCPU_REGS_CR3] = PML3_PAGE;
+ vrs->vrs_crs[VCPU_REGS_CR4] = CR4_PSE;
+ vrs->vrs_msrs[VCPU_REGS_EFER] = 0ULL;
+ }
+ else
+ push_pt_64();
+
n = create_bios_memmap(vcp, memmap);
bootargsz = push_bootargs(memmap, n);
stacksize = push_stack(bootargsz, marks[MARK_END], bootdev, howto);
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index 67252e5cf89..046b2be8503 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm.c,v 1.37 2018/07/12 10:15:44 mlarkin Exp $ */
+/* $OpenBSD: vm.c,v 1.38 2018/07/17 13:47:06 mlarkin Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -110,7 +110,7 @@ uint8_t vcpu_done[VMM_MAX_VCPUS_PER_VM];
/*
* Represents a standard register set for an OS to be booted
- * as a flat 32 bit address space, before paging is enabled.
+ * as a flat 64 bit address space.
*
* NOT set here are:
* RIP
@@ -123,7 +123,7 @@ uint8_t vcpu_done[VMM_MAX_VCPUS_PER_VM];
* Note - CR3 and various bits in CR0 may be overridden by vmm(4) based on
* features of the CPU in use.
*/
-static const struct vcpu_reg_state vcpu_init_flat32 = {
+static const struct vcpu_reg_state vcpu_init_flat64 = {
#ifdef __i386__
.vrs_gprs[VCPU_REGS_EFLAGS] = 0x2,
.vrs_gprs[VCPU_REGS_EIP] = 0x0,
@@ -136,7 +136,7 @@ static const struct vcpu_reg_state vcpu_init_flat32 = {
.vrs_crs[VCPU_REGS_CR0] = CR0_CD | CR0_NW | CR0_ET | CR0_PE | CR0_PG,
.vrs_crs[VCPU_REGS_CR3] = PML4_PAGE,
.vrs_crs[VCPU_REGS_CR4] = CR4_PAE | CR4_PSE,
- .vrs_crs[VCPU_REGS_PDPTE0] = PML3_PAGE | PG_V,
+ .vrs_crs[VCPU_REGS_PDPTE0] = 0ULL,
.vrs_crs[VCPU_REGS_PDPTE1] = 0ULL,
.vrs_crs[VCPU_REGS_PDPTE2] = 0ULL,
.vrs_crs[VCPU_REGS_PDPTE3] = 0ULL,
@@ -319,10 +319,10 @@ start_vm(struct vmd_vm *vm, int fd)
vrs = vrp.vrwp_regs;
} else {
/*
- * Set up default "flat 32 bit" register state - RIP,
+ * Set up default "flat 64 bit" register state - RIP,
* RSP, and GDT info will be set in bootloader
*/
- memcpy(&vrs, &vcpu_init_flat32, sizeof(vrs));
+ memcpy(&vrs, &vcpu_init_flat64, sizeof(vrs));
/* Find and open kernel image */
if ((fp = vmboot_open(vm->vm_kernel,