vmm_lapic.c (241766) | vmm_lapic.c (243640) |
---|---|
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 --- 20 unchanged lines hidden (view full) --- 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/smp.h> 35 36#include <x86/specialreg.h> | 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 --- 20 unchanged lines hidden (view full) --- 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/smp.h> 35 36#include <x86/specialreg.h> |
37#include <x86/apicreg.h> |
|
37 38#include <machine/vmm.h> 39#include "vmm_ipi.h" 40#include "vmm_lapic.h" 41#include "vlapic.h" | 38 39#include <machine/vmm.h> 40#include "vmm_ipi.h" 41#include "vmm_lapic.h" 42#include "vlapic.h" |
42#include "vmm_instruction_emul.h" | |
43 44static int 45lapic_write(struct vlapic *vlapic, u_int offset, uint64_t val) 46{ 47 int handled; 48 49 if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0) 50 handled = 1; --- 121 unchanged lines hidden (view full) --- 172 handled = 1; 173 } else 174 handled = lapic_write(vlapic, x2apic_msr_to_regoff(msr), val); 175 176 return (handled); 177} 178 179int | 43 44static int 45lapic_write(struct vlapic *vlapic, u_int offset, uint64_t val) 46{ 47 int handled; 48 49 if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0) 50 handled = 1; --- 121 unchanged lines hidden (view full) --- 172 handled = 1; 173 } else 174 handled = lapic_write(vlapic, x2apic_msr_to_regoff(msr), val); 175 176 return (handled); 177} 178 179int |
180lapic_mmio(struct vm *vm, int cpu, u_int offset, int read, struct vie *vie) | 180lapic_mmio_write(void *vm, int cpu, uint64_t gpa, uint64_t wval, int size, 181 void *arg) |
181{ | 182{ |
182 int handled, error; 183 uint64_t val; | 183 int error; 184 uint64_t off; |
184 struct vlapic *vlapic; 185 | 185 struct vlapic *vlapic; 186 |
186 const int UNHANDLED = 0; | 187 off = gpa - DEFAULT_APIC_BASE; |
187 | 188 |
188 vlapic = vm_lapic(vm, cpu); 189 190 /* Only 32-bit accesses to local apic */ 191 if (vie->op_size != VIE_OP_SIZE_32BIT) 192 return (UNHANDLED); 193 | |
194 /* | 189 /* |
195 * XXX 196 * The operand register in which we store the result of the 197 * read must be a GPR that we can modify even if the vcpu 198 * is "running". All the GPRs qualify except for %rsp. 199 * 200 * This is a limitation of the vm_set_register() API 201 * and can be fixed if necessary. | 190 * Memory mapped local apic accesses must be 4 bytes wide and 191 * aligned on a 16-byte boundary. |
202 */ | 192 */ |
203 if (vie->operand_register == VM_REG_GUEST_RSP) 204 return (UNHANDLED); | 193 if (size != 4 || off & 0xf) 194 return (EINVAL); |
205 | 195 |
206 if (read) { 207 if ((vie->opcode_flags & VIE_F_TO_REG) == 0) 208 return (UNHANDLED); | 196 vlapic = vm_lapic(vm, cpu); 197 error = vlapic_op_mem_write(vlapic, off, DWORD, wval); 198 return (error); 199} |
209 | 200 |
210 if (vie->operand_register >= VM_REG_LAST) 211 return (UNHANDLED); | 201int 202lapic_mmio_read(void *vm, int cpu, uint64_t gpa, uint64_t *rval, int size, 203 void *arg) 204{ 205 int error; 206 uint64_t off; 207 struct vlapic *vlapic; |
212 | 208 |
213 handled = lapic_read(vlapic, offset, &val); 214 if (handled) { 215 error = vm_set_register(vm, cpu, vie->operand_register, 216 val); 217 if (error) 218 panic("lapic_mmio: error %d setting gpr %d", 219 error, vie->operand_register); 220 } 221 } else { 222 if ((vie->opcode_flags & VIE_F_FROM_REG) && 223 (vie->operand_register < VM_REG_LAST)) { 224 error = vm_get_register(vm, cpu, vie->operand_register, 225 &val); 226 if (error) { 227 panic("lapic_mmio: error %d getting gpr %d", 228 error, vie->operand_register); 229 } 230 } else if (vie->opcode_flags & VIE_F_FROM_IMM) { 231 val = vie->immediate; 232 } else { 233 return (UNHANDLED); 234 } | 209 off = gpa - DEFAULT_APIC_BASE; |
235 | 210 |
236 handled = lapic_write(vlapic, offset, val); 237 } | 211 /* 212 * Memory mapped local apic accesses must be 4 bytes wide and 213 * aligned on a 16-byte boundary. 214 */ 215 if (size != 4 || off & 0xf) 216 return (EINVAL); |
238 | 217 |
239 return (handled); | 218 vlapic = vm_lapic(vm, cpu); 219 error = vlapic_op_mem_read(vlapic, off, DWORD, rval); 220 return (error); |
240} | 221} |