vmm_lapic.c revision 240772
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 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 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$ 27 */ 28 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 38#include <machine/vmm.h> 39#include "vmm_ipi.h" 40#include "vmm_lapic.h" 41#include "vlapic.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; 50 else 51 handled = 0; 52 53 return (handled); 54} 55 56static int 57lapic_read(struct vlapic *vlapic, u_int offset, uint64_t *rv) 58{ 59 int handled; 60 61 if (vlapic_op_mem_read(vlapic, offset, DWORD, rv) == 0) 62 handled = 1; 63 else 64 handled = 0; 65 66 return (handled); 67} 68 69int 70lapic_pending_intr(struct vm *vm, int cpu) 71{ 72 struct vlapic *vlapic; 73 74 vlapic = vm_lapic(vm, cpu); 75 76 return (vlapic_pending_intr(vlapic)); 77} 78 79void 80lapic_intr_accepted(struct vm *vm, int cpu, int vector) 81{ 82 struct vlapic *vlapic; 83 84 vlapic = vm_lapic(vm, cpu); 85 86 vlapic_intr_accepted(vlapic, vector); 87} 88 89int 90lapic_set_intr(struct vm *vm, int cpu, int vector) 91{ 92 struct vlapic *vlapic; 93 94 if (cpu < 0 || cpu >= VM_MAXCPU) 95 return (EINVAL); 96 97 if (vector < 32 || vector > 255) 98 return (EINVAL); 99 100 vlapic = vm_lapic(vm, cpu); 101 vlapic_set_intr_ready(vlapic, vector); 102 103 vm_interrupt_hostcpu(vm, cpu); 104 105 return (0); 106} 107 108void 109lapic_timer_tick(struct vm *vm, int cpu) 110{ 111 struct vlapic *vlapic; 112 113 vlapic = vm_lapic(vm, cpu); 114 115 vlapic_timer_tick(vlapic); 116} 117 118static boolean_t 119x2apic_msr(u_int msr) 120{ 121 if (msr >= 0x800 && msr <= 0xBFF) 122 return (TRUE); 123 else 124 return (FALSE); 125} 126 127static u_int 128x2apic_msr_to_regoff(u_int msr) 129{ 130 131 return ((msr - 0x800) << 4); 132} 133 134boolean_t 135lapic_msr(u_int msr) 136{ 137 138 if (x2apic_msr(msr) || (msr == MSR_APICBASE)) 139 return (TRUE); 140 else 141 return (FALSE); 142} 143 144int 145lapic_rdmsr(struct vm *vm, int cpu, u_int msr, uint64_t *rval) 146{ 147 int handled; 148 struct vlapic *vlapic; 149 150 vlapic = vm_lapic(vm, cpu); 151 152 if (msr == MSR_APICBASE) { 153 *rval = vlapic_get_apicbase(vlapic); 154 handled = 1; 155 } else 156 handled = lapic_read(vlapic, x2apic_msr_to_regoff(msr), rval); 157 158 return (handled); 159} 160 161int 162lapic_wrmsr(struct vm *vm, int cpu, u_int msr, uint64_t val) 163{ 164 int handled; 165 struct vlapic *vlapic; 166 167 vlapic = vm_lapic(vm, cpu); 168 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} 177