summaryrefslogtreecommitdiff
path: root/lib/libnvmm
diff options
context:
space:
mode:
authormaxv <maxv@NetBSD.org>2019-05-11 07:31:56 +0000
committermaxv <maxv@NetBSD.org>2019-05-11 07:31:56 +0000
commit94cb33e2cf5452fce4540089ff62353767d8fc54 (patch)
tree86e33af7d758812ec93fe3217f775a4f22f5e20c /lib/libnvmm
parent2a689df7e163cb590df71d0c2225a2a734e42116 (diff)
Rework the machine configuration interface.
Provide three ranges in the conf space: <libnvmm:0-100>, <MI:100-200> and <MD:200-...>. Remove nvmm_callbacks_register(), and replace it by the conf op NVMM_MACH_CONF_CALLBACKS, handled by libnvmm. The callbacks are now per-machine, and the emulators should now do: - nvmm_callbacks_register(&cbs); + nvmm_machine_configure(&mach, NVMM_MACH_CONF_CALLBACKS, &cbs); This provides more granularity, for example if the process runs two VMs and wants different callbacks for each.
Diffstat (limited to 'lib/libnvmm')
-rw-r--r--lib/libnvmm/libnvmm.c15
-rw-r--r--lib/libnvmm/libnvmm_x86.c82
-rw-r--r--lib/libnvmm/nvmm.h20
3 files changed, 59 insertions, 58 deletions
diff --git a/lib/libnvmm/libnvmm.c b/lib/libnvmm/libnvmm.c
index 110a827fd82..5b47bed70fa 100644
--- a/lib/libnvmm/libnvmm.c
+++ b/lib/libnvmm/libnvmm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: libnvmm.c,v 1.12 2019/05/01 09:20:21 maxv Exp $ */
+/* $NetBSD: libnvmm.c,v 1.13 2019/05/11 07:31:57 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -44,7 +44,6 @@
#include "nvmm.h"
-static struct nvmm_callbacks __callbacks;
static struct nvmm_capability __capability;
#ifdef __x86_64__
@@ -255,6 +254,12 @@ nvmm_machine_configure(struct nvmm_machine *mach, uint64_t op, void *conf)
struct nvmm_ioc_machine_configure args;
int ret;
+ switch (op) {
+ case NVMM_MACH_CONF_CALLBACKS:
+ memcpy(&mach->cbs, conf, sizeof(mach->cbs));
+ return 0;
+ }
+
args.machid = mach->machid;
args.op = op;
args.conf = conf;
@@ -510,12 +515,6 @@ nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva,
* nvmm_assist_mem(): architecture-specific.
*/
-void
-nvmm_callbacks_register(const struct nvmm_callbacks *cbs)
-{
- memcpy(&__callbacks, cbs, sizeof(__callbacks));
-}
-
int
nvmm_ctl(int op, void *data, size_t size)
{
diff --git a/lib/libnvmm/libnvmm_x86.c b/lib/libnvmm/libnvmm_x86.c
index 34f21929b3c..63e860ebabb 100644
--- a/lib/libnvmm/libnvmm_x86.c
+++ b/lib/libnvmm/libnvmm_x86.c
@@ -1,4 +1,4 @@
-/* $NetBSD: libnvmm_x86.c,v 1.29 2019/04/28 14:22:13 maxv Exp $ */
+/* $NetBSD: libnvmm_x86.c,v 1.30 2019/05/11 07:31:57 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -606,7 +606,7 @@ read_guest_memory(struct nvmm_machine *mach, struct nvmm_x64_state *state,
mem.gpa = gpa;
mem.write = false;
mem.size = size;
- (*__callbacks.mem)(&mem);
+ (*mach->cbs.mem)(&mem);
} else {
if (__predict_false(!(prot & NVMM_PROT_READ))) {
errno = EFAULT;
@@ -660,7 +660,7 @@ write_guest_memory(struct nvmm_machine *mach, struct nvmm_x64_state *state,
mem.gpa = gpa;
mem.write = true;
mem.size = size;
- (*__callbacks.mem)(&mem);
+ (*mach->cbs.mem)(&mem);
} else {
if (__predict_false(!(prot & NVMM_PROT_WRITE))) {
errno = EFAULT;
@@ -706,7 +706,7 @@ assist_io_batch(struct nvmm_machine *mach, struct nvmm_x64_state *state,
}
for (i = 0; i < iocnt; i++) {
- (*__callbacks.io)(io);
+ (*mach->cbs.io)(io);
io->data += io->size;
}
@@ -816,7 +816,7 @@ nvmm_assist_io(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
}
}
- (*__callbacks.io)(&io);
+ (*mach->cbs.io)(&io);
if (io.in) {
if (!exit->u.io.str) {
@@ -865,19 +865,19 @@ out:
struct x86_emul {
bool read;
bool notouch;
- void (*func)(struct nvmm_mem *, uint64_t *);
+ void (*func)(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
};
-static void x86_func_or(struct nvmm_mem *, uint64_t *);
-static void x86_func_and(struct nvmm_mem *, uint64_t *);
-static void x86_func_sub(struct nvmm_mem *, uint64_t *);
-static void x86_func_xor(struct nvmm_mem *, uint64_t *);
-static void x86_func_cmp(struct nvmm_mem *, uint64_t *);
-static void x86_func_test(struct nvmm_mem *, uint64_t *);
-static void x86_func_mov(struct nvmm_mem *, uint64_t *);
-static void x86_func_stos(struct nvmm_mem *, uint64_t *);
-static void x86_func_lods(struct nvmm_mem *, uint64_t *);
-static void x86_func_movs(struct nvmm_mem *, uint64_t *);
+static void x86_func_or(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_and(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_sub(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_xor(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_cmp(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_test(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_mov(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_stos(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_lods(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
+static void x86_func_movs(struct nvmm_machine *, struct nvmm_mem *, uint64_t *);
static const struct x86_emul x86_emul_or = {
.read = true,
@@ -2631,7 +2631,7 @@ EXEC_DISPATCHER(xor)
*/
static void
-x86_func_or(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_or(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *retval = (uint64_t *)mem->data;
const bool write = mem->write;
@@ -2643,7 +2643,7 @@ x86_func_or(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be OR'ed (op2). */
mem->data = (uint8_t *)&op2;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the OR. */
ret = exec_or(*op1, op2, &fl, mem->size);
@@ -2652,7 +2652,7 @@ x86_func_or(struct nvmm_mem *mem, uint64_t *gprs)
/* Write back the result. */
mem->data = (uint8_t *)&ret;
mem->write = true;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
} else {
/* Return data to the caller. */
*retval = ret;
@@ -2663,7 +2663,7 @@ x86_func_or(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_and(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_and(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *retval = (uint64_t *)mem->data;
const bool write = mem->write;
@@ -2675,7 +2675,7 @@ x86_func_and(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be AND'ed (op2). */
mem->data = (uint8_t *)&op2;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the AND. */
ret = exec_and(*op1, op2, &fl, mem->size);
@@ -2684,7 +2684,7 @@ x86_func_and(struct nvmm_mem *mem, uint64_t *gprs)
/* Write back the result. */
mem->data = (uint8_t *)&ret;
mem->write = true;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
} else {
/* Return data to the caller. */
*retval = ret;
@@ -2695,7 +2695,7 @@ x86_func_and(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_sub(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_sub(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *retval = (uint64_t *)mem->data;
const bool write = mem->write;
@@ -2710,7 +2710,7 @@ x86_func_sub(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be SUB'ed (op1 or op2). */
mem->data = (uint8_t *)&tmp;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the SUB. */
ret = exec_sub(*op1, *op2, &fl, mem->size);
@@ -2719,7 +2719,7 @@ x86_func_sub(struct nvmm_mem *mem, uint64_t *gprs)
/* Write back the result. */
mem->data = (uint8_t *)&ret;
mem->write = true;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
} else {
/* Return data to the caller. */
*retval = ret;
@@ -2730,7 +2730,7 @@ x86_func_sub(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_xor(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_xor(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *retval = (uint64_t *)mem->data;
const bool write = mem->write;
@@ -2742,7 +2742,7 @@ x86_func_xor(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be XOR'ed (op2). */
mem->data = (uint8_t *)&op2;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the XOR. */
ret = exec_xor(*op1, op2, &fl, mem->size);
@@ -2751,7 +2751,7 @@ x86_func_xor(struct nvmm_mem *mem, uint64_t *gprs)
/* Write back the result. */
mem->data = (uint8_t *)&ret;
mem->write = true;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
} else {
/* Return data to the caller. */
*retval = ret;
@@ -2762,7 +2762,7 @@ x86_func_xor(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_cmp(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_cmp(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *op1, *op2, fl;
uint64_t tmp;
@@ -2775,7 +2775,7 @@ x86_func_cmp(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be CMP'ed (op1 or op2). */
mem->data = (uint8_t *)&tmp;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the CMP. */
exec_sub(*op1, *op2, &fl, mem->size);
@@ -2785,7 +2785,7 @@ x86_func_cmp(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_test(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_test(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
uint64_t *op1, *op2, fl;
uint64_t tmp;
@@ -2798,7 +2798,7 @@ x86_func_test(struct nvmm_mem *mem, uint64_t *gprs)
/* Fetch the value to be TEST'ed (op1 or op2). */
mem->data = (uint8_t *)&tmp;
mem->write = false;
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
/* Perform the TEST. */
exec_and(*op1, *op2, &fl, mem->size);
@@ -2808,21 +2808,21 @@ x86_func_test(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_mov(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_mov(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
/*
* Nothing special, just move without emulation.
*/
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
}
static void
-x86_func_stos(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_stos(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
/*
* Just move, and update RDI.
*/
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
if (gprs[NVMM_X64_GPR_RFLAGS] & PSL_D) {
gprs[NVMM_X64_GPR_RDI] -= mem->size;
@@ -2832,12 +2832,12 @@ x86_func_stos(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_lods(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_lods(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
/*
* Just move, and update RSI.
*/
- (*__callbacks.mem)(mem);
+ (*mach->cbs.mem)(mem);
if (gprs[NVMM_X64_GPR_RFLAGS] & PSL_D) {
gprs[NVMM_X64_GPR_RSI] -= mem->size;
@@ -2847,7 +2847,7 @@ x86_func_lods(struct nvmm_mem *mem, uint64_t *gprs)
}
static void
-x86_func_movs(struct nvmm_mem *mem, uint64_t *gprs)
+x86_func_movs(struct nvmm_machine *mach, struct nvmm_mem *mem, uint64_t *gprs)
{
/*
* Special instruction: double memory operand. Don't call the cb,
@@ -3047,7 +3047,7 @@ assist_mem_double(struct nvmm_machine *mach, struct nvmm_x64_state *state,
return -1;
mem.size = size;
- (*instr->emul->func)(&mem, state->gprs);
+ (*instr->emul->func)(mach, &mem, state->gprs);
return 0;
}
@@ -3124,7 +3124,7 @@ assist_mem_single(struct nvmm_machine *mach, struct nvmm_x64_state *state,
memcpy(mem.data, &val, mem.size);
}
- (*instr->emul->func)(&mem, state->gprs);
+ (*instr->emul->func)(mach, &mem, state->gprs);
if (!instr->emul->notouch && !mem.write) {
if (instr->dst.type != STORE_REG) {
diff --git a/lib/libnvmm/nvmm.h b/lib/libnvmm/nvmm.h
index e2e75ff8c81..cfd4be712a7 100644
--- a/lib/libnvmm/nvmm.h
+++ b/lib/libnvmm/nvmm.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm.h,v 1.10 2019/04/28 14:22:13 maxv Exp $ */
+/* $NetBSD: nvmm.h,v 1.11 2019/05/11 07:31:57 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -38,13 +38,6 @@
#include <dev/nvmm/nvmm.h>
#include <dev/nvmm/nvmm_ioctl.h>
-struct nvmm_machine {
- nvmm_machid_t machid;
- struct nvmm_comm_page **pages;
- size_t npages;
- void *areas; /* opaque */
-};
-
struct nvmm_io {
uint64_t port;
bool in;
@@ -64,6 +57,16 @@ struct nvmm_callbacks {
void (*mem)(struct nvmm_mem *);
};
+struct nvmm_machine {
+ nvmm_machid_t machid;
+ struct nvmm_comm_page **pages;
+ size_t npages;
+ void *areas; /* opaque */
+ struct nvmm_callbacks cbs;
+};
+
+#define NVMM_MACH_CONF_CALLBACKS NVMM_MACH_CONF_LIBNVMM_BEGIN
+
#define NVMM_PROT_READ 0x01
#define NVMM_PROT_WRITE 0x02
#define NVMM_PROT_EXEC 0x04
@@ -96,7 +99,6 @@ int nvmm_gpa_to_hva(struct nvmm_machine *, gpaddr_t, uintptr_t *,
int nvmm_assist_io(struct nvmm_machine *, nvmm_cpuid_t, struct nvmm_exit *);
int nvmm_assist_mem(struct nvmm_machine *, nvmm_cpuid_t, struct nvmm_exit *);
-void nvmm_callbacks_register(const struct nvmm_callbacks *);
int nvmm_ctl(int, void *, size_t);