mem.c (241744) | mem.c (243640) |
---|---|
1/*- 2 * Copyright (c) 2012 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2012 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: projects/bhyve/usr.sbin/bhyve/mem.c 241744 2012-10-19 18:11:17Z grehan $ | 26 * $FreeBSD: projects/bhyve/usr.sbin/bhyve/mem.c 243640 2012-11-28 00:02:17Z neel $ |
27 */ 28 29/* 30 * Memory ranges are represented with an RB tree. On insertion, the range 31 * is checked for overlaps. On lookup, the key has the same base and limit 32 * so it can be searched within the range. 33 * 34 * It is assumed that all setup of ranges takes place in single-threaded 35 * mode before vCPUs have been started. As such, no locks are used on the 36 * RB tree. If this is no longer the case, then a r/w lock could be used, 37 * with readers on the lookup and a writer if the tree needs to be changed 38 * (and per vCPU caches flushed) 39 */ 40 41#include <sys/cdefs.h> | 27 */ 28 29/* 30 * Memory ranges are represented with an RB tree. On insertion, the range 31 * is checked for overlaps. On lookup, the key has the same base and limit 32 * so it can be searched within the range. 33 * 34 * It is assumed that all setup of ranges takes place in single-threaded 35 * mode before vCPUs have been started. As such, no locks are used on the 36 * RB tree. If this is no longer the case, then a r/w lock could be used, 37 * with readers on the lookup and a writer if the tree needs to be changed 38 * (and per vCPU caches flushed) 39 */ 40 41#include <sys/cdefs.h> |
42__FBSDID("$FreeBSD: projects/bhyve/usr.sbin/bhyve/mem.c 241744 2012-10-19 18:11:17Z grehan $"); | 42__FBSDID("$FreeBSD: projects/bhyve/usr.sbin/bhyve/mem.c 243640 2012-11-28 00:02:17Z neel $"); |
43 44#include <sys/types.h> 45#include <sys/tree.h> 46#include <sys/errno.h> 47#include <machine/vmm.h> 48 49#include <stdio.h> 50#include <stdlib.h> 51#include <assert.h> 52 53#include "mem.h" | 43 44#include <sys/types.h> 45#include <sys/tree.h> 46#include <sys/errno.h> 47#include <machine/vmm.h> 48 49#include <stdio.h> 50#include <stdlib.h> 51#include <assert.h> 52 53#include "mem.h" |
54#include "instruction_emul.h" | |
55 56struct mmio_rb_range { 57 RB_ENTRY(mmio_rb_range) mr_link; /* RB tree links */ 58 struct mem_range mr_param; 59 uint64_t mr_base; 60 uint64_t mr_end; 61}; 62 --- 66 unchanged lines hidden (view full) --- 129 printf(" %lx:%lx, %s\n", np->mr_base, np->mr_end, 130 np->mr_param.name); 131 } 132} 133#endif 134 135RB_GENERATE(mmio_rb_tree, mmio_rb_range, mr_link, mmio_rb_range_compare); 136 | 54 55struct mmio_rb_range { 56 RB_ENTRY(mmio_rb_range) mr_link; /* RB tree links */ 57 struct mem_range mr_param; 58 uint64_t mr_base; 59 uint64_t mr_end; 60}; 61 --- 66 unchanged lines hidden (view full) --- 128 printf(" %lx:%lx, %s\n", np->mr_base, np->mr_end, 129 np->mr_param.name); 130 } 131} 132#endif 133 134RB_GENERATE(mmio_rb_tree, mmio_rb_range, mr_link, mmio_rb_range_compare); 135 |
136static int 137mem_read(void *ctx, int vcpu, uint64_t gpa, uint64_t *rval, int size, void *arg) 138{ 139 int error; 140 struct mem_range *mr = arg; 141 142 error = (*mr->handler)(ctx, vcpu, MEM_F_READ, gpa, size, 143 rval, mr->arg1, mr->arg2); 144 return (error); 145} 146 147static int 148mem_write(void *ctx, int vcpu, uint64_t gpa, uint64_t wval, int size, void *arg) 149{ 150 int error; 151 struct mem_range *mr = arg; 152 153 error = (*mr->handler)(ctx, vcpu, MEM_F_WRITE, gpa, size, 154 &wval, mr->arg1, mr->arg2); 155 return (error); 156} 157 |
|
137int 138emulate_mem(struct vmctx *ctx, int vcpu, uint64_t paddr, uint64_t rip, | 158int 159emulate_mem(struct vmctx *ctx, int vcpu, uint64_t paddr, uint64_t rip, |
139 uint64_t cr3, int mode) | 160 uint64_t cr3, int mode, struct vie *vie) |
140{ 141 struct mmio_rb_range *entry; 142 int err; 143 | 161{ 162 struct mmio_rb_range *entry; 163 int err; 164 |
144 err = 0; 145 | |
146 /* 147 * First check the per-vCPU cache 148 */ 149 if (mmio_hint[vcpu] && 150 paddr >= mmio_hint[vcpu]->mr_base && 151 paddr <= mmio_hint[vcpu]->mr_end) { | 165 /* 166 * First check the per-vCPU cache 167 */ 168 if (mmio_hint[vcpu] && 169 paddr >= mmio_hint[vcpu]->mr_base && 170 paddr <= mmio_hint[vcpu]->mr_end) { |
152 err = emulate_instruction(ctx, vcpu, rip, cr3, paddr, mode, 153 &mmio_hint[vcpu]->mr_param); 154 } else { 155 if (mmio_rb_lookup(paddr, &entry)) { 156 err = ENOENT; 157 } else { 158 mmio_hint[vcpu] = entry; 159 err = emulate_instruction(ctx, vcpu, rip, cr3, paddr, 160 mode, &entry->mr_param); 161 } | 171 entry = mmio_hint[vcpu]; 172 } else 173 entry = NULL; 174 175 if (entry == NULL) { 176 if (mmio_rb_lookup(paddr, &entry)) 177 return (ESRCH); 178 179 /* Update the per-vCPU cache */ 180 mmio_hint[vcpu] = entry; |
162 } 163 | 181 } 182 |
183 assert(entry != NULL && entry == mmio_hint[vcpu]); 184 185 err = vmm_emulate_instruction(ctx, vcpu, paddr, vie, 186 mem_read, mem_write, &entry->mr_param); |
|
164 return (err); 165} 166 167int 168register_mem(struct mem_range *memp) 169{ 170 struct mmio_rb_range *mrp; 171 int err; --- 25 unchanged lines hidden --- | 187 return (err); 188} 189 190int 191register_mem(struct mem_range *memp) 192{ 193 struct mmio_rb_range *mrp; 194 int err; --- 25 unchanged lines hidden --- |