vmm.c (268889) | vmm.c (269008) |
---|---|
1/*- 2 * Copyright (c) 2011 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) 2011 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: head/sys/amd64/vmm/vmm.c 268889 2014-07-19 20:59:08Z neel $ | 26 * $FreeBSD: head/sys/amd64/vmm/vmm.c 269008 2014-07-23 04:28:51Z neel $ |
27 */ 28 29#include <sys/cdefs.h> | 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/amd64/vmm/vmm.c 268889 2014-07-19 20:59:08Z neel $"); | 30__FBSDID("$FreeBSD: head/sys/amd64/vmm/vmm.c 269008 2014-07-23 04:28:51Z neel $"); |
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/sysctl.h> 37#include <sys/malloc.h> 38#include <sys/pcpu.h> --- 1191 unchanged lines hidden (view full) --- 1230 } else if (gpa >= VHPET_BASE && gpa < VHPET_BASE + VHPET_SIZE) { 1231 mread = vhpet_mmio_read; 1232 mwrite = vhpet_mmio_write; 1233 } else { 1234 *retu = true; 1235 return (0); 1236 } 1237 | 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/sysctl.h> 37#include <sys/malloc.h> 38#include <sys/pcpu.h> --- 1191 unchanged lines hidden (view full) --- 1230 } else if (gpa >= VHPET_BASE && gpa < VHPET_BASE + VHPET_SIZE) { 1231 mread = vhpet_mmio_read; 1232 mwrite = vhpet_mmio_write; 1233 } else { 1234 *retu = true; 1235 return (0); 1236 } 1237 |
1238 error = vmm_emulate_instruction(vm, vcpuid, gpa, vie, mread, mwrite, 1239 retu); | 1238 error = vmm_emulate_instruction(vm, vcpuid, gpa, vie, paging, 1239 mread, mwrite, retu); |
1240 1241 return (error); 1242} 1243 1244static int 1245vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu) 1246{ 1247 int i, done; --- 498 unchanged lines hidden (view full) --- 1746 struct vm_exception udf = { 1747 .vector = IDT_UD, 1748 .error_code_valid = 0 1749 }; 1750 1751 vm_inject_fault(vm, vcpuid, &udf); 1752} 1753 | 1240 1241 return (error); 1242} 1243 1244static int 1245vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu) 1246{ 1247 int i, done; --- 498 unchanged lines hidden (view full) --- 1746 struct vm_exception udf = { 1747 .vector = IDT_UD, 1748 .error_code_valid = 0 1749 }; 1750 1751 vm_inject_fault(vm, vcpuid, &udf); 1752} 1753 |
1754void 1755vm_inject_ac(struct vm *vm, int vcpuid, int error_code) 1756{ 1757 struct vm_exception acf = { 1758 .vector = IDT_AC, 1759 .error_code_valid = 1, 1760 .error_code = error_code 1761 }; 1762 1763 vm_inject_fault(vm, vcpuid, &acf); 1764} 1765 1766void 1767vm_inject_ss(struct vm *vm, int vcpuid, int error_code) 1768{ 1769 struct vm_exception ssf = { 1770 .vector = IDT_SS, 1771 .error_code_valid = 1, 1772 .error_code = error_code 1773 }; 1774 1775 vm_inject_fault(vm, vcpuid, &ssf); 1776} 1777 |
|
1754static VMM_STAT(VCPU_NMI_COUNT, "number of NMIs delivered to vcpu"); 1755 1756int 1757vm_inject_nmi(struct vm *vm, int vcpuid) 1758{ 1759 struct vcpu *vcpu; 1760 1761 if (vcpuid < 0 || vcpuid >= VM_MAXCPU) --- 415 unchanged lines hidden (view full) --- 2177 VM_REG_GUEST_GS 2178 }; 2179 2180 KASSERT(seg >= 0 && seg < nitems(seg_names), 2181 ("%s: invalid segment encoding %d", __func__, seg)); 2182 return (seg_names[seg]); 2183} 2184 | 1778static VMM_STAT(VCPU_NMI_COUNT, "number of NMIs delivered to vcpu"); 1779 1780int 1781vm_inject_nmi(struct vm *vm, int vcpuid) 1782{ 1783 struct vcpu *vcpu; 1784 1785 if (vcpuid < 0 || vcpuid >= VM_MAXCPU) --- 415 unchanged lines hidden (view full) --- 2201 VM_REG_GUEST_GS 2202 }; 2203 2204 KASSERT(seg >= 0 && seg < nitems(seg_names), 2205 ("%s: invalid segment encoding %d", __func__, seg)); 2206 return (seg_names[seg]); 2207} 2208 |
2209void 2210vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, 2211 int num_copyinfo) 2212{ 2213 int idx; |
|
2185 | 2214 |
2215 for (idx = 0; idx < num_copyinfo; idx++) { 2216 if (copyinfo[idx].cookie != NULL) 2217 vm_gpa_release(copyinfo[idx].cookie); 2218 } 2219 bzero(copyinfo, num_copyinfo * sizeof(struct vm_copyinfo)); 2220} 2221 2222int 2223vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, 2224 uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo, 2225 int num_copyinfo) 2226{ 2227 int error, idx, nused; 2228 size_t n, off, remaining; 2229 void *hva, *cookie; 2230 uint64_t gpa; 2231 2232 bzero(copyinfo, sizeof(struct vm_copyinfo) * num_copyinfo); 2233 2234 nused = 0; 2235 remaining = len; 2236 while (remaining > 0) { 2237 KASSERT(nused < num_copyinfo, ("insufficient vm_copyinfo")); 2238 error = vmm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa); 2239 if (error) 2240 return (error); 2241 off = gpa & PAGE_MASK; 2242 n = min(remaining, PAGE_SIZE - off); 2243 copyinfo[nused].gpa = gpa; 2244 copyinfo[nused].len = n; 2245 remaining -= n; 2246 gla += n; 2247 nused++; 2248 } 2249 2250 for (idx = 0; idx < nused; idx++) { 2251 hva = vm_gpa_hold(vm, copyinfo[idx].gpa, copyinfo[idx].len, 2252 prot, &cookie); 2253 if (hva == NULL) 2254 break; 2255 copyinfo[idx].hva = hva; 2256 copyinfo[idx].cookie = cookie; 2257 } 2258 2259 if (idx != nused) { 2260 vm_copy_teardown(vm, vcpuid, copyinfo, num_copyinfo); 2261 return (-1); 2262 } else { 2263 return (0); 2264 } 2265} 2266 2267void 2268vm_copyin(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, void *kaddr, 2269 size_t len) 2270{ 2271 char *dst; 2272 int idx; 2273 2274 dst = kaddr; 2275 idx = 0; 2276 while (len > 0) { 2277 bcopy(copyinfo[idx].hva, dst, copyinfo[idx].len); 2278 len -= copyinfo[idx].len; 2279 dst += copyinfo[idx].len; 2280 idx++; 2281 } 2282} 2283 2284void 2285vm_copyout(struct vm *vm, int vcpuid, const void *kaddr, 2286 struct vm_copyinfo *copyinfo, size_t len) 2287{ 2288 const char *src; 2289 int idx; 2290 2291 src = kaddr; 2292 idx = 0; 2293 while (len > 0) { 2294 bcopy(src, copyinfo[idx].hva, copyinfo[idx].len); 2295 len -= copyinfo[idx].len; 2296 src += copyinfo[idx].len; 2297 idx++; 2298 } 2299} 2300 |
|
2186/* 2187 * Return the amount of in-use and wired memory for the VM. Since 2188 * these are global stats, only return the values with for vCPU 0 2189 */ 2190VMM_STAT_DECLARE(VMM_MEM_RESIDENT); 2191VMM_STAT_DECLARE(VMM_MEM_WIRED); 2192 2193static void --- 21 unchanged lines hidden --- | 2301/* 2302 * Return the amount of in-use and wired memory for the VM. Since 2303 * these are global stats, only return the values with for vCPU 0 2304 */ 2305VMM_STAT_DECLARE(VMM_MEM_RESIDENT); 2306VMM_STAT_DECLARE(VMM_MEM_WIRED); 2307 2308static void --- 21 unchanged lines hidden --- |