Skip to content

Commit 7d57eb0

Browse files
Sainath Grandhiwenlingz
authored andcommitted
hv: Add bit representation for MSI addr and data
As we enable Interrupt Remapping, bit positions in MSI address and data registers have a different syntax for programming. This patch adds bit granularity for MSI address and data structs. Tracked-On: #2407 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
1 parent 6825043 commit 7d57eb0

File tree

7 files changed

+92
-55
lines changed

7 files changed

+92
-55
lines changed

hypervisor/arch/x86/assign.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,32 +77,33 @@ static void ptirq_build_physical_msi(struct acrn_vm *vm, struct ptirq_msi_info *
7777
bool phys;
7878

7979
/* get physical destination cpu mask */
80-
dest = (uint32_t)(info->vmsi_addr & MSI_ADDR_DEST) >> MSI_ADDR_DEST_SHIFT;
81-
phys = ((info->vmsi_addr & MSI_ADDR_LOG) != MSI_ADDR_LOG);
80+
dest = info->vmsi_addr.bits.dest_field;
81+
phys = (info->vmsi_addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
8282

8383
vlapic_calcdest(vm, &vdmask, dest, phys, false);
8484
pdmask = vcpumask2pcpumask(vm, vdmask);
8585

8686
/* get physical delivery mode */
87-
delmode = info->vmsi_data & APIC_DELMODE_MASK;
88-
if ((delmode != APIC_DELMODE_FIXED) && (delmode != APIC_DELMODE_LOWPRIO)) {
89-
delmode = APIC_DELMODE_LOWPRIO;
87+
delmode = info->vmsi_data.bits.delivery_mode;
88+
if ((delmode != MSI_DATA_DELMODE_FIXED) && (delmode != MSI_DATA_DELMODE_LOPRI)) {
89+
delmode = MSI_DATA_DELMODE_LOPRI;
9090
}
9191

9292
/* update physical delivery mode & vector */
9393
info->pmsi_data = info->vmsi_data;
94-
info->pmsi_data &= ~0x7FFU;
95-
info->pmsi_data |= delmode | vector;
94+
info->pmsi_data.bits.delivery_mode = delmode;
95+
info->pmsi_data.bits.vector = vector;
9696

9797
dest_mask = calculate_logical_dest_mask(pdmask);
9898
/* update physical dest mode & dest field */
9999
info->pmsi_addr = info->vmsi_addr;
100-
info->pmsi_addr &= ~0xFF00CU;
101-
info->pmsi_addr |= (dest_mask << MSI_ADDR_DEST_SHIFT) | MSI_ADDR_RH | MSI_ADDR_LOG;
100+
info->pmsi_addr.bits.dest_mode = MSI_ADDR_DESTMODE_LOGICAL;
101+
info->pmsi_addr.bits.rh = MSI_ADDR_RH;
102+
info->pmsi_addr.bits.dest_field = dest_mask;
102103

103104
dev_dbg(ACRN_DBG_IRQ, "MSI addr:data = 0x%llx:%x(V) -> 0x%llx:%x(P)",
104-
info->vmsi_addr, info->vmsi_data,
105-
info->pmsi_addr, info->pmsi_data);
105+
info->vmsi_addr.full, info->vmsi_data.full,
106+
info->pmsi_addr.full, info->pmsi_data.full);
106107
}
107108

108109
static union ioapic_rte
@@ -442,14 +443,14 @@ void ptirq_softirq(uint16_t pcpu_id)
442443
} else {
443444
if (msi != NULL) {
444445
/* TODO: msi destmode check required */
445-
(void)vlapic_intr_msi(vm, msi->vmsi_addr, msi->vmsi_data);
446+
(void)vlapic_intr_msi(vm, msi->vmsi_addr.full, msi->vmsi_data.full);
446447
dev_dbg(ACRN_DBG_PTIRQ, "dev-assign: irq=0x%x MSI VR: 0x%x-0x%x",
447448
entry->allocated_pirq,
448-
msi->vmsi_data & 0xFFU,
449+
msi->vmsi_data.bits.vector,
449450
irq_to_vector(entry->allocated_pirq));
450451
dev_dbg(ACRN_DBG_PTIRQ, " vmsi_addr: 0x%llx vmsi_data: 0x%x",
451-
msi->vmsi_addr,
452-
msi->vmsi_data);
452+
msi->vmsi_addr.full,
453+
msi->vmsi_data.full);
453454
}
454455
}
455456
}
@@ -534,16 +535,16 @@ int32_t ptirq_msix_remap(struct acrn_vm *vm, uint16_t virt_bdf,
534535
spinlock_release(&ptdev_lock);
535536

536537
if (entry != NULL) {
537-
if (is_entry_active(entry) && (info->vmsi_data == 0U)) {
538+
if (is_entry_active(entry) && (info->vmsi_data.full == 0U)) {
538539
/* handle destroy case */
539-
info->pmsi_data = 0U;
540+
info->pmsi_data.full = 0U;
540541
} else {
541542
/* build physical config MSI, update to info->pmsi_xxx */
542543
ptirq_build_physical_msi(vm, info, irq_to_vector(entry->allocated_pirq));
543544
entry->msi = *info;
544545
dev_dbg(ACRN_DBG_IRQ, "PCI %x:%x.%x MSI VR[%d] 0x%x->0x%x assigned to vm%d",
545546
pci_bus(virt_bdf), pci_slot(virt_bdf), pci_func(virt_bdf), entry_nr,
546-
info->vmsi_data & 0xFFU, irq_to_vector(entry->allocated_pirq), entry->vm->vm_id);
547+
info->vmsi_data.bits.vector, irq_to_vector(entry->allocated_pirq), entry->vm->vm_id);
547548
}
548549
ret = 0;
549550
}

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,10 +1940,14 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
19401940
uint32_t dest;
19411941
bool phys, rh;
19421942
int32_t ret;
1943+
union msi_addr_reg address;
1944+
union msi_data_reg data;
19431945

1944-
dev_dbg(ACRN_DBG_LAPIC, "lapic MSI addr: %#lx msg: %#lx", addr, msg);
1946+
address.full = addr;
1947+
data.full = (uint32_t) msg;
1948+
dev_dbg(ACRN_DBG_LAPIC, "lapic MSI addr: %#lx msg: %#lx", address.full, data.full);
19451949

1946-
if ((addr & MSI_ADDR_MASK) == MSI_ADDR_BASE) {
1950+
if (address.bits.addr_base == MSI_ADDR_BASE) {
19471951
/*
19481952
* Extract the x86-specific fields from the MSI addr/msg
19491953
* params according to the Intel Arch spec, Vol3 Ch 10.
@@ -1955,20 +1959,20 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
19551959
* the Redirection Hint and Destination Mode are '1' and
19561960
* physical otherwise.
19571961
*/
1958-
dest = (uint32_t)(addr >> 12U) & 0xffU;
1959-
phys = ((addr & MSI_ADDR_LOG) != MSI_ADDR_LOG);
1960-
rh = ((addr & MSI_ADDR_RH) == MSI_ADDR_RH);
1962+
dest = address.bits.dest_field;
1963+
phys = (address.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
1964+
rh = (address.bits.rh == MSI_ADDR_RH);
19611965

1962-
delmode = (uint32_t)msg & APIC_DELMODE_MASK;
1963-
vec = (uint32_t)msg & 0xffU;
1966+
delmode = data.bits.delivery_mode;
1967+
vec = data.bits.vector;
19641968

19651969
dev_dbg(ACRN_DBG_LAPIC, "lapic MSI %s dest %#x, vec %u",
19661970
phys ? "physical" : "logical", dest, vec);
19671971

19681972
vlapic_deliver_intr(vm, LAPIC_TRIG_EDGE, dest, phys, delmode, vec, rh);
19691973
ret = 0;
19701974
} else {
1971-
dev_dbg(ACRN_DBG_LAPIC, "lapic MSI invalid addr %#lx", addr);
1975+
dev_dbg(ACRN_DBG_LAPIC, "lapic MSI invalid addr %#lx", address.full);
19721976
ret = -1;
19731977
}
19741978

hypervisor/debug/shell.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,8 @@ static void get_entry_info(const struct ptirq_remapping_info *entry, char *type,
907907
if (is_entry_active(entry)) {
908908
if (entry->intr_type == PTDEV_INTR_MSI) {
909909
(void)strncpy_s(type, 16U, "MSI", 16U);
910-
*dest = (entry->msi.pmsi_addr & 0xFF000U) >> PAGE_SHIFT;
911-
if ((entry->msi.pmsi_data & APIC_TRIGMOD_LEVEL) != 0U) {
910+
*dest = entry->msi.pmsi_addr.bits.dest_field;
911+
if (entry->msi.pmsi_data.bits.trigger_mode == MSI_DATA_TRGRMODE_LEVEL) {
912912
*lvl_tm = true;
913913
} else {
914914
*lvl_tm = false;

hypervisor/dm/vpci/msi.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,24 @@ static int32_t vmsi_remap(const struct pci_vdev *vdev, bool enable)
6969
}
7070

7171
info.is_msix = 0;
72-
info.vmsi_addr = (uint64_t)addrlo | ((uint64_t)addrhi << 32U);
72+
info.vmsi_addr.full = (uint64_t)addrlo | ((uint64_t)addrhi << 32U);
7373

7474
/* MSI is being enabled or disabled */
7575
if (enable) {
76-
info.vmsi_data = msgdata;
76+
info.vmsi_data.full = msgdata;
7777
} else {
78-
info.vmsi_data = 0U;
78+
info.vmsi_data.full = 0U;
7979
}
8080

8181
ret = ptirq_msix_remap(vm, vdev->vbdf.value, 0U, &info);
8282
if (ret == 0) {
8383
/* Update MSI Capability structure to physical device */
84-
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR, 0x4U, (uint32_t)info.pmsi_addr);
84+
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR, 0x4U, (uint32_t)info.pmsi_addr.full);
8585
if ((msgctrl & PCIM_MSICTRL_64BIT) != 0U) {
86-
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR_HIGH, 0x4U, (uint32_t)(info.pmsi_addr >> 32U));
87-
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA_64BIT, 0x2U, (uint16_t)info.pmsi_data);
86+
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_ADDR_HIGH, 0x4U, (uint32_t)(info.pmsi_addr.full >> 32U));
87+
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA_64BIT, 0x2U, (uint16_t)info.pmsi_data.full);
8888
} else {
89-
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA, 0x2U, (uint16_t)info.pmsi_data);
89+
pci_pdev_write_cfg(pbdf, capoff + PCIR_MSI_DATA, 0x2U, (uint16_t)info.pmsi_data.full);
9090
}
9191

9292
/* If MSI Enable is being set, make sure INTxDIS bit is set */

hypervisor/dm/vpci/msix.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ static int32_t vmsix_remap_entry(const struct pci_vdev *vdev, uint32_t index, bo
5656
int32_t ret;
5757

5858
info.is_msix = 1;
59-
info.vmsi_addr = vdev->msix.tables[index].addr;
60-
info.vmsi_data = (enable) ? vdev->msix.tables[index].data : 0U;
59+
info.vmsi_addr.full = vdev->msix.tables[index].addr;
60+
info.vmsi_data.full = (enable) ? vdev->msix.tables[index].data : 0U;
6161

6262
ret = ptirq_msix_remap(vdev->vpci->vm, vdev->vbdf.value, (uint16_t)index, &info);
6363
if (ret == 0) {
@@ -71,10 +71,10 @@ static int32_t vmsix_remap_entry(const struct pci_vdev *vdev, uint32_t index, bo
7171
* write only
7272
*/
7373
stac();
74-
mmio_write32((uint32_t)(info.pmsi_addr), (void *)&(pentry->addr));
75-
mmio_write32((uint32_t)(info.pmsi_addr >> 32U), (void *)((char *)&(pentry->addr) + 4U));
74+
mmio_write32((uint32_t)(info.pmsi_addr.full), (void *)&(pentry->addr));
75+
mmio_write32((uint32_t)(info.pmsi_addr.full >> 32U), (void *)((char *)&(pentry->addr) + 4U));
7676

77-
mmio_write32(info.pmsi_data, (void *)&(pentry->data));
77+
mmio_write32(info.pmsi_data.full, (void *)&(pentry->data));
7878
mmio_write32(vdev->msix.tables[index].vector_control, (void *)&(pentry->vector_control));
7979
clac();
8080
}

hypervisor/include/arch/x86/irq.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,6 @@ uint32_t alloc_irq_vector(uint32_t irq);
102102
*/
103103
uint32_t irq_to_vector(uint32_t irq);
104104

105-
/*
106-
* Some MSI message definitions
107-
*/
108-
#define MSI_ADDR_MASK 0xfff00000UL
109-
#define MSI_ADDR_BASE 0xfee00000UL
110-
#define MSI_ADDR_RH 0x00000008UL /* Redirection Hint */
111-
#define MSI_ADDR_LOG 0x00000004UL /* Destination Mode */
112-
#define MSI_ADDR_DEST 0x000FF000UL /* Destination Field */
113-
114-
#define MSI_ADDR_DEST_SHIFT (12U)
115-
116105
/* RFLAGS */
117106
#define HV_ARCH_VCPU_RFLAGS_IF (1UL<<9U)
118107

hypervisor/include/common/ptdev.h

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,55 @@ union source_id {
3636
} intx_id;
3737
};
3838

39+
/*
40+
* Macros for bits in union msi_addr_reg
41+
*/
42+
43+
#define MSI_ADDR_BASE 0xfeeUL /* Base address for MSI messages */
44+
#define MSI_ADDR_RH 0x1U /* Redirection Hint */
45+
#define MSI_ADDR_DESTMODE_LOGICAL 0x1U /* Destination Mode: Logical*/
46+
#define MSI_ADDR_DESTMODE_PHYS 0x0U /* Destination Mode: Physical*/
47+
48+
union msi_addr_reg {
49+
uint64_t full;
50+
struct {
51+
uint32_t rsvd_1:2;
52+
uint32_t dest_mode:1;
53+
uint32_t rh:1;
54+
uint32_t rsvd_2:8;
55+
uint32_t dest_field:8;
56+
uint32_t addr_base:12;
57+
uint32_t hi_32;
58+
} bits __packed;
59+
};
60+
61+
/*
62+
* Macros for bits in union msi_data_reg
63+
*/
64+
65+
#define MSI_DATA_DELMODE_FIXED 0x0U /* Delivery Mode: Fixed */
66+
#define MSI_DATA_DELMODE_LOPRI 0x1U /* Delivery Mode: Low Priority */
67+
#define MSI_DATA_TRGRMODE_EDGE 0x0U /* Trigger Mode: Edge */
68+
#define MSI_DATA_TRGRMODE_LEVEL 0x1U /* Trigger Mode: Level */
69+
70+
union msi_data_reg {
71+
uint32_t full;
72+
struct {
73+
uint32_t vector:8;
74+
uint32_t delivery_mode:3;
75+
uint32_t rsvd_1:3;
76+
uint32_t level:1;
77+
uint32_t trigger_mode:1;
78+
uint32_t rsvd_2:16;
79+
} bits __packed;
80+
};
81+
3982
/* entry per guest virt vector */
4083
struct ptirq_msi_info {
41-
uint64_t vmsi_addr; /* virt msi_addr */
42-
uint32_t vmsi_data; /* virt msi_data */
43-
uint64_t pmsi_addr; /* phys msi_addr */
44-
uint32_t pmsi_data; /* phys msi_data */
84+
union msi_addr_reg vmsi_addr; /* virt msi_addr */
85+
union msi_data_reg vmsi_data; /* virt msi_data */
86+
union msi_addr_reg pmsi_addr; /* phys msi_addr */
87+
union msi_data_reg pmsi_data; /* phys msi_data */
4588
int32_t is_msix; /* 0-MSI, 1-MSIX */
4689
};
4790

0 commit comments

Comments
 (0)