vmm_lapic.c (240772) | vmm_lapic.c (240941) |
---|---|
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 --- 25 unchanged lines hidden (view full) --- 34#include <sys/smp.h> 35 36#include <x86/specialreg.h> 37 38#include <machine/vmm.h> 39#include "vmm_ipi.h" 40#include "vmm_lapic.h" 41#include "vlapic.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 --- 25 unchanged lines hidden (view full) --- 34#include <sys/smp.h> 35 36#include <x86/specialreg.h> 37 38#include <machine/vmm.h> 39#include "vmm_ipi.h" 40#include "vmm_lapic.h" 41#include "vlapic.h" |
42#include "vmm_instruction_emul.h" |
|
42 43static int 44lapic_write(struct vlapic *vlapic, u_int offset, uint64_t val) 45{ 46 int handled; 47 48 if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0) 49 handled = 1; --- 119 unchanged lines hidden (view full) --- 169 if (msr == MSR_APICBASE) { 170 vlapic_set_apicbase(vlapic, val); 171 handled = 1; 172 } else 173 handled = lapic_write(vlapic, x2apic_msr_to_regoff(msr), val); 174 175 return (handled); 176} | 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; --- 119 unchanged lines hidden (view full) --- 170 if (msr == MSR_APICBASE) { 171 vlapic_set_apicbase(vlapic, val); 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, 181 uint64_t rip, uint64_t cr3) 182{ 183 int handled, error; 184 uint64_t val; 185 struct vie vie; 186 struct vlapic *vlapic; 187 188 const int UNHANDLED = 0; 189 190 vlapic = vm_lapic(vm, cpu); 191 192 vmm_fetch_instruction(vm, rip, cr3, &vie); 193 194 if (vmm_decode_instruction(&vie) != 0) 195 return (UNHANDLED); 196 197 /* Only 32-bit accesses to local apic */ 198 if (vie.op_size != VIE_OP_SIZE_32BIT) 199 return (UNHANDLED); 200 201 /* 202 * XXX 203 * The operand register in which we store the result of the 204 * read must be a GPR that we can modify even if the vcpu 205 * is "running". All the GPRs qualify except for %rsp. 206 * 207 * This is a limitation of the vm_set_register() API 208 * and can be fixed if necessary. 209 */ 210 if (vie.operand_register == VM_REG_GUEST_RSP) 211 return (UNHANDLED); 212 213 if (read) { 214 if ((vie.opcode_flags & VIE_F_TO_REG) == 0) 215 return (UNHANDLED); 216 217 if (vie.operand_register >= VM_REG_LAST) 218 return (UNHANDLED); 219 220 handled = lapic_read(vlapic, offset, &val); 221 if (handled) { 222 error = vm_set_register(vm, cpu, vie.operand_register, 223 val); 224 if (error) 225 panic("lapic_mmio: error %d setting gpr %d", 226 error, vie.operand_register); 227 } 228 } else { 229 if ((vie.opcode_flags & VIE_F_FROM_REG) && 230 (vie.operand_register < VM_REG_LAST)) { 231 error = vm_get_register(vm, cpu, vie.operand_register, 232 &val); 233 if (error) { 234 panic("lapic_mmio: error %d getting gpr %d", 235 error, vie.operand_register); 236 } 237 } else if (vie.opcode_flags & VIE_F_FROM_IMM) { 238 val = vie.immediate; 239 } else { 240 return (UNHANDLED); 241 } 242 243 handled = lapic_write(vlapic, offset, val); 244 } 245 246 return (handled); 247} |
|