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