/* $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.
#include <machine/vmmvar.h>
#include <machine/biosvar.h>
#include <machine/segments.h>
+#include <machine/specialreg.h>
#include <machine/pte.h>
#include "loadfile.h"
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);
}
/*
- * 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));
/* 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);
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];
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);
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);
-/* $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>
/*
* 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
* 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,
.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,
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,