summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bhyve/mem.c')
-rw-r--r--usr.sbin/bhyve/mem.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/usr.sbin/bhyve/mem.c b/usr.sbin/bhyve/mem.c
index 27f4782..c2b5ab4 100644
--- a/usr.sbin/bhyve/mem.c
+++ b/usr.sbin/bhyve/mem.c
@@ -62,7 +62,7 @@ struct mmio_rb_range {
struct mmio_rb_tree;
RB_PROTOTYPE(mmio_rb_tree, mmio_rb_range, mr_link, mmio_rb_range_compare);
-RB_HEAD(mmio_rb_tree, mmio_rb_range) mmio_rbroot;
+RB_HEAD(mmio_rb_tree, mmio_rb_range) mmio_rb_root, mmio_rb_fallback;
/*
* Per-vCPU cache. Since most accesses from a vCPU will be to
@@ -82,13 +82,14 @@ mmio_rb_range_compare(struct mmio_rb_range *a, struct mmio_rb_range *b)
}
static int
-mmio_rb_lookup(uint64_t addr, struct mmio_rb_range **entry)
+mmio_rb_lookup(struct mmio_rb_tree *rbt, uint64_t addr,
+ struct mmio_rb_range **entry)
{
struct mmio_rb_range find, *res;
find.mr_base = find.mr_end = addr;
- res = RB_FIND(mmio_rb_tree, &mmio_rbroot, &find);
+ res = RB_FIND(mmio_rb_tree, rbt, &find);
if (res != NULL) {
*entry = res;
@@ -99,11 +100,11 @@ mmio_rb_lookup(uint64_t addr, struct mmio_rb_range **entry)
}
static int
-mmio_rb_add(struct mmio_rb_range *new)
+mmio_rb_add(struct mmio_rb_tree *rbt, struct mmio_rb_range *new)
{
struct mmio_rb_range *overlap;
- overlap = RB_INSERT(mmio_rb_tree, &mmio_rbroot, new);
+ overlap = RB_INSERT(mmio_rb_tree, rbt, new);
if (overlap != NULL) {
#ifdef RB_DEBUG
@@ -120,11 +121,11 @@ mmio_rb_add(struct mmio_rb_range *new)
#if 0
static void
-mmio_rb_dump(void)
+mmio_rb_dump(struct mmio_rb_tree *rbt)
{
struct mmio_rb_range *np;
- RB_FOREACH(np, mmio_rb_tree, &mmio_rbroot) {
+ RB_FOREACH(np, mmio_rb_tree, rbt) {
printf(" %lx:%lx, %s\n", np->mr_base, np->mr_end,
np->mr_param.name);
}
@@ -172,22 +173,22 @@ emulate_mem(struct vmctx *ctx, int vcpu, uint64_t paddr, struct vie *vie)
entry = NULL;
if (entry == NULL) {
- if (mmio_rb_lookup(paddr, &entry))
+ if (!mmio_rb_lookup(&mmio_rb_root, paddr, &entry)) {
+ /* Update the per-vCPU cache */
+ mmio_hint[vcpu] = entry;
+ } else if (mmio_rb_lookup(&mmio_rb_fallback, paddr, &entry)) {
return (ESRCH);
-
- /* Update the per-vCPU cache */
- mmio_hint[vcpu] = entry;
+ }
}
- assert(entry != NULL && entry == mmio_hint[vcpu]);
-
+ assert(entry != NULL);
err = vmm_emulate_instruction(ctx, vcpu, paddr, vie,
mem_read, mem_write, &entry->mr_param);
return (err);
}
-int
-register_mem(struct mem_range *memp)
+static int
+register_mem_int(struct mmio_rb_tree *rbt, struct mem_range *memp)
{
struct mmio_rb_range *mrp;
int err;
@@ -201,7 +202,7 @@ register_mem(struct mem_range *memp)
mrp->mr_base = memp->base;
mrp->mr_end = memp->base + memp->size - 1;
- err = mmio_rb_add(mrp);
+ err = mmio_rb_add(rbt, mrp);
if (err)
free(mrp);
} else
@@ -210,9 +211,24 @@ register_mem(struct mem_range *memp)
return (err);
}
+int
+register_mem(struct mem_range *memp)
+{
+
+ return (register_mem_int(&mmio_rb_root, memp));
+}
+
+int
+register_mem_fallback(struct mem_range *memp)
+{
+
+ return (register_mem_int(&mmio_rb_fallback, memp));
+}
+
void
init_mem(void)
{
- RB_INIT(&mmio_rbroot);
+ RB_INIT(&mmio_rb_root);
+ RB_INIT(&mmio_rb_fallback);
}
OpenPOWER on IntegriCloud