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