KVM: Add statistic for remote tlb flushes
[linux-2.6] / drivers / kvm / ioapic.c
1 /*
2  *  Copyright (C) 2001  MandrakeSoft S.A.
3  *
4  *    MandrakeSoft S.A.
5  *    43, rue d'Aboukir
6  *    75002 Paris - France
7  *    http://www.linux-mandrake.com/
8  *    http://www.mandrakesoft.com/
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  *
24  *  Yunhong Jiang <yunhong.jiang@intel.com>
25  *  Yaozu (Eddie) Dong <eddie.dong@intel.com>
26  *  Based on Xen 3.1 code.
27  */
28
29 #include "kvm.h"
30 #include "x86.h"
31
32 #include <linux/kvm.h>
33 #include <linux/mm.h>
34 #include <linux/highmem.h>
35 #include <linux/smp.h>
36 #include <linux/hrtimer.h>
37 #include <linux/io.h>
38 #include <asm/processor.h>
39 #include <asm/msr.h>
40 #include <asm/page.h>
41 #include <asm/current.h>
42 #include <asm/apicdef.h>
43 #include <asm/io_apic.h>
44 #include "irq.h"
45 #if 0
46 #define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg)
47 #else
48 #define ioapic_debug(fmt, arg...)
49 #endif
50 static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq);
51
52 static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
53                                           unsigned long addr,
54                                           unsigned long length)
55 {
56         unsigned long result = 0;
57
58         switch (ioapic->ioregsel) {
59         case IOAPIC_REG_VERSION:
60                 result = ((((IOAPIC_NUM_PINS - 1) & 0xff) << 16)
61                           | (IOAPIC_VERSION_ID & 0xff));
62                 break;
63
64         case IOAPIC_REG_APIC_ID:
65         case IOAPIC_REG_ARB_ID:
66                 result = ((ioapic->id & 0xf) << 24);
67                 break;
68
69         default:
70                 {
71                         u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
72                         u64 redir_content;
73
74                         ASSERT(redir_index < IOAPIC_NUM_PINS);
75
76                         redir_content = ioapic->redirtbl[redir_index].bits;
77                         result = (ioapic->ioregsel & 0x1) ?
78                             (redir_content >> 32) & 0xffffffff :
79                             redir_content & 0xffffffff;
80                         break;
81                 }
82         }
83
84         return result;
85 }
86
87 static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
88 {
89         union ioapic_redir_entry *pent;
90
91         pent = &ioapic->redirtbl[idx];
92
93         if (!pent->fields.mask) {
94                 ioapic_deliver(ioapic, idx);
95                 if (pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
96                         pent->fields.remote_irr = 1;
97         }
98         if (!pent->fields.trig_mode)
99                 ioapic->irr &= ~(1 << idx);
100 }
101
102 static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
103 {
104         unsigned index;
105
106         switch (ioapic->ioregsel) {
107         case IOAPIC_REG_VERSION:
108                 /* Writes are ignored. */
109                 break;
110
111         case IOAPIC_REG_APIC_ID:
112                 ioapic->id = (val >> 24) & 0xf;
113                 break;
114
115         case IOAPIC_REG_ARB_ID:
116                 break;
117
118         default:
119                 index = (ioapic->ioregsel - 0x10) >> 1;
120
121                 ioapic_debug("change redir index %x val %x\n", index, val);
122                 if (index >= IOAPIC_NUM_PINS)
123                         return;
124                 if (ioapic->ioregsel & 1) {
125                         ioapic->redirtbl[index].bits &= 0xffffffff;
126                         ioapic->redirtbl[index].bits |= (u64) val << 32;
127                 } else {
128                         ioapic->redirtbl[index].bits &= ~0xffffffffULL;
129                         ioapic->redirtbl[index].bits |= (u32) val;
130                         ioapic->redirtbl[index].fields.remote_irr = 0;
131                 }
132                 if (ioapic->irr & (1 << index))
133                         ioapic_service(ioapic, index);
134                 break;
135         }
136 }
137
138 static void ioapic_inj_irq(struct kvm_ioapic *ioapic,
139                            struct kvm_lapic *target,
140                            u8 vector, u8 trig_mode, u8 delivery_mode)
141 {
142         ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode,
143                      delivery_mode);
144
145         ASSERT((delivery_mode == dest_Fixed) ||
146                (delivery_mode == dest_LowestPrio));
147
148         kvm_apic_set_irq(target, vector, trig_mode);
149 }
150
151 static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
152                                        u8 dest_mode)
153 {
154         u32 mask = 0;
155         int i;
156         struct kvm *kvm = ioapic->kvm;
157         struct kvm_vcpu *vcpu;
158
159         ioapic_debug("dest %d dest_mode %d\n", dest, dest_mode);
160
161         if (dest_mode == 0) {   /* Physical mode. */
162                 if (dest == 0xFF) {     /* Broadcast. */
163                         for (i = 0; i < KVM_MAX_VCPUS; ++i)
164                                 if (kvm->vcpus[i] && kvm->vcpus[i]->apic)
165                                         mask |= 1 << i;
166                         return mask;
167                 }
168                 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
169                         vcpu = kvm->vcpus[i];
170                         if (!vcpu)
171                                 continue;
172                         if (kvm_apic_match_physical_addr(vcpu->apic, dest)) {
173                                 if (vcpu->apic)
174                                         mask = 1 << i;
175                                 break;
176                         }
177                 }
178         } else if (dest != 0)   /* Logical mode, MDA non-zero. */
179                 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
180                         vcpu = kvm->vcpus[i];
181                         if (!vcpu)
182                                 continue;
183                         if (vcpu->apic &&
184                             kvm_apic_match_logical_addr(vcpu->apic, dest))
185                                 mask |= 1 << vcpu->vcpu_id;
186                 }
187         ioapic_debug("mask %x\n", mask);
188         return mask;
189 }
190
191 static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
192 {
193         u8 dest = ioapic->redirtbl[irq].fields.dest_id;
194         u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode;
195         u8 delivery_mode = ioapic->redirtbl[irq].fields.delivery_mode;
196         u8 vector = ioapic->redirtbl[irq].fields.vector;
197         u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode;
198         u32 deliver_bitmask;
199         struct kvm_lapic *target;
200         struct kvm_vcpu *vcpu;
201         int vcpu_id;
202
203         ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x "
204                      "vector=%x trig_mode=%x\n",
205                      dest, dest_mode, delivery_mode, vector, trig_mode);
206
207         deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode);
208         if (!deliver_bitmask) {
209                 ioapic_debug("no target on destination\n");
210                 return;
211         }
212
213         switch (delivery_mode) {
214         case dest_LowestPrio:
215                 target =
216                     kvm_apic_round_robin(ioapic->kvm, vector, deliver_bitmask);
217                 if (target != NULL)
218                         ioapic_inj_irq(ioapic, target, vector,
219                                        trig_mode, delivery_mode);
220                 else
221                         ioapic_debug("null round robin: "
222                                      "mask=%x vector=%x delivery_mode=%x\n",
223                                      deliver_bitmask, vector, dest_LowestPrio);
224                 break;
225         case dest_Fixed:
226                 for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
227                         if (!(deliver_bitmask & (1 << vcpu_id)))
228                                 continue;
229                         deliver_bitmask &= ~(1 << vcpu_id);
230                         vcpu = ioapic->kvm->vcpus[vcpu_id];
231                         if (vcpu) {
232                                 target = vcpu->apic;
233                                 ioapic_inj_irq(ioapic, target, vector,
234                                                trig_mode, delivery_mode);
235                         }
236                 }
237                 break;
238
239                 /* TODO: NMI */
240         default:
241                 printk(KERN_WARNING "Unsupported delivery mode %d\n",
242                        delivery_mode);
243                 break;
244         }
245 }
246
247 void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
248 {
249         u32 old_irr = ioapic->irr;
250         u32 mask = 1 << irq;
251         union ioapic_redir_entry entry;
252
253         if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
254                 entry = ioapic->redirtbl[irq];
255                 level ^= entry.fields.polarity;
256                 if (!level)
257                         ioapic->irr &= ~mask;
258                 else {
259                         ioapic->irr |= mask;
260                         if ((!entry.fields.trig_mode && old_irr != ioapic->irr)
261                             || !entry.fields.remote_irr)
262                                 ioapic_service(ioapic, irq);
263                 }
264         }
265 }
266
267 static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector)
268 {
269         int i;
270
271         for (i = 0; i < IOAPIC_NUM_PINS; i++)
272                 if (ioapic->redirtbl[i].fields.vector == vector)
273                         return i;
274         return -1;
275 }
276
277 void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
278 {
279         struct kvm_ioapic *ioapic = kvm->vioapic;
280         union ioapic_redir_entry *ent;
281         int gsi;
282
283         gsi = get_eoi_gsi(ioapic, vector);
284         if (gsi == -1) {
285                 printk(KERN_WARNING "Can't find redir item for %d EOI\n",
286                        vector);
287                 return;
288         }
289
290         ent = &ioapic->redirtbl[gsi];
291         ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
292
293         ent->fields.remote_irr = 0;
294         if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
295                 ioapic_deliver(ioapic, gsi);
296 }
297
298 static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
299 {
300         struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
301
302         return ((addr >= ioapic->base_address &&
303                  (addr < ioapic->base_address + IOAPIC_MEM_LENGTH)));
304 }
305
306 static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
307                              void *val)
308 {
309         struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
310         u32 result;
311
312         ioapic_debug("addr %lx\n", (unsigned long)addr);
313         ASSERT(!(addr & 0xf));  /* check alignment */
314
315         addr &= 0xff;
316         switch (addr) {
317         case IOAPIC_REG_SELECT:
318                 result = ioapic->ioregsel;
319                 break;
320
321         case IOAPIC_REG_WINDOW:
322                 result = ioapic_read_indirect(ioapic, addr, len);
323                 break;
324
325         default:
326                 result = 0;
327                 break;
328         }
329         switch (len) {
330         case 8:
331                 *(u64 *) val = result;
332                 break;
333         case 1:
334         case 2:
335         case 4:
336                 memcpy(val, (char *)&result, len);
337                 break;
338         default:
339                 printk(KERN_WARNING "ioapic: wrong length %d\n", len);
340         }
341 }
342
343 static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
344                               const void *val)
345 {
346         struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
347         u32 data;
348
349         ioapic_debug("ioapic_mmio_write addr=%p len=%d val=%p\n",
350                      (void*)addr, len, val);
351         ASSERT(!(addr & 0xf));  /* check alignment */
352         if (len == 4 || len == 8)
353                 data = *(u32 *) val;
354         else {
355                 printk(KERN_WARNING "ioapic: Unsupported size %d\n", len);
356                 return;
357         }
358
359         addr &= 0xff;
360         switch (addr) {
361         case IOAPIC_REG_SELECT:
362                 ioapic->ioregsel = data;
363                 break;
364
365         case IOAPIC_REG_WINDOW:
366                 ioapic_write_indirect(ioapic, data);
367                 break;
368
369         default:
370                 break;
371         }
372 }
373
374 void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
375 {
376         int i;
377
378         for (i = 0; i < IOAPIC_NUM_PINS; i++)
379                 ioapic->redirtbl[i].fields.mask = 1;
380         ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
381         ioapic->ioregsel = 0;
382         ioapic->irr = 0;
383         ioapic->id = 0;
384 }
385
386 int kvm_ioapic_init(struct kvm *kvm)
387 {
388         struct kvm_ioapic *ioapic;
389
390         ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
391         if (!ioapic)
392                 return -ENOMEM;
393         kvm->vioapic = ioapic;
394         kvm_ioapic_reset(ioapic);
395         ioapic->dev.read = ioapic_mmio_read;
396         ioapic->dev.write = ioapic_mmio_write;
397         ioapic->dev.in_range = ioapic_in_range;
398         ioapic->dev.private = ioapic;
399         ioapic->kvm = kvm;
400         kvm_io_bus_register_dev(&kvm->mmio_bus, &ioapic->dev);
401         return 0;
402 }