2
* Copyright (c) 2006, Intel Corporation.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* You should have received a copy of the GNU General Public License along with
14
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
* Place - Suite 330, Boston, MA 02111-1307 USA.
17
* Copyright (C) Allen Kay <allen.m.kay@intel.com>
18
* Copyright (C) Xiaohui Xin <xiaohui.xin@intel.com>
21
#include <xen/event.h>
22
#include <xen/iommu.h>
23
#include <asm/hvm/irq.h>
24
#include <asm/hvm/iommu.h>
25
#include <asm/hvm/support.h>
26
#include <xen/hvm/irq.h>
28
static void hvm_dirq_assist(unsigned long _d);
30
static int pt_irq_need_timer(uint32_t flags)
32
return !(flags & (HVM_IRQ_DPCI_GUEST_MSI | HVM_IRQ_DPCI_TRANSLATE));
35
static void pt_irq_time_out(void *data)
37
struct hvm_mirq_dpci_mapping *irq_map = data;
38
unsigned int guest_gsi, machine_gsi = 0;
39
struct hvm_irq_dpci *dpci = NULL;
40
struct dev_intx_gsi_link *digl;
41
struct hvm_girq_dpci_mapping *girq;
42
uint32_t device, intx;
43
unsigned int nr_pirqs = irq_map->dom->nr_pirqs;
44
DECLARE_BITMAP(machine_gsi_map, nr_pirqs);
46
bitmap_zero(machine_gsi_map, nr_pirqs);
48
spin_lock(&irq_map->dom->event_lock);
50
dpci = domain_get_irq_dpci(irq_map->dom);
52
list_for_each_entry ( digl, &irq_map->digl_list, list )
54
guest_gsi = digl->gsi;
55
list_for_each_entry ( girq, &dpci->girq[guest_gsi], list )
57
machine_gsi = girq->machine_gsi;
58
set_bit(machine_gsi, machine_gsi_map);
60
device = digl->device;
62
hvm_pci_intx_deassert(irq_map->dom, device, intx);
65
for ( machine_gsi = find_first_bit(machine_gsi_map, nr_pirqs);
66
machine_gsi < nr_pirqs;
67
machine_gsi = find_next_bit(machine_gsi_map, nr_pirqs,
70
clear_bit(machine_gsi, dpci->dirq_mask);
71
dpci->mirq[machine_gsi].pending = 0;
74
spin_unlock(&irq_map->dom->event_lock);
76
for ( machine_gsi = find_first_bit(machine_gsi_map, nr_pirqs);
77
machine_gsi < nr_pirqs;
78
machine_gsi = find_next_bit(machine_gsi_map, nr_pirqs,
81
pirq_guest_eoi(irq_map->dom, machine_gsi);
85
void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci)
88
xfree(dpci->dirq_mask);
90
xfree(dpci->hvm_timer);
94
int pt_irq_create_bind_vtd(
95
struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
97
struct hvm_irq_dpci *hvm_irq_dpci = NULL;
98
uint32_t machine_gsi, guest_gsi;
99
uint32_t device, intx, link;
100
struct dev_intx_gsi_link *digl;
101
struct hvm_girq_dpci_mapping *girq;
102
int rc, pirq = pt_irq_bind->machine_irq;
104
if ( pirq < 0 || pirq >= d->nr_pirqs )
107
spin_lock(&d->event_lock);
109
hvm_irq_dpci = domain_get_irq_dpci(d);
110
if ( hvm_irq_dpci == NULL )
112
hvm_irq_dpci = xmalloc(struct hvm_irq_dpci);
113
if ( hvm_irq_dpci == NULL )
115
spin_unlock(&d->event_lock);
118
memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
119
tasklet_init(&hvm_irq_dpci->dirq_tasklet,
120
hvm_dirq_assist, (unsigned long)d);
121
hvm_irq_dpci->mirq = xmalloc_array(struct hvm_mirq_dpci_mapping,
123
hvm_irq_dpci->dirq_mask = xmalloc_array(unsigned long,
124
BITS_TO_LONGS(d->nr_pirqs));
125
hvm_irq_dpci->mapping = xmalloc_array(unsigned long,
126
BITS_TO_LONGS(d->nr_pirqs));
127
hvm_irq_dpci->hvm_timer = xmalloc_array(struct timer, nr_irqs);
128
if ( !hvm_irq_dpci->mirq ||
129
!hvm_irq_dpci->dirq_mask ||
130
!hvm_irq_dpci->mapping ||
131
!hvm_irq_dpci->hvm_timer)
133
spin_unlock(&d->event_lock);
134
free_hvm_irq_dpci(hvm_irq_dpci);
137
memset(hvm_irq_dpci->mirq, 0,
138
d->nr_pirqs * sizeof(*hvm_irq_dpci->mirq));
139
bitmap_zero(hvm_irq_dpci->dirq_mask, d->nr_pirqs);
140
bitmap_zero(hvm_irq_dpci->mapping, d->nr_pirqs);
141
memset(hvm_irq_dpci->hvm_timer, 0,
142
nr_irqs * sizeof(*hvm_irq_dpci->hvm_timer));
143
for ( int i = 0; i < d->nr_pirqs; i++ ) {
144
INIT_LIST_HEAD(&hvm_irq_dpci->mirq[i].digl_list);
145
hvm_irq_dpci->mirq[i].gmsi.dest_vcpu_id = -1;
147
for ( int i = 0; i < NR_HVM_IRQS; i++ )
148
INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]);
150
if ( domain_set_irq_dpci(d, hvm_irq_dpci) == 0 )
152
spin_unlock(&d->event_lock);
153
free_hvm_irq_dpci(hvm_irq_dpci);
158
if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI )
160
uint8_t dest, dest_mode;
163
if ( !test_and_set_bit(pirq, hvm_irq_dpci->mapping))
165
hvm_irq_dpci->mirq[pirq].flags = HVM_IRQ_DPCI_MACH_MSI |
166
HVM_IRQ_DPCI_GUEST_MSI;
167
hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
168
hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
169
/* bind after hvm_irq_dpci is setup to avoid race with irq handler*/
170
rc = pirq_guest_bind(d->vcpu[0], pirq, 0);
171
if ( rc == 0 && pt_irq_bind->u.msi.gtable )
173
rc = msixtbl_pt_register(d, pirq, pt_irq_bind->u.msi.gtable);
175
pirq_guest_unbind(d, pirq);
179
hvm_irq_dpci->mirq[pirq].gmsi.gflags = 0;
180
hvm_irq_dpci->mirq[pirq].gmsi.gvec = 0;
181
hvm_irq_dpci->mirq[pirq].flags = 0;
182
clear_bit(pirq, hvm_irq_dpci->mapping);
183
spin_unlock(&d->event_lock);
189
uint32_t mask = HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_MSI;
191
if ( (hvm_irq_dpci->mirq[pirq].flags & mask) != mask)
193
spin_unlock(&d->event_lock);
197
/* if pirq is already mapped as vmsi, update the guest data/addr */
198
if ( hvm_irq_dpci->mirq[pirq].gmsi.gvec != pt_irq_bind->u.msi.gvec ||
199
hvm_irq_dpci->mirq[pirq].gmsi.gflags != pt_irq_bind->u.msi.gflags) {
200
/* Directly clear pending EOIs before enabling new MSI info. */
201
pirq_guest_eoi(d, pirq);
203
hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
204
hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
207
/* Caculate dest_vcpu_id for MSI-type pirq migration */
208
dest = hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DEST_ID_MASK;
209
dest_mode = !!(hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DM_MASK);
210
dest_vcpu_id = hvm_girq_dest_2_vcpu_id(d, dest, dest_mode);
211
hvm_irq_dpci->mirq[pirq].gmsi.dest_vcpu_id = dest_vcpu_id;
212
spin_unlock(&d->event_lock);
213
if ( dest_vcpu_id >= 0 )
214
hvm_migrate_pirqs(d->vcpu[dest_vcpu_id]);
218
machine_gsi = pt_irq_bind->machine_irq;
219
device = pt_irq_bind->u.pci.device;
220
intx = pt_irq_bind->u.pci.intx;
221
guest_gsi = hvm_pci_intx_gsi(device, intx);
222
link = hvm_pci_intx_link(device, intx);
223
hvm_irq_dpci->link_cnt[link]++;
225
digl = xmalloc(struct dev_intx_gsi_link);
228
spin_unlock(&d->event_lock);
232
girq = xmalloc(struct hvm_girq_dpci_mapping);
236
spin_unlock(&d->event_lock);
240
digl->device = device;
242
digl->gsi = guest_gsi;
244
list_add_tail(&digl->list,
245
&hvm_irq_dpci->mirq[machine_gsi].digl_list);
247
girq->device = device;
249
girq->machine_gsi = machine_gsi;
250
list_add_tail(&girq->list, &hvm_irq_dpci->girq[guest_gsi]);
252
/* Bind the same mirq once in the same domain */
253
if ( !test_and_set_bit(machine_gsi, hvm_irq_dpci->mapping))
255
unsigned int irq = domain_pirq_to_irq(d, machine_gsi);
258
hvm_irq_dpci->mirq[machine_gsi].dom = d;
259
if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI_TRANSLATE )
261
hvm_irq_dpci->mirq[machine_gsi].flags = HVM_IRQ_DPCI_MACH_MSI |
262
HVM_IRQ_DPCI_GUEST_PCI |
263
HVM_IRQ_DPCI_TRANSLATE;
266
else /* PT_IRQ_TYPE_PCI */
268
hvm_irq_dpci->mirq[machine_gsi].flags = HVM_IRQ_DPCI_MACH_PCI |
269
HVM_IRQ_DPCI_GUEST_PCI;
270
share = BIND_PIRQ__WILL_SHARE;
273
/* Init timer before binding */
274
if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
275
init_timer(&hvm_irq_dpci->hvm_timer[irq],
276
pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
277
/* Deal with gsi for legacy devices */
278
rc = pirq_guest_bind(d->vcpu[0], machine_gsi, share);
281
if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
282
kill_timer(&hvm_irq_dpci->hvm_timer[irq]);
283
hvm_irq_dpci->mirq[machine_gsi].dom = NULL;
284
clear_bit(machine_gsi, hvm_irq_dpci->mapping);
285
list_del(&girq->list);
287
list_del(&digl->list);
288
hvm_irq_dpci->link_cnt[link]--;
289
spin_unlock(&d->event_lock);
295
spin_unlock(&d->event_lock);
299
"d%d: bind: m_gsi=%u g_gsi=%u device=%u intx=%u\n",
300
d->domain_id, machine_gsi, guest_gsi, device, intx);
305
int pt_irq_destroy_bind_vtd(
306
struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
308
struct hvm_irq_dpci *hvm_irq_dpci = NULL;
309
uint32_t machine_gsi, guest_gsi;
310
uint32_t device, intx, link;
311
struct list_head *digl_list, *tmp;
312
struct dev_intx_gsi_link *digl;
313
struct hvm_girq_dpci_mapping *girq;
315
machine_gsi = pt_irq_bind->machine_irq;
316
device = pt_irq_bind->u.pci.device;
317
intx = pt_irq_bind->u.pci.intx;
318
guest_gsi = hvm_pci_intx_gsi(device, intx);
319
link = hvm_pci_intx_link(device, intx);
323
"d%d: unbind: m_gsi=%u g_gsi=%u device=%u intx=%u\n",
324
d->domain_id, machine_gsi, guest_gsi, device, intx);
326
spin_lock(&d->event_lock);
328
hvm_irq_dpci = domain_get_irq_dpci(d);
330
if ( hvm_irq_dpci == NULL )
332
spin_unlock(&d->event_lock);
336
hvm_irq_dpci->link_cnt[link]--;
338
list_for_each_entry ( girq, &hvm_irq_dpci->girq[guest_gsi], list )
340
if ( girq->machine_gsi == machine_gsi )
342
list_del(&girq->list);
348
/* clear the mirq info */
349
if ( test_bit(machine_gsi, hvm_irq_dpci->mapping))
351
list_for_each_safe ( digl_list, tmp,
352
&hvm_irq_dpci->mirq[machine_gsi].digl_list )
354
digl = list_entry(digl_list,
355
struct dev_intx_gsi_link, list);
356
if ( digl->device == device &&
357
digl->intx == intx &&
358
digl->link == link &&
359
digl->gsi == guest_gsi )
361
list_del(&digl->list);
366
if ( list_empty(&hvm_irq_dpci->mirq[machine_gsi].digl_list) )
368
pirq_guest_unbind(d, machine_gsi);
369
msixtbl_pt_unregister(d, machine_gsi);
370
if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
371
kill_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, machine_gsi)]);
372
hvm_irq_dpci->mirq[machine_gsi].dom = NULL;
373
hvm_irq_dpci->mirq[machine_gsi].flags = 0;
374
clear_bit(machine_gsi, hvm_irq_dpci->mapping);
377
spin_unlock(&d->event_lock);
381
"d%d unmap: m_irq=%u device=%u intx=%u\n",
382
d->domain_id, machine_gsi, device, intx);
387
int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
389
struct hvm_irq_dpci *dpci = domain_get_irq_dpci(d);
391
ASSERT(spin_is_locked(&irq_desc[domain_pirq_to_irq(d, mirq)].lock));
392
if ( !iommu_enabled || (d == dom0) || !dpci ||
393
!test_bit(mirq, dpci->mapping))
396
set_bit(mirq, dpci->dirq_mask);
397
tasklet_schedule(&dpci->dirq_tasklet);
401
#ifdef SUPPORT_MSI_REMAPPING
402
/* called with d->event_lock held */
403
static void __msi_pirq_eoi(struct domain *d, int pirq)
405
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
408
if ( ( pirq >= 0 ) && ( pirq < d->nr_pirqs ) &&
409
test_bit(pirq, hvm_irq_dpci->mapping) &&
410
( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MACH_MSI) )
412
BUG_ON(!local_irq_is_enabled());
413
desc = domain_spin_lock_irq_desc(d, pirq, NULL);
417
desc->status &= ~IRQ_INPROGRESS;
418
spin_unlock_irq(&desc->lock);
420
pirq_guest_eoi(d, pirq);
424
void hvm_dpci_msi_eoi(struct domain *d, int vector)
426
int pirq, dest, dest_mode;
427
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
429
if ( !iommu_enabled || (hvm_irq_dpci == NULL) )
432
spin_lock(&d->event_lock);
433
for ( pirq = find_first_bit(hvm_irq_dpci->mapping, d->nr_pirqs);
435
pirq = find_next_bit(hvm_irq_dpci->mapping, d->nr_pirqs, pirq + 1) )
437
if ( (!(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MACH_MSI)) ||
438
(hvm_irq_dpci->mirq[pirq].gmsi.gvec != vector) )
441
dest = hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DEST_ID_MASK;
442
dest_mode = !!(hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DM_MASK);
443
if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest, dest_mode) )
446
if ( pirq < d->nr_pirqs )
447
__msi_pirq_eoi(d, pirq);
448
spin_unlock(&d->event_lock);
451
extern int vmsi_deliver(struct domain *d, int pirq);
452
static int hvm_pci_msi_assert(struct domain *d, int pirq)
454
return vmsi_deliver(d, pirq);
458
static void hvm_dirq_assist(unsigned long _d)
461
uint32_t device, intx;
462
struct domain *d = (struct domain *)_d;
463
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
464
struct dev_intx_gsi_link *digl;
466
ASSERT(hvm_irq_dpci);
468
for ( pirq = find_first_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs);
470
pirq = find_next_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs, pirq + 1) )
472
if ( !test_and_clear_bit(pirq, hvm_irq_dpci->dirq_mask) )
475
spin_lock(&d->event_lock);
476
#ifdef SUPPORT_MSI_REMAPPING
477
if ( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_GUEST_MSI )
479
hvm_pci_msi_assert(d, pirq);
480
spin_unlock(&d->event_lock);
484
list_for_each_entry ( digl, &hvm_irq_dpci->mirq[pirq].digl_list, list )
486
device = digl->device;
488
hvm_pci_intx_assert(d, device, intx);
489
hvm_irq_dpci->mirq[pirq].pending++;
491
#ifdef SUPPORT_MSI_REMAPPING
492
if ( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_TRANSLATE )
494
/* for translated MSI to INTx interrupt, eoi as early as possible */
495
__msi_pirq_eoi(d, pirq);
501
* Set a timer to see if the guest can finish the interrupt or not. For
502
* example, the guest OS may unmask the PIC during boot, before the
503
* guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
504
* guest will never deal with the irq, then the physical interrupt line
505
* will never be deasserted.
507
if ( pt_irq_need_timer(hvm_irq_dpci->mirq[pirq].flags) )
508
set_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, pirq)],
509
NOW() + PT_IRQ_TIME_OUT);
510
spin_unlock(&d->event_lock);
514
static void __hvm_dpci_eoi(struct domain *d,
515
struct hvm_irq_dpci *hvm_irq_dpci,
516
struct hvm_girq_dpci_mapping *girq,
517
union vioapic_redir_entry *ent)
519
uint32_t device, intx, machine_gsi;
521
device = girq->device;
523
hvm_pci_intx_deassert(d, device, intx);
525
machine_gsi = girq->machine_gsi;
528
* No need to get vector lock for timer
529
* since interrupt is still not EOIed
531
if ( --hvm_irq_dpci->mirq[machine_gsi].pending ||
532
( ent && ent->fields.mask ) ||
533
! pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
536
stop_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, machine_gsi)]);
537
pirq_guest_eoi(d, machine_gsi);
540
void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
541
union vioapic_redir_entry *ent)
543
struct hvm_irq_dpci *hvm_irq_dpci;
544
struct hvm_girq_dpci_mapping *girq;
546
if ( !iommu_enabled )
549
if ( guest_gsi < NR_ISAIRQS )
551
hvm_dpci_isairq_eoi(d, guest_gsi);
555
spin_lock(&d->event_lock);
556
hvm_irq_dpci = domain_get_irq_dpci(d);
561
list_for_each_entry ( girq, &hvm_irq_dpci->girq[guest_gsi], list )
562
__hvm_dpci_eoi(d, hvm_irq_dpci, girq, ent);
565
spin_unlock(&d->event_lock);