mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 21:47:22 +00:00
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>
This commit is contained in:
parent
05ad6d6628
commit
dd6a5fbe95
@ -99,6 +99,12 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
|
|||||||
ret = hcall_pulse_irqline(vm, (uint16_t)param1, param2);
|
ret = hcall_pulse_irqline(vm, (uint16_t)param1, param2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HC_SET_IRQLINE:
|
||||||
|
/* param1: vmid */
|
||||||
|
ret = hcall_set_irqline(vm, (uint16_t)param1,
|
||||||
|
(struct acrn_irqline_ops *)¶m2);
|
||||||
|
break;
|
||||||
|
|
||||||
case HC_INJECT_MSI:
|
case HC_INJECT_MSI:
|
||||||
/* param1: vmid */
|
/* param1: vmid */
|
||||||
ret = hcall_inject_msi(vm, (uint16_t)param1, param2);
|
ret = hcall_inject_msi(vm, (uint16_t)param1, param2);
|
||||||
|
@ -71,22 +71,19 @@ int32_t hcall_get_api_version(struct vm *vm, uint64_t param)
|
|||||||
*@pre Pointer vm shall point to VM0
|
*@pre Pointer vm shall point to VM0
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_vpic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
|
handle_vpic_irqline(struct vm *vm, uint32_t irq, uint32_t operation)
|
||||||
{
|
{
|
||||||
|
switch (operation) {
|
||||||
switch (mode) {
|
case GSI_SET_HIGH:
|
||||||
case IRQ_ASSERT:
|
|
||||||
vpic_assert_irq(vm, irq);
|
vpic_assert_irq(vm, irq);
|
||||||
break;
|
break;
|
||||||
case IRQ_DEASSERT:
|
case GSI_SET_LOW:
|
||||||
vpic_deassert_irq(vm, irq);
|
vpic_deassert_irq(vm, irq);
|
||||||
break;
|
break;
|
||||||
case IRQ_PULSE:
|
case GSI_RAISING_PULSE:
|
||||||
vpic_pulse_irq(vm, irq);
|
vpic_pulse_irq(vm, irq);
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* In this switch statement, mode shall either be IRQ_ASSERT or
|
|
||||||
* IRQ_DEASSERT or IRQ_PULSE.
|
|
||||||
* Gracefully return if prior case clauses have not been met.
|
* Gracefully return if prior case clauses have not been met.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
@ -97,22 +94,20 @@ handle_vpic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
|
|||||||
*@pre Pointer vm shall point to VM0
|
*@pre Pointer vm shall point to VM0
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_vioapic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
|
handle_vioapic_irqline(struct vm *vm, uint32_t irq, uint32_t operation)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (operation) {
|
||||||
case IRQ_ASSERT:
|
case GSI_SET_HIGH:
|
||||||
vioapic_assert_irq(vm, irq);
|
vioapic_assert_irq(vm, irq);
|
||||||
break;
|
break;
|
||||||
case IRQ_DEASSERT:
|
case GSI_SET_LOW:
|
||||||
vioapic_deassert_irq(vm, irq);
|
vioapic_deassert_irq(vm, irq);
|
||||||
break;
|
break;
|
||||||
case IRQ_PULSE:
|
case GSI_RAISING_PULSE:
|
||||||
vioapic_pulse_irq(vm, irq);
|
vioapic_pulse_irq(vm, irq);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* In this switch statement, mode shall either be IRQ_ASSERT or
|
|
||||||
* IRQ_DEASSERT or IRQ_PULSE.
|
|
||||||
* Gracefully return if prior case clauses have not been met.
|
* Gracefully return if prior case clauses have not been met.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
@ -124,7 +119,7 @@ handle_vioapic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)
|
|||||||
*/
|
*/
|
||||||
static int32_t
|
static int32_t
|
||||||
handle_virt_irqline(struct vm *vm, uint16_t target_vmid,
|
handle_virt_irqline(struct vm *vm, uint16_t target_vmid,
|
||||||
struct acrn_irqline *param, enum irq_mode mode)
|
struct acrn_irqline *param, uint32_t operation)
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
uint32_t intr_type;
|
uint32_t intr_type;
|
||||||
@ -152,19 +147,19 @@ handle_virt_irqline(struct vm *vm, uint16_t target_vmid,
|
|||||||
switch (intr_type) {
|
switch (intr_type) {
|
||||||
case ACRN_INTR_TYPE_ISA:
|
case ACRN_INTR_TYPE_ISA:
|
||||||
/* Call vpic for pic injection */
|
/* Call vpic for pic injection */
|
||||||
handle_vpic_irqline(target_vm, param->pic_irq, mode);
|
handle_vpic_irqline(target_vm, param->pic_irq, operation);
|
||||||
|
|
||||||
/* call vioapic for ioapic injection if ioapic_irq != ~0U*/
|
/* call vioapic for ioapic injection if ioapic_irq != ~0U*/
|
||||||
if (param->ioapic_irq != (~0U)) {
|
if (param->ioapic_irq != (~0U)) {
|
||||||
/* handle IOAPIC irqline */
|
/* handle IOAPIC irqline */
|
||||||
handle_vioapic_irqline(target_vm,
|
handle_vioapic_irqline(target_vm,
|
||||||
param->ioapic_irq, mode);
|
param->ioapic_irq, operation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACRN_INTR_TYPE_IOAPIC:
|
case ACRN_INTR_TYPE_IOAPIC:
|
||||||
/* handle IOAPIC irqline */
|
/* handle IOAPIC irqline */
|
||||||
handle_vioapic_irqline(target_vm,
|
handle_vioapic_irqline(target_vm,
|
||||||
param->ioapic_irq, mode);
|
param->ioapic_irq, operation);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_dbg(ACRN_DBG_HYCALL, "vINTR inject failed. type=%d",
|
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)
|
|||||||
pr_err("%s: Unable copy param to vm\n", __func__);
|
pr_err("%s: Unable copy param to vm\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_ASSERT);
|
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_SET_HIGH);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -326,7 +321,7 @@ int32_t hcall_deassert_irqline(struct vm *vm, uint16_t vmid, uint64_t param)
|
|||||||
pr_err("%s: Unable copy param to vm\n", __func__);
|
pr_err("%s: Unable copy param to vm\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_DEASSERT);
|
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_SET_LOW);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -343,11 +338,38 @@ int32_t hcall_pulse_irqline(struct vm *vm, uint16_t vmid, uint64_t param)
|
|||||||
pr_err("%s: Unable copy param to vm\n", __func__);
|
pr_err("%s: Unable copy param to vm\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = handle_virt_irqline(vm, vmid, &irqline, IRQ_PULSE);
|
ret = handle_virt_irqline(vm, vmid, &irqline, GSI_RAISING_PULSE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@pre Pointer vm shall point to VM0
|
||||||
|
*/
|
||||||
|
int32_t hcall_set_irqline(struct vm *vm, uint16_t vmid,
|
||||||
|
struct acrn_irqline_ops *ops)
|
||||||
|
{
|
||||||
|
struct vm *target_vm = get_vm_from_vmid(vmid);
|
||||||
|
|
||||||
|
if (target_vm == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ops->nr_gsi >= vioapic_pincount(vm)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ops->nr_gsi < vpic_pincount()) {
|
||||||
|
/* Call vpic for pic injection */
|
||||||
|
handle_vpic_irqline(target_vm, ops->nr_gsi, ops->op);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle IOAPIC irqline */
|
||||||
|
handle_vioapic_irqline(target_vm, ops->nr_gsi, ops->op);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@pre Pointer vm shall point to VM0
|
*@pre Pointer vm shall point to VM0
|
||||||
*/
|
*/
|
||||||
|
@ -184,6 +184,23 @@ int32_t hcall_deassert_irqline(struct vm *vm, uint16_t vmid, uint64_t param);
|
|||||||
*/
|
*/
|
||||||
int32_t hcall_pulse_irqline(struct vm *vm, uint16_t vmid, uint64_t param);
|
int32_t hcall_pulse_irqline(struct vm *vm, uint16_t vmid, uint64_t param);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief set or clear IRQ line
|
||||||
|
*
|
||||||
|
* Set or clear a virtual IRQ line for a VM, which could be from ISA
|
||||||
|
* or IOAPIC, normally it triggers an edge IRQ.
|
||||||
|
* The function will return -1 if the target VM does not exist.
|
||||||
|
*
|
||||||
|
* @param vm Pointer to VM data structure
|
||||||
|
* @param vmid ID of the VM
|
||||||
|
* @irq_req: request command for IRQ set or clear
|
||||||
|
*
|
||||||
|
* @pre Pointer vm shall point to VM0
|
||||||
|
* @return 0 on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int32_t hcall_set_irqline(struct vm *vm, uint16_t vmid,
|
||||||
|
struct acrn_irqline_ops *ops);
|
||||||
/**
|
/**
|
||||||
* @brief inject MSI interrupt
|
* @brief inject MSI interrupt
|
||||||
*
|
*
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
#define IRQF_LEVEL (1U << 1U) /* 1: level trigger; 0: edge trigger */
|
#define IRQF_LEVEL (1U << 1U) /* 1: level trigger; 0: edge trigger */
|
||||||
#define IRQF_PT (1U << 2U) /* 1: for passthrough dev */
|
#define IRQF_PT (1U << 2U) /* 1: for passthrough dev */
|
||||||
|
|
||||||
enum irq_mode {
|
|
||||||
IRQ_PULSE,
|
|
||||||
IRQ_ASSERT,
|
|
||||||
IRQ_DEASSERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
|
typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
|
||||||
|
|
||||||
|
@ -264,6 +264,22 @@ struct acrn_set_ioreq_buffer {
|
|||||||
/** Interrupt type for acrn_irqline: inject interrupt to both PIC and IOAPIC */
|
/** Interrupt type for acrn_irqline: inject interrupt to both PIC and IOAPIC */
|
||||||
#define ACRN_INTR_TYPE_IOAPIC 1U
|
#define ACRN_INTR_TYPE_IOAPIC 1U
|
||||||
|
|
||||||
|
/** Operation types for setting IRQ line */
|
||||||
|
#define GSI_SET_HIGH 0U
|
||||||
|
#define GSI_SET_LOW 1U
|
||||||
|
#define GSI_RAISING_PULSE 2U
|
||||||
|
#define GSI_FALLING_PULSE 3U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Info to Set/Clear/Pulse a virtual IRQ line for a VM
|
||||||
|
*
|
||||||
|
* the parameter for HC_SET_IRQLINE hypercall
|
||||||
|
*/
|
||||||
|
struct acrn_irqline_ops {
|
||||||
|
uint32_t nr_gsi;
|
||||||
|
uint32_t op;
|
||||||
|
} __aligned(8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Info to assert/deassert/pulse a virtual IRQ line for a VM
|
* @brief Info to assert/deassert/pulse a virtual IRQ line for a VM
|
||||||
*
|
*
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#define HC_PULSE_IRQLINE BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x02UL)
|
#define HC_PULSE_IRQLINE BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x02UL)
|
||||||
#define HC_INJECT_MSI BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x03UL)
|
#define HC_INJECT_MSI BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x03UL)
|
||||||
#define HC_VM_INTR_MONITOR BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x04UL)
|
#define HC_VM_INTR_MONITOR BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x04UL)
|
||||||
|
#define HC_SET_IRQLINE BASE_HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x05UL)
|
||||||
|
|
||||||
/* DM ioreq management */
|
/* DM ioreq management */
|
||||||
#define HC_ID_IOREQ_BASE 0x30UL
|
#define HC_ID_IOREQ_BASE 0x30UL
|
||||||
|
Loading…
Reference in New Issue
Block a user