diff --git a/hypervisor/arch/x86/assign.c b/hypervisor/arch/x86/assign.c index c5edf2b36..4f885b4cb 100644 --- a/hypervisor/arch/x86/assign.c +++ b/hypervisor/arch/x86/assign.c @@ -77,32 +77,33 @@ static void ptirq_build_physical_msi(struct acrn_vm *vm, struct ptirq_msi_info * bool phys; /* get physical destination cpu mask */ - dest = (uint32_t)(info->vmsi_addr & MSI_ADDR_DEST) >> MSI_ADDR_DEST_SHIFT; - phys = ((info->vmsi_addr & MSI_ADDR_LOG) != MSI_ADDR_LOG); + dest = info->vmsi_addr.bits.dest_field; + phys = (info->vmsi_addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS); vlapic_calcdest(vm, &vdmask, dest, phys, false); pdmask = vcpumask2pcpumask(vm, vdmask); /* get physical delivery mode */ - delmode = info->vmsi_data & APIC_DELMODE_MASK; - if ((delmode != APIC_DELMODE_FIXED) && (delmode != APIC_DELMODE_LOWPRIO)) { - delmode = APIC_DELMODE_LOWPRIO; + delmode = info->vmsi_data.bits.delivery_mode; + if ((delmode != MSI_DATA_DELMODE_FIXED) && (delmode != MSI_DATA_DELMODE_LOPRI)) { + delmode = MSI_DATA_DELMODE_LOPRI; } /* update physical delivery mode & vector */ info->pmsi_data = info->vmsi_data; - info->pmsi_data &= ~0x7FFU; - info->pmsi_data |= delmode | vector; + info->pmsi_data.bits.delivery_mode = delmode; + info->pmsi_data.bits.vector = vector; dest_mask = calculate_logical_dest_mask(pdmask); /* update physical dest mode & dest field */ info->pmsi_addr = info->vmsi_addr; - info->pmsi_addr &= ~0xFF00CU; - info->pmsi_addr |= (dest_mask << MSI_ADDR_DEST_SHIFT) | MSI_ADDR_RH | MSI_ADDR_LOG; + info->pmsi_addr.bits.dest_mode = MSI_ADDR_DESTMODE_LOGICAL; + info->pmsi_addr.bits.rh = MSI_ADDR_RH; + info->pmsi_addr.bits.dest_field = dest_mask; dev_dbg(ACRN_DBG_IRQ, "MSI addr:data = 0x%llx:%x(V) -> 0x%llx:%x(P)", - info->vmsi_addr, info->vmsi_data, - info->pmsi_addr, info->pmsi_data); + info->vmsi_addr.full, info->vmsi_data.full, + info->pmsi_addr.full, info->pmsi_data.full); } static union ioapic_rte @@ -442,14 +443,14 @@ void ptirq_softirq(uint16_t pcpu_id) } else { if (msi != NULL) { /* TODO: msi destmode check required */ - (void)vlapic_intr_msi(vm, msi->vmsi_addr, msi->vmsi_data); + (void)vlapic_intr_msi(vm, msi->vmsi_addr.full, msi->vmsi_data.full); dev_dbg(ACRN_DBG_PTIRQ, "dev-assign: irq=0x%x MSI VR: 0x%x-0x%x", entry->allocated_pirq, - msi->vmsi_data & 0xFFU, + msi->vmsi_data.bits.vector, irq_to_vector(entry->allocated_pirq)); dev_dbg(ACRN_DBG_PTIRQ, " vmsi_addr: 0x%llx vmsi_data: 0x%x", - msi->vmsi_addr, - msi->vmsi_data); + msi->vmsi_addr.full, + msi->vmsi_data.full); } } } @@ -534,16 +535,16 @@ int32_t ptirq_msix_remap(struct acrn_vm *vm, uint16_t virt_bdf, spinlock_release(&ptdev_lock); if (entry != NULL) { - if (is_entry_active(entry) && (info->vmsi_data == 0U)) { + if (is_entry_active(entry) && (info->vmsi_data.full == 0U)) { /* handle destroy case */ - info->pmsi_data = 0U; + info->pmsi_data.full = 0U; } else { /* build physical config MSI, update to info->pmsi_xxx */ ptirq_build_physical_msi(vm, info, irq_to_vector(entry->allocated_pirq)); entry->msi = *info; dev_dbg(ACRN_DBG_IRQ, "PCI %x:%x.%x MSI VR[%d] 0x%x->0x%x assigned to vm%d", pci_bus(virt_bdf), pci_slot(virt_bdf), pci_func(virt_bdf), entry_nr, - info->vmsi_data & 0xFFU, irq_to_vector(entry->allocated_pirq), entry->vm->vm_id); + info->vmsi_data.bits.vector, irq_to_vector(entry->allocated_pirq), entry->vm->vm_id); } ret = 0; } diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index c08fa2399..3deef4925 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1940,10 +1940,14 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg) uint32_t dest; bool phys, rh; int32_t ret; + union msi_addr_reg address; + union msi_data_reg data; - dev_dbg(ACRN_DBG_LAPIC, "lapic MSI addr: %#lx msg: %#lx", addr, msg); + address.full = addr; + data.full = (uint32_t) msg; + dev_dbg(ACRN_DBG_LAPIC, "lapic MSI addr: %#lx msg: %#lx", address.full, data.full); - if ((addr & MSI_ADDR_MASK) == MSI_ADDR_BASE) { + if (address.bits.addr_base == MSI_ADDR_BASE) { /* * Extract the x86-specific fields from the MSI addr/msg * params according to the Intel Arch spec, Vol3 Ch 10. @@ -1955,12 +1959,12 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg) * the Redirection Hint and Destination Mode are '1' and * physical otherwise. */ - dest = (uint32_t)(addr >> 12U) & 0xffU; - phys = ((addr & MSI_ADDR_LOG) != MSI_ADDR_LOG); - rh = ((addr & MSI_ADDR_RH) == MSI_ADDR_RH); + dest = address.bits.dest_field; + phys = (address.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS); + rh = (address.bits.rh == MSI_ADDR_RH); - delmode = (uint32_t)msg & APIC_DELMODE_MASK; - vec = (uint32_t)msg & 0xffU; + delmode = data.bits.delivery_mode; + vec = data.bits.vector; dev_dbg(ACRN_DBG_LAPIC, "lapic MSI %s dest %#x, vec %u", phys ? "physical" : "logical", dest, vec); @@ -1968,7 +1972,7 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg) vlapic_deliver_intr(vm, LAPIC_TRIG_EDGE, dest, phys, delmode, vec, rh); ret = 0; } else { - dev_dbg(ACRN_DBG_LAPIC, "lapic MSI invalid addr %#lx", addr); + dev_dbg(ACRN_DBG_LAPIC, "lapic MSI invalid addr %#lx", address.full); ret = -1; } diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index 367930050..86ca79066 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -907,8 +907,8 @@ static void get_entry_info(const struct ptirq_remapping_info *entry, char *type, if (is_entry_active(entry)) { if (entry->intr_type == PTDEV_INTR_MSI) { (void)strncpy_s(type, 16U, "MSI", 16U); - *dest = (entry->msi.pmsi_addr & 0xFF000U) >> PAGE_SHIFT; - if ((entry->msi.pmsi_data & APIC_TRIGMOD_LEVEL) != 0U) { + *dest = entry->msi.pmsi_addr.bits.dest_field; + if (entry->msi.pmsi_data.bits.trigger_mode == MSI_DATA_TRGRMODE_LEVEL) { *lvl_tm = true; } else { *lvl_tm = false; diff --git a/hypervisor/dm/vpci/msi.c b/hypervisor/dm/vpci/msi.c index a40583337..1d713ddee 100644 --- a/hypervisor/dm/vpci/msi.c +++ b/hypervisor/dm/vpci/msi.c @@ -69,24 +69,24 @@ static int32_t vmsi_remap(const struct pci_vdev *vdev, bool enable) } info.is_msix = 0; - info.vmsi_addr = (uint64_t)addrlo | ((uint64_t)addrhi << 32U); + info.vmsi_addr.full = (uint64_t)addrlo | ((uint64_t)addrhi << 32U); /* MSI is being enabled or disabled */ if (enable) { - info.vmsi_data = msgdata; + info.vmsi_data.full = msgdata; } else { - info.vmsi_data = 0U; + info.vmsi_data.full = 0U; } ret = ptirq_msix_remap(vm, vdev->vbdf.value, 0U, &info); if (ret == 0) { /* Update MSI Capability structure to physical device */ - pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR, 0x4U, (uint32_t)info.pmsi_addr); + pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR, 0x4U, (uint32_t)info.pmsi_addr.full); if ((msgctrl & PCIM_MSICTRL_64BIT) != 0U) { - pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR_HIGH, 0x4U, (uint32_t)(info.pmsi_addr >> 32U)); - pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA_64BIT, 0x2U, (uint16_t)info.pmsi_data); + pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR_HIGH, 0x4U, (uint32_t)(info.pmsi_addr.full >> 32U)); + pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA_64BIT, 0x2U, (uint16_t)info.pmsi_data.full); } else { - pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA, 0x2U, (uint16_t)info.pmsi_data); + pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA, 0x2U, (uint16_t)info.pmsi_data.full); } /* If MSI Enable is being set, make sure INTxDIS bit is set */ diff --git a/hypervisor/dm/vpci/msix.c b/hypervisor/dm/vpci/msix.c index 269f4d9a9..2f1df43e0 100644 --- a/hypervisor/dm/vpci/msix.c +++ b/hypervisor/dm/vpci/msix.c @@ -56,8 +56,8 @@ static int32_t vmsix_remap_entry(const struct pci_vdev *vdev, uint32_t index, bo int32_t ret; info.is_msix = 1; - info.vmsi_addr = vdev->msix.tables[index].addr; - info.vmsi_data = (enable) ? vdev->msix.tables[index].data : 0U; + info.vmsi_addr.full = vdev->msix.tables[index].addr; + info.vmsi_data.full = (enable) ? vdev->msix.tables[index].data : 0U; ret = ptirq_msix_remap(vdev->vpci->vm, vdev->vbdf.value, (uint16_t)index, &info); if (ret == 0) { @@ -71,10 +71,10 @@ static int32_t vmsix_remap_entry(const struct pci_vdev *vdev, uint32_t index, bo * write only */ stac(); - mmio_write32((uint32_t)(info.pmsi_addr), (void *)&(pentry->addr)); - mmio_write32((uint32_t)(info.pmsi_addr >> 32U), (void *)((char *)&(pentry->addr) + 4U)); + mmio_write32((uint32_t)(info.pmsi_addr.full), (void *)&(pentry->addr)); + mmio_write32((uint32_t)(info.pmsi_addr.full >> 32U), (void *)((char *)&(pentry->addr) + 4U)); - mmio_write32(info.pmsi_data, (void *)&(pentry->data)); + mmio_write32(info.pmsi_data.full, (void *)&(pentry->data)); mmio_write32(vdev->msix.tables[index].vector_control, (void *)&(pentry->vector_control)); clac(); } diff --git a/hypervisor/include/arch/x86/irq.h b/hypervisor/include/arch/x86/irq.h index 652e58239..d56032a7d 100644 --- a/hypervisor/include/arch/x86/irq.h +++ b/hypervisor/include/arch/x86/irq.h @@ -102,17 +102,6 @@ uint32_t alloc_irq_vector(uint32_t irq); */ uint32_t irq_to_vector(uint32_t irq); -/* - * Some MSI message definitions - */ -#define MSI_ADDR_MASK 0xfff00000UL -#define MSI_ADDR_BASE 0xfee00000UL -#define MSI_ADDR_RH 0x00000008UL /* Redirection Hint */ -#define MSI_ADDR_LOG 0x00000004UL /* Destination Mode */ -#define MSI_ADDR_DEST 0x000FF000UL /* Destination Field */ - -#define MSI_ADDR_DEST_SHIFT (12U) - /* RFLAGS */ #define HV_ARCH_VCPU_RFLAGS_IF (1UL<<9U) diff --git a/hypervisor/include/common/ptdev.h b/hypervisor/include/common/ptdev.h index e3cbe7a77..3a303fd90 100644 --- a/hypervisor/include/common/ptdev.h +++ b/hypervisor/include/common/ptdev.h @@ -36,12 +36,55 @@ union source_id { } intx_id; }; +/* + * Macros for bits in union msi_addr_reg + */ + +#define MSI_ADDR_BASE 0xfeeUL /* Base address for MSI messages */ +#define MSI_ADDR_RH 0x1U /* Redirection Hint */ +#define MSI_ADDR_DESTMODE_LOGICAL 0x1U /* Destination Mode: Logical*/ +#define MSI_ADDR_DESTMODE_PHYS 0x0U /* Destination Mode: Physical*/ + +union msi_addr_reg { + uint64_t full; + struct { + uint32_t rsvd_1:2; + uint32_t dest_mode:1; + uint32_t rh:1; + uint32_t rsvd_2:8; + uint32_t dest_field:8; + uint32_t addr_base:12; + uint32_t hi_32; + } bits __packed; +}; + +/* + * Macros for bits in union msi_data_reg + */ + +#define MSI_DATA_DELMODE_FIXED 0x0U /* Delivery Mode: Fixed */ +#define MSI_DATA_DELMODE_LOPRI 0x1U /* Delivery Mode: Low Priority */ +#define MSI_DATA_TRGRMODE_EDGE 0x0U /* Trigger Mode: Edge */ +#define MSI_DATA_TRGRMODE_LEVEL 0x1U /* Trigger Mode: Level */ + +union msi_data_reg { + uint32_t full; + struct { + uint32_t vector:8; + uint32_t delivery_mode:3; + uint32_t rsvd_1:3; + uint32_t level:1; + uint32_t trigger_mode:1; + uint32_t rsvd_2:16; + } bits __packed; +}; + /* entry per guest virt vector */ struct ptirq_msi_info { - uint64_t vmsi_addr; /* virt msi_addr */ - uint32_t vmsi_data; /* virt msi_data */ - uint64_t pmsi_addr; /* phys msi_addr */ - uint32_t pmsi_data; /* phys msi_data */ + union msi_addr_reg vmsi_addr; /* virt msi_addr */ + union msi_data_reg vmsi_data; /* virt msi_data */ + union msi_addr_reg pmsi_addr; /* phys msi_addr */ + union msi_data_reg pmsi_data; /* phys msi_data */ int32_t is_msix; /* 0-MSI, 1-MSIX */ };