Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/include/asm/hvm/irq.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * irq.h
3
 * 
4
 * Interrupt distribution and delivery logic.
5
 * 
6
 * Copyright (c) 2006, K A Fraser, XenSource Inc.
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms and conditions of the GNU General Public License,
10
 * version 2, as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope it will be useful, but WITHOUT
13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15
 * more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along with
18
 * this program; If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#ifndef __ASM_X86_HVM_IRQ_H__
22
#define __ASM_X86_HVM_IRQ_H__
23
24
#include <xen/timer.h>
25
26
#include <asm/hvm/hvm.h>
27
#include <asm/hvm/vpic.h>
28
#include <asm/hvm/vioapic.h>
29
30
struct hvm_irq {
31
    /*
32
     * Virtual interrupt wires for a single PCI bus.
33
     * Indexed by: device*4 + INTx#.
34
     */
35
    struct hvm_hw_pci_irqs pci_intx;
36
37
    /*
38
     * Virtual interrupt wires for ISA devices.
39
     * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
40
     */
41
    struct hvm_hw_isa_irqs isa_irq;
42
43
    /*
44
     * PCI-ISA interrupt router.
45
     * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
46
     * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
47
     * The router provides a programmable mapping from each link to a GSI.
48
     */
49
    struct hvm_hw_pci_link pci_link;
50
51
    /* Virtual interrupt and via-link for paravirtual platform driver. */
52
    uint32_t callback_via_asserted;
53
    union {
54
        enum {
55
            HVMIRQ_callback_none,
56
            HVMIRQ_callback_gsi,
57
            HVMIRQ_callback_pci_intx,
58
            HVMIRQ_callback_vector
59
        } callback_via_type;
60
    };
61
    union {
62
        uint32_t gsi;
63
        struct { uint8_t dev, intx; } pci;
64
        uint32_t vector;
65
    } callback_via;
66
67
    /* Number of INTx wires asserting each PCI-ISA link. */
68
    u8 pci_link_assert_count[4];
69
70
    /*
71
     * GSIs map onto PIC/IO-APIC in the usual way:
72
     *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
73
     *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
74
     *  16+ : IO-APIC pins 16+
75
     */
76
77
    /* Last VCPU that was delivered a LowestPrio interrupt. */
78
    u8 round_robin_prev_vcpu;
79
80
    struct hvm_irq_dpci *dpci;
81
82
    /*
83
     * Number of wires asserting each GSI.
84
     *
85
     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
86
     * except ISA IRQ 0, which is connected to GSI 2.
87
     * PCI links map into this space via the PCI-ISA bridge.
88
     *
89
     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
90
     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
91
     */
92
    unsigned int nr_gsis;
93
    u8 gsi_assert_count[];
94
};
95
96
#define hvm_pci_intx_gsi(dev, intx)  \
97
0
    (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
98
#define hvm_pci_intx_link(dev, intx) \
99
0
    (((dev) + (intx)) & 3)
100
5.09M
#define hvm_domain_irq(d) ((d)->arch.hvm_domain.irq)
101
#define hvm_irq_size(cnt) offsetof(struct hvm_irq, gsi_assert_count[cnt])
102
103
297
#define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
104
105
/* Check/Acknowledge next pending interrupt. */
106
struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v);
107
struct hvm_intack hvm_vcpu_ack_pending_irq(struct vcpu *v,
108
                                           struct hvm_intack intack);
109
110
struct dev_intx_gsi_link {
111
    struct list_head list;
112
    uint8_t bus;
113
    uint8_t device;
114
    uint8_t intx;
115
};
116
117
6
#define _HVM_IRQ_DPCI_MACH_PCI_SHIFT            0
118
42
#define _HVM_IRQ_DPCI_MACH_MSI_SHIFT            1
119
4.24k
#define _HVM_IRQ_DPCI_MAPPED_SHIFT              2
120
67
#define _HVM_IRQ_DPCI_EOI_LATCH_SHIFT           3
121
6
#define _HVM_IRQ_DPCI_GUEST_PCI_SHIFT           4
122
4.49k
#define _HVM_IRQ_DPCI_GUEST_MSI_SHIFT           5
123
374
#define _HVM_IRQ_DPCI_IDENTITY_GSI_SHIFT        6
124
608
#define _HVM_IRQ_DPCI_TRANSLATE_SHIFT          15
125
6
#define HVM_IRQ_DPCI_MACH_PCI        (1u << _HVM_IRQ_DPCI_MACH_PCI_SHIFT)
126
42
#define HVM_IRQ_DPCI_MACH_MSI        (1u << _HVM_IRQ_DPCI_MACH_MSI_SHIFT)
127
4.24k
#define HVM_IRQ_DPCI_MAPPED          (1u << _HVM_IRQ_DPCI_MAPPED_SHIFT)
128
67
#define HVM_IRQ_DPCI_EOI_LATCH       (1u << _HVM_IRQ_DPCI_EOI_LATCH_SHIFT)
129
6
#define HVM_IRQ_DPCI_GUEST_PCI       (1u << _HVM_IRQ_DPCI_GUEST_PCI_SHIFT)
130
4.49k
#define HVM_IRQ_DPCI_GUEST_MSI       (1u << _HVM_IRQ_DPCI_GUEST_MSI_SHIFT)
131
374
#define HVM_IRQ_DPCI_IDENTITY_GSI    (1u << _HVM_IRQ_DPCI_IDENTITY_GSI_SHIFT)
132
608
#define HVM_IRQ_DPCI_TRANSLATE       (1u << _HVM_IRQ_DPCI_TRANSLATE_SHIFT)
133
134
struct hvm_gmsi_info {
135
    uint32_t gvec;
136
    uint32_t gflags;
137
    int dest_vcpu_id; /* -1 :multi-dest, non-negative: dest_vcpu_id */
138
    bool posted; /* directly deliver to guest via VT-d PI? */
139
};
140
141
struct hvm_girq_dpci_mapping {
142
    struct list_head list;
143
    uint8_t bus;
144
    uint8_t device;
145
    uint8_t intx;
146
    uint8_t machine_gsi;
147
};
148
149
0
#define NR_ISAIRQS  16
150
0
#define NR_LINK     4
151
0
#define NR_HVM_DOMU_IRQS ARRAY_SIZE(((struct hvm_hw_vioapic *)0)->redirtbl)
152
153
/* Protected by domain's event_lock */
154
struct hvm_irq_dpci {
155
    /* Guest IRQ to guest device/intx mapping. */
156
    struct list_head girq[NR_HVM_DOMU_IRQS];
157
    /* Record of mapped ISA IRQs */
158
    DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
159
    /* Record of mapped Links */
160
    uint8_t link_cnt[NR_LINK];
161
};
162
163
/* Machine IRQ to guest device/intx mapping. */
164
struct hvm_pirq_dpci {
165
    uint32_t flags;
166
    unsigned int state;
167
    bool masked;
168
    uint16_t pending;
169
    struct list_head digl_list;
170
    struct domain *dom;
171
    struct hvm_gmsi_info gmsi;
172
    struct timer timer;
173
    struct list_head softirq_list;
174
};
175
176
void pt_pirq_init(struct domain *, struct hvm_pirq_dpci *);
177
bool pt_pirq_cleanup_check(struct hvm_pirq_dpci *);
178
int pt_pirq_iterate(struct domain *d,
179
                    int (*cb)(struct domain *,
180
                              struct hvm_pirq_dpci *, void *arg),
181
                    void *arg);
182
183
bool pt_pirq_softirq_active(struct hvm_pirq_dpci *);
184
/* Modify state of a PCI INTx wire. */
185
void hvm_pci_intx_assert(struct domain *d, unsigned int device,
186
                         unsigned int intx);
187
void hvm_pci_intx_deassert(struct domain *d, unsigned int device,
188
                           unsigned int intx);
189
190
/* Modify state of an ISA device's IRQ wire. */
191
void hvm_isa_irq_assert(struct domain *d, unsigned int isa_irq);
192
void hvm_isa_irq_deassert(struct domain *d, unsigned int isa_irq);
193
194
/* Modify state of GSIs. */
195
void hvm_gsi_assert(struct domain *d, unsigned int gsi);
196
void hvm_gsi_deassert(struct domain *d, unsigned int gsi);
197
198
int hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
199
200
int hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data);
201
202
void hvm_maybe_deassert_evtchn_irq(void);
203
void hvm_assert_evtchn_irq(struct vcpu *v);
204
void hvm_set_callback_via(struct domain *d, uint64_t via);
205
206
#endif /* __ASM_X86_HVM_IRQ_H__ */