mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-26 15:31:35 +00:00
hv: coding style: refine functions under dm/ to one exit point
Refine vioapic_indirect_write and vmsix_table_rw to one exit point. Tracked-On: #861 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
087fbfe136
commit
1bc90293be
@ -275,9 +275,7 @@ static inline bool vioapic_need_intr(const struct acrn_vioapic *vioapic, uint16_
|
|||||||
* Due to the race between vcpus, ensure to do spinlock_obtain(&(vioapic->mtx))
|
* Due to the race between vcpus, ensure to do spinlock_obtain(&(vioapic->mtx))
|
||||||
* & spinlock_release(&(vioapic->mtx)) by caller.
|
* & spinlock_release(&(vioapic->mtx)) by caller.
|
||||||
*/
|
*/
|
||||||
static void
|
static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr, uint32_t data)
|
||||||
vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr,
|
|
||||||
uint32_t data)
|
|
||||||
{
|
{
|
||||||
union ioapic_rte last, new;
|
union ioapic_rte last, new;
|
||||||
uint64_t changed;
|
uint64_t changed;
|
||||||
@ -304,8 +302,8 @@ vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* redirection table entries */
|
/* redirection table entries */
|
||||||
if ((regnum >= IOAPIC_REDTBL) &&
|
if ((regnum >= IOAPIC_REDTBL) && (regnum < (IOAPIC_REDTBL + (pincount * 2U)))) {
|
||||||
(regnum < (IOAPIC_REDTBL + (pincount * 2U)))) {
|
bool wire_mode_valid = true;
|
||||||
uint32_t addr_offset = regnum - IOAPIC_REDTBL;
|
uint32_t addr_offset = regnum - IOAPIC_REDTBL;
|
||||||
uint32_t rte_offset = addr_offset >> 1U;
|
uint32_t rte_offset = addr_offset >> 1U;
|
||||||
pin = rte_offset;
|
pin = rte_offset;
|
||||||
@ -334,73 +332,63 @@ vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr,
|
|||||||
if ((pin == 0U) && ((changed & IOAPIC_RTE_INTMASK) != 0UL)) {
|
if ((pin == 0U) && ((changed & IOAPIC_RTE_INTMASK) != 0UL)) {
|
||||||
/* mask -> umask */
|
/* mask -> umask */
|
||||||
if ((last.full & IOAPIC_RTE_INTMASK) != 0UL) {
|
if ((last.full & IOAPIC_RTE_INTMASK) != 0UL) {
|
||||||
if ((vioapic->vm->wire_mode ==
|
if ((vioapic->vm->wire_mode == VPIC_WIRE_NULL) ||
|
||||||
VPIC_WIRE_NULL) ||
|
(vioapic->vm->wire_mode == VPIC_WIRE_INTR)) {
|
||||||
(vioapic->vm->wire_mode ==
|
vioapic->vm->wire_mode = VPIC_WIRE_IOAPIC;
|
||||||
VPIC_WIRE_INTR)) {
|
dev_dbg(ACRN_DBG_IOAPIC, "vpic wire mode -> IOAPIC");
|
||||||
vioapic->vm->wire_mode =
|
|
||||||
VPIC_WIRE_IOAPIC;
|
|
||||||
dev_dbg(ACRN_DBG_IOAPIC,
|
|
||||||
"vpic wire mode -> IOAPIC");
|
|
||||||
} else {
|
} else {
|
||||||
pr_err("WARNING: invalid vpic wire mode change");
|
pr_err("WARNING: invalid vpic wire mode change");
|
||||||
return;
|
wire_mode_valid = false;
|
||||||
}
|
}
|
||||||
/* unmask -> mask */
|
/* unmask -> mask */
|
||||||
} else {
|
} else {
|
||||||
if (vioapic->vm->wire_mode ==
|
if (vioapic->vm->wire_mode == VPIC_WIRE_IOAPIC) {
|
||||||
VPIC_WIRE_IOAPIC) {
|
vioapic->vm->wire_mode = VPIC_WIRE_INTR;
|
||||||
vioapic->vm->wire_mode =
|
dev_dbg(ACRN_DBG_IOAPIC, "vpic wire mode -> INTR");
|
||||||
VPIC_WIRE_INTR;
|
|
||||||
dev_dbg(ACRN_DBG_IOAPIC,
|
|
||||||
"vpic wire mode -> INTR");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vioapic->rtbl[pin] = new;
|
|
||||||
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: redir table entry %#lx",
|
|
||||||
pin, vioapic->rtbl[pin].full);
|
|
||||||
/*
|
|
||||||
* If "Trigger Mode" or "Delivery Mode" or "Vector"
|
|
||||||
* in the redirection table entry have changed then
|
|
||||||
* rendezvous all the vcpus to update their vlapic
|
|
||||||
* trigger-mode registers.
|
|
||||||
*/
|
|
||||||
if ((changed & NEED_TMR_UPDATE) != 0UL) {
|
|
||||||
uint16_t i;
|
|
||||||
struct acrn_vcpu *vcpu;
|
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_IOAPIC,
|
if (wire_mode_valid) {
|
||||||
"ioapic pin%hhu: recalculate vlapic trigger-mode reg",
|
vioapic->rtbl[pin] = new;
|
||||||
pin);
|
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: redir table entry %#lx",
|
||||||
|
pin, vioapic->rtbl[pin].full);
|
||||||
|
/*
|
||||||
|
* If "Trigger Mode" or "Delivery Mode" or "Vector"
|
||||||
|
* in the redirection table entry have changed then
|
||||||
|
* rendezvous all the vcpus to update their vlapic
|
||||||
|
* trigger-mode registers.
|
||||||
|
*/
|
||||||
|
if ((changed & NEED_TMR_UPDATE) != 0UL) {
|
||||||
|
uint16_t i;
|
||||||
|
struct acrn_vcpu *vcpu;
|
||||||
|
|
||||||
foreach_vcpu(i, vioapic->vm, vcpu) {
|
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: recalculate vlapic trigger-mode reg", pin);
|
||||||
vcpu_make_request(vcpu, ACRN_REQUEST_TMR_UPDATE);
|
|
||||||
|
foreach_vcpu(i, vioapic->vm, vcpu) {
|
||||||
|
vcpu_make_request(vcpu, ACRN_REQUEST_TMR_UPDATE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an interrupt if the following conditions are met:
|
* Generate an interrupt if the following conditions are met:
|
||||||
* - pin is not masked
|
* - pin is not masked
|
||||||
* - previous interrupt has been EOIed
|
* - previous interrupt has been EOIed
|
||||||
* - pin level is asserted
|
* - pin level is asserted
|
||||||
*/
|
*/
|
||||||
if (((vioapic->rtbl[pin].full & IOAPIC_RTE_INTMASK) ==
|
if (((vioapic->rtbl[pin].full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMCLR) &&
|
||||||
IOAPIC_RTE_INTMCLR) &&
|
((vioapic->rtbl[pin].full & IOAPIC_RTE_REM_IRR) == 0UL) &&
|
||||||
((vioapic->rtbl[pin].full & IOAPIC_RTE_REM_IRR) == 0UL)
|
vioapic_need_intr(vioapic, (uint16_t)pin)) {
|
||||||
&& vioapic_need_intr(vioapic, (uint16_t)pin)) {
|
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: asserted at rtbl write", pin);
|
||||||
dev_dbg(ACRN_DBG_IOAPIC,
|
vioapic_generate_intr(vioapic, pin);
|
||||||
"ioapic pin%hhu: asserted at rtbl write", pin);
|
}
|
||||||
vioapic_generate_intr(vioapic, pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remap for ptdev */
|
/* remap for ptdev */
|
||||||
if (((new.full & IOAPIC_RTE_INTMASK) == 0UL) ||
|
if (((new.full & IOAPIC_RTE_INTMASK) == 0UL) || ((last.full & IOAPIC_RTE_INTMASK) == 0UL)) {
|
||||||
((last.full & IOAPIC_RTE_INTMASK) == 0UL)) {
|
/* VM enable intr */
|
||||||
/* VM enable intr */
|
/* NOTE: only support max 256 pin */
|
||||||
/* NOTE: only support max 256 pin */
|
(void)ptirq_intx_pin_remap(vioapic->vm, (uint8_t)pin, PTDEV_VPIN_IOAPIC);
|
||||||
(void)ptirq_intx_pin_remap(vioapic->vm,
|
}
|
||||||
(uint8_t)pin, PTDEV_VPIN_IOAPIC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,57 +208,62 @@ static void vmsix_table_rw(struct pci_vdev *vdev, struct mmio_request *mmio, uin
|
|||||||
/* Find out which entry it's accessing */
|
/* Find out which entry it's accessing */
|
||||||
table_offset = offset - vdev->msix.table_offset;
|
table_offset = offset - vdev->msix.table_offset;
|
||||||
index = table_offset / MSIX_TABLE_ENTRY_SIZE;
|
index = table_offset / MSIX_TABLE_ENTRY_SIZE;
|
||||||
if (index >= vdev->msix.table_count) {
|
|
||||||
pr_err("%s, invalid arguments %llx - %llx", __func__, mmio->value, mmio->address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = &vdev->msix.tables[index];
|
if (index < vdev->msix.table_count) {
|
||||||
entry_offset = table_offset % MSIX_TABLE_ENTRY_SIZE;
|
entry = &vdev->msix.tables[index];
|
||||||
|
entry_offset = table_offset % MSIX_TABLE_ENTRY_SIZE;
|
||||||
|
|
||||||
if (mmio->direction == REQUEST_READ) {
|
if (mmio->direction == REQUEST_READ) {
|
||||||
(void)memcpy_s(&mmio->value, (size_t)mmio->size, (void *)entry + entry_offset, (size_t)mmio->size);
|
(void)memcpy_s(&mmio->value, (size_t)mmio->size,
|
||||||
} else {
|
(void *)entry + entry_offset, (size_t)mmio->size);
|
||||||
/* Only DWORD and QWORD are permitted */
|
|
||||||
if ((mmio->size != 4U) && (mmio->size != 8U)) {
|
|
||||||
pr_err("%s, Only DWORD and QWORD are permitted", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save for comparison */
|
|
||||||
vector_control = entry->vector_control;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Writing different value to Message Data/Addr?
|
|
||||||
* PCI Spec: Software is permitted to fill in MSI-X Table entry DWORD fields individually
|
|
||||||
* with DWORD writes, or software in certain cases is permitted to fill in appropriate pairs
|
|
||||||
* of DWORDs with a single QWORD write
|
|
||||||
*/
|
|
||||||
if (entry_offset < offsetof(struct msix_table_entry, data)) {
|
|
||||||
uint64_t qword_mask = ~0UL;
|
|
||||||
if (mmio->size == 4U) {
|
|
||||||
qword_mask = (entry_offset == 0U) ? 0x00000000FFFFFFFFUL : 0xFFFFFFFF00000000UL;
|
|
||||||
}
|
|
||||||
message_changed = ((entry->addr & qword_mask) != (mmio->value & qword_mask));
|
|
||||||
} else {
|
} else {
|
||||||
if (entry_offset == offsetof(struct msix_table_entry, data)) {
|
/* Only DWORD and QWORD are permitted */
|
||||||
message_changed = (entry->data != (uint32_t)mmio->value);
|
if ((mmio->size == 4U) || (mmio->size == 8U)) {
|
||||||
}
|
/* Save for comparison */
|
||||||
}
|
vector_control = entry->vector_control;
|
||||||
|
|
||||||
/* Write to pci_vdev */
|
/*
|
||||||
(void)memcpy_s((void *)entry + entry_offset, (size_t)mmio->size, &mmio->value, (size_t)mmio->size);
|
* Writing different value to Message Data/Addr?
|
||||||
|
* PCI Spec: Software is permitted to fill in MSI-X Table entry DWORD fields
|
||||||
/* If MSI-X hasn't been enabled, do nothing */
|
* individually with DWORD writes, or software in certain cases is permitted
|
||||||
if ((pci_vdev_read_cfg(vdev, vdev->msix.capoff + PCIR_MSIX_CTRL, 2U) & PCIM_MSIXCTRL_MSIX_ENABLE)
|
* to fill in appropriate pairs of DWORDs with a single QWORD write
|
||||||
== PCIM_MSIXCTRL_MSIX_ENABLE) {
|
*/
|
||||||
|
if (entry_offset < offsetof(struct msix_table_entry, data)) {
|
||||||
if ((((entry->vector_control ^ vector_control) & PCIM_MSIX_VCTRL_MASK) != 0U) || message_changed) {
|
uint64_t qword_mask = ~0UL;
|
||||||
unmasked = ((entry->vector_control & PCIM_MSIX_VCTRL_MASK) == 0U);
|
if (mmio->size == 4U) {
|
||||||
(void)vmsix_remap_one_entry(vdev, index, unmasked);
|
qword_mask = (entry_offset == 0U) ?
|
||||||
|
0x00000000FFFFFFFFUL : 0xFFFFFFFF00000000UL;
|
||||||
|
}
|
||||||
|
message_changed = ((entry->addr & qword_mask) != (mmio->value & qword_mask));
|
||||||
|
} else {
|
||||||
|
if (entry_offset == offsetof(struct msix_table_entry, data)) {
|
||||||
|
message_changed = (entry->data != (uint32_t)mmio->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write to pci_vdev */
|
||||||
|
(void)memcpy_s((void *)entry + entry_offset, (size_t)mmio->size,
|
||||||
|
&mmio->value, (size_t)mmio->size);
|
||||||
|
|
||||||
|
/* If MSI-X hasn't been enabled, do nothing */
|
||||||
|
if ((pci_vdev_read_cfg(vdev, vdev->msix.capoff + PCIR_MSIX_CTRL, 2U)
|
||||||
|
& PCIM_MSIXCTRL_MSIX_ENABLE) == PCIM_MSIXCTRL_MSIX_ENABLE) {
|
||||||
|
|
||||||
|
if ((((entry->vector_control ^ vector_control) & PCIM_MSIX_VCTRL_MASK) != 0U)
|
||||||
|
|| message_changed) {
|
||||||
|
unmasked = ((entry->vector_control & PCIM_MSIX_VCTRL_MASK) == 0U);
|
||||||
|
(void)vmsix_remap_one_entry(vdev, index, unmasked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_err("%s, Only DWORD and QWORD are permitted", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pr_err("%s, invalid arguments %llx - %llx", __func__, mmio->value, mmio->address);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data)
|
static int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data)
|
||||||
|
Loading…
Reference in New Issue
Block a user