Deleted Added
full compact
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 ---