Skip to content

Commit dd6a5fb

Browse files
yonghuahlijinxia
authored andcommitted
HV: Add hypercall to set/clear IRQ line
- wraps ASSERT/DEASSERT IRQ line hypercalls. - remove 'intr_type' from set/clear IRQ line interface. - deprecate "IRQ_ASSERT", "IRQ_DEASSERT" & "IRQ_PULSE". - new adding hypercall will support "GSI_SET_HIGH"/ "GSI_SET_LOW"/ "GSI_RAISING_PULSE"/ "GSI_FALLING_PULSE" operations Tracked-On: #861 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 05ad6d6 commit dd6a5fb

File tree

6 files changed

+84
-27
lines changed

6 files changed

+84
-27
lines changed

hypervisor/arch/x86/guest/vmcall.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
9999
ret = hcall_pulse_irqline(vm, (uint16_t)param1, param2);
100100
break;
101101

102+
case HC_SET_IRQLINE:
103+
/* param1: vmid */
104+
ret = hcall_set_irqline(vm, (uint16_t)param1,
105+
(struct acrn_irqline_ops *)&param2);
106+
break;
107+
102108
case HC_INJECT_MSI:
103109
/* param1: vmid */
104110
ret = hcall_inject_msi(vm, (uint16_t)param1, param2);

hypervisor/common/hypercall.c

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,19 @@ int32_t hcall_get_api_version(struct vm *vm, uint64_t param)
7171
*@pre Pointer vm shall point to VM0
7272
*/
7373
static void
74-
handle_vpic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
74+
handle_vpic_irqline(struct vm *vm, uint32_t irq, uint32_t operation)
7575
{
76-
77-
switch (mode) {
78-
case IRQ_ASSERT:
76+
switch (operation) {
77+
case GSI_SET_HIGH:
7978
vpic_assert_irq(vm, irq);
8079
break;
81-
case IRQ_DEASSERT:
80+
case GSI_SET_LOW:
8281
vpic_deassert_irq(vm, irq);
8382
break;
84-
case IRQ_PULSE:
83+
case GSI_RAISING_PULSE:
8584
vpic_pulse_irq(vm, irq);
8685
default:
8786
/*
88-
* In this switch statement, mode shall either be IRQ_ASSERT or
89-
* IRQ_DEASSERT or IRQ_PULSE.
9087
* Gracefully return if prior case clauses have not been met.
9188
*/
9289
break;
@@ -97,22 +94,20 @@ handle_vpic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
9794
*@pre Pointer vm shall point to VM0
9895
*/
9996
static void
100-
handle_vioapic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
97+
handle_vioapic_irqline(struct vm *vm, uint32_t irq, uint32_t operation)
10198
{
102-
switch (mode) {
103-
case IRQ_ASSERT:
99+
switch (operation) {
100+
case GSI_SET_HIGH:
104101
vioapic_assert_irq(vm, irq);
105102
break;
106-
case IRQ_DEASSERT:
103+
case GSI_SET_LOW:
107104
vioapic_deassert_irq(vm, irq);
108105
break;
109-
case IRQ_PULSE:
106+
case GSI_RAISING_PULSE:
110107
vioapic_pulse_irq(vm, irq);
111108
break;
112109
default:
113110
/*
114-
* In this switch statement, mode shall either be IRQ_ASSERT or
115-
* IRQ_DEASSERT or IRQ_PULSE.
116111
* Gracefully return if prior case clauses have not been met.
117112
*/
118113
break;
@@ -124,7 +119,7 @@ handle_vioapic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
124119
*/
125120
static int32_t
126121
handle_virt_irqline(struct vm *vm, uint16_t target_vmid,
127-
struct acrn_irqline *param, enum irq_mode mode)
122+
struct acrn_irqline *param, uint32_t operation)
128123
{
129124
int32_t ret = 0;
130125
uint32_t intr_type;
@@ -152,19 +147,19 @@ handle_virt_irqline(struct vm *vm, uint16_t target_vmid,
152147
switch (intr_type) {
153148
case ACRN_INTR_TYPE_ISA:
154149
/* Call vpic for pic injection */
155-
handle_vpic_irqline(target_vm, param->pic_irq, mode);
150+
handle_vpic_irqline(target_vm, param->pic_irq, operation);
156151

157152
/* call vioapic for ioapic injection if ioapic_irq != ~0U*/
158153
if (param->ioapic_irq != (~0U)) {
159154
/* handle IOAPIC irqline */
160155
handle_vioapic_irqline(target_vm,
161-
param->ioapic_irq, mode);
156+
param->ioapic_irq, operation);
162157
}
163158
break;
164159
case ACRN_INTR_TYPE_IOAPIC:
165160
/* handle IOAPIC irqline */
166161
handle_vioapic_irqline(target_vm,
167-
param->ioapic_irq, mode);
162+
param->ioapic_irq, operation);
168163
break;
169164
default:
170165
dev_dbg(ACRN_DBG_HYCALL, "vINTR inject failed. type=%d",
@@ -309,7 +304,7 @@ int32_t hcall_assert_irqline(struct vm *vm, uint16_t vmid, uint64_t param)
309304
pr_err("%s: Unable copy param to vm\n", __func__);
310305
return -1;
311306
}
312-
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_ASSERT);
307+
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_SET_HIGH);
313308

314309
return ret;
315310
}
@@ -326,7 +321,7 @@ int32_t hcall_deassert_irqline(struct vm *vm, uint16_t vmid, uint64_t param)
326321
pr_err("%s: Unable copy param to vm\n", __func__);
327322
return -1;
328323
}
329-
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_DEASSERT);
324+
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_SET_LOW);
330325

331326
return ret;
332327
}
@@ -343,11 +338,38 @@ int32_t hcall_pulse_irqline(struct vm *vm, uint16_t vmid, uint64_t param)
343338
pr_err("%s: Unable copy param to vm\n", __func__);
344339
return -1;
345340
}
346-
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_PULSE);
341+
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_RAISING_PULSE);
347342

348343
return ret;
349344
}
350345

346+
/**
347+
*@pre Pointer vm shall point to VM0
348+
*/
349+
int32_t hcall_set_irqline(struct vm *vm, uint16_t vmid,
350+
struct acrn_irqline_ops *ops)
351+
{
352+
struct vm *target_vm = get_vm_from_vmid(vmid);
353+
354+
if (target_vm == NULL) {
355+
return -EINVAL;
356+
}
357+
358+
if (ops->nr_gsi >= vioapic_pincount(vm)) {
359+
return -EINVAL;
360+
}
361+
362+
if (ops->nr_gsi < vpic_pincount()) {
363+
/* Call vpic for pic injection */
364+
handle_vpic_irqline(target_vm, ops->nr_gsi, ops->op);
365+
}
366+
367+
/* handle IOAPIC irqline */
368+
handle_vioapic_irqline(target_vm, ops->nr_gsi, ops->op);
369+
370+
return 0;
371+
}
372+
351373
/**
352374
*@pre Pointer vm shall point to VM0
353375
*/

hypervisor/include/common/hypercall.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ int32_t hcall_deassert_irqline(struct vm *vm, uint16_t vmid, uint64_t param);
184184
*/
185185
int32_t hcall_pulse_irqline(struct vm *vm, uint16_t vmid, uint64_t param);
186186

187+
188+
/**
189+
* @brief set or clear IRQ line
190+
*
191+
* Set or clear a virtual IRQ line for a VM, which could be from ISA
192+
* or IOAPIC, normally it triggers an edge IRQ.
193+
* The function will return -1 if the target VM does not exist.
194+
*
195+
* @param vm Pointer to VM data structure
196+
* @param vmid ID of the VM
197+
* @irq_req: request command for IRQ set or clear
198+
*
199+
* @pre Pointer vm shall point to VM0
200+
* @return 0 on success, non-zero on error.
201+
*/
202+
int32_t hcall_set_irqline(struct vm *vm, uint16_t vmid,
203+
struct acrn_irqline_ops *ops);
187204
/**
188205
* @brief inject MSI interrupt
189206
*

hypervisor/include/common/irq.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111
#define IRQF_LEVEL (1U << 1U) /* 1: level trigger; 0: edge trigger */
1212
#define IRQF_PT (1U << 2U) /* 1: for passthrough dev */
1313

14-
enum irq_mode {
15-
IRQ_PULSE,
16-
IRQ_ASSERT,
17-
IRQ_DEASSERT,
18-
};
1914

2015
typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
2116

hypervisor/include/public/acrn_common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,22 @@ struct acrn_set_ioreq_buffer {
264264
/** Interrupt type for acrn_irqline: inject interrupt to both PIC and IOAPIC */
265265
#define ACRN_INTR_TYPE_IOAPIC 1U
266266

267+
/** Operation types for setting IRQ line */
268+
#define GSI_SET_HIGH 0U
269+
#define GSI_SET_LOW 1U
270+
#define GSI_RAISING_PULSE 2U
271+
#define GSI_FALLING_PULSE 3U
272+
273+
/**
274+
* @brief Info to Set/Clear/Pulse a virtual IRQ line for a VM
275+
*
276+
* the parameter for HC_SET_IRQLINE hypercall
277+
*/
278+
struct acrn_irqline_ops {
279+
uint32_t nr_gsi;
280+
uint32_t op;
281+
} __aligned(8);
282+
267283
/**
268284
* @brief Info to assert/deassert/pulse a virtual IRQ line for a VM
269285
*

hypervisor/include/public/acrn_hv_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#define HC_PULSE_IRQLINE BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x02UL)
4646
#define HC_INJECT_MSI BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x03UL)
4747
#define HC_VM_INTR_MONITOR BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x04UL)
48+
#define HC_SET_IRQLINE BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x05UL)
4849

4950
/* DM ioreq management */
5051
#define HC_ID_IOREQ_BASE 0x30UL

0 commit comments

Comments
 (0)