mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-23 14:07:42 +00:00
hv: pci: update "union pci_bdf"
- add one more filed in "union pci_bdf" - remove following interfaces: * pci_bus * pci_slot * pci_func * pci_devfn Tracked-On: #1842 Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
This commit is contained in:
parent
b16531257e
commit
658fff27b4
@ -103,27 +103,23 @@ static uint8_t get_secondary_bus(uint8_t bus, uint8_t dev, uint8_t func)
|
||||
return (data >> 8U) & 0xffU;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
static union pci_bdf
|
||||
dmar_path_bdf(int32_t path_len, int32_t busno,
|
||||
const struct acpi_dmar_pci_path *path)
|
||||
{
|
||||
int32_t i;
|
||||
uint8_t bus;
|
||||
uint8_t dev;
|
||||
uint8_t fun;
|
||||
|
||||
|
||||
bus = (uint8_t)busno;
|
||||
dev = path->device;
|
||||
fun = path->function;
|
||||
union pci_bdf dmar_bdf;
|
||||
|
||||
dmar_bdf.bits.b = (uint8_t)busno;
|
||||
dmar_bdf.bits.d = path->device;
|
||||
dmar_bdf.bits.f = path->function;
|
||||
|
||||
for (i = 1; i < path_len; i++) {
|
||||
bus = get_secondary_bus(bus, dev, fun);
|
||||
dev = path[i].device;
|
||||
fun = path[i].function;
|
||||
dmar_bdf.bits.b = get_secondary_bus(dmar_bdf.bits.b, dmar_bdf.bits.d, dmar_bdf.bits.f);
|
||||
dmar_bdf.bits.d = path[i].device;
|
||||
dmar_bdf.bits.f = path[i].function;
|
||||
}
|
||||
return (bus << 8U | DEVFUN(dev, fun));
|
||||
return dmar_bdf;
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +128,7 @@ handle_dmar_devscope(struct dmar_dev_scope *dev_scope,
|
||||
void *addr, int32_t remaining)
|
||||
{
|
||||
int32_t path_len;
|
||||
uint16_t bdf;
|
||||
union pci_bdf dmar_bdf;
|
||||
struct acpi_dmar_pci_path *path;
|
||||
struct acpi_dmar_device_scope *apci_devscope = addr;
|
||||
|
||||
@ -147,11 +143,11 @@ handle_dmar_devscope(struct dmar_dev_scope *dev_scope,
|
||||
sizeof(struct acpi_dmar_device_scope)) /
|
||||
sizeof(struct acpi_dmar_pci_path);
|
||||
|
||||
bdf = dmar_path_bdf(path_len, apci_devscope->bus, path);
|
||||
dmar_bdf = dmar_path_bdf(path_len, apci_devscope->bus, path);
|
||||
dev_scope->id = apci_devscope->enumeration_id;
|
||||
dev_scope->type = apci_devscope->entry_type;
|
||||
dev_scope->bus = (bdf >> 8U) & 0xffU;
|
||||
dev_scope->devfun = bdf & 0xffU;
|
||||
dev_scope->bus = dmar_bdf.fields.bus;
|
||||
dev_scope->devfun = dmar_bdf.fields.devfun;
|
||||
|
||||
return apci_devscope->length;
|
||||
}
|
||||
|
@ -607,6 +607,7 @@ int32_t ptirq_msix_remap(struct acrn_vm *vm, uint16_t virt_bdf, uint16_t phys_bd
|
||||
struct ptirq_remapping_info *entry;
|
||||
DEFINE_MSI_SID(virt_sid, virt_bdf, entry_nr);
|
||||
int32_t ret = -ENODEV;
|
||||
union pci_bdf vbdf;
|
||||
|
||||
/*
|
||||
* Device Model should pre-hold the mapping entries by calling
|
||||
@ -673,9 +674,10 @@ int32_t ptirq_msix_remap(struct acrn_vm *vm, uint16_t virt_bdf, uint16_t phys_bd
|
||||
|
||||
if (ret == 0) {
|
||||
entry->msi = *info;
|
||||
vbdf.value = virt_bdf;
|
||||
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.bits.vector, irq_to_vector(entry->allocated_pirq), entry->vm->vm_id);
|
||||
vbdf.bits.b, vbdf.bits.d, vbdf.bits.f, entry_nr, info->vmsi_data.bits.vector,
|
||||
irq_to_vector(entry->allocated_pirq), entry->vm->vm_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -532,9 +532,8 @@ static struct dmar_drhd_rt *ioapic_to_dmaru(uint16_t ioapic_id, union pci_bdf *s
|
||||
for (i = 0U; i < dmar_unit->drhd->dev_cnt; i++) {
|
||||
if ((dmar_unit->drhd->devices[i].type == ACPI_DMAR_SCOPE_TYPE_IOAPIC) &&
|
||||
(dmar_unit->drhd->devices[i].id == ioapic_id)) {
|
||||
sid->bits.f = pci_func((uint8_t)dmar_unit->drhd->devices[i].devfun);
|
||||
sid->bits.d = pci_slot((uint8_t)dmar_unit->drhd->devices[i].devfun);
|
||||
sid->bits.b = dmar_unit->drhd->devices[i].bus;
|
||||
sid->fields.devfun = dmar_unit->drhd->devices[i].devfun;
|
||||
sid->fields.bus = dmar_unit->drhd->devices[i].bus;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -868,11 +867,14 @@ static void fault_status_analysis(uint32_t status)
|
||||
|
||||
static void fault_record_analysis(__unused uint64_t low, uint64_t high)
|
||||
{
|
||||
union pci_bdf dmar_bdf;
|
||||
|
||||
if (!dma_frcd_up_f(high)) {
|
||||
dmar_bdf.value = dma_frcd_up_sid(high);
|
||||
/* currently skip PASID related parsing */
|
||||
pr_info("%s, Reason: 0x%x, SID: %x.%x.%x @0x%llx",
|
||||
(dma_frcd_up_t(high) != 0U) ? "Read/Atomic" : "Write", dma_frcd_up_fr(high),
|
||||
pci_bus(dma_frcd_up_sid(high)), pci_slot(dma_frcd_up_sid(high)), pci_func(dma_frcd_up_sid(high)), low);
|
||||
dmar_bdf.bits.b, dmar_bdf.bits.d, dmar_bdf.bits.f, low);
|
||||
#if DBG_IOMMU
|
||||
if (iommu_ecap_dt(dmar_unit->ecap) != 0U) {
|
||||
pr_info("Address Type: 0x%x", dma_frcd_up_at(high));
|
||||
@ -1055,13 +1057,18 @@ static int32_t add_iommu_device(struct iommu_domain *domain, uint16_t segment, u
|
||||
uint64_t hi_64;
|
||||
uint64_t lo_64 = 0UL;
|
||||
int32_t ret = 0;
|
||||
/* source id */
|
||||
union pci_bdf sid;
|
||||
|
||||
sid.fields.bus = bus;
|
||||
sid.fields.devfun = devfun;
|
||||
|
||||
dmar_unit = device_to_dmaru(segment, bus, devfun);
|
||||
if (dmar_unit == NULL) {
|
||||
pr_err("no dmar unit found for device: %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||
pr_err("no dmar unit found for device: %x:%x.%x", bus, sid.bits.d, sid.bits.f);
|
||||
ret = -EINVAL;
|
||||
} else if (dmar_unit->drhd->ignore) {
|
||||
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, sid.bits.d, sid.bits.f);
|
||||
} else if ((!dmar_unit_support_aw(dmar_unit, domain->addr_width)) || (dmar_unit->root_table_addr == 0UL)) {
|
||||
pr_err("invalid dmar unit");
|
||||
ret = -EINVAL;
|
||||
@ -1108,7 +1115,7 @@ static int32_t add_iommu_device(struct iommu_domain *domain, uint16_t segment, u
|
||||
} else if (dmar_get_bitslice(context_entry->lo_64, CTX_ENTRY_LOWER_P_MASK, CTX_ENTRY_LOWER_P_POS) != 0UL) {
|
||||
/* the context entry should not be present */
|
||||
pr_err("%s: context entry@0x%llx (Lower:%x) ", __func__, context_entry, context_entry->lo_64);
|
||||
pr_err("already present for %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||
pr_err("already present for %x:%x.%x", bus, sid.bits.d, sid.bits.f);
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
/* setup context entry for the devfun */
|
||||
@ -1162,15 +1169,20 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
|
||||
struct dmar_entry *context;
|
||||
struct dmar_entry *root_entry;
|
||||
struct dmar_entry *context_entry;
|
||||
/* source id */
|
||||
union pci_bdf sid;
|
||||
int32_t ret = 0;
|
||||
|
||||
dmar_unit = device_to_dmaru(segment, bus, devfun);
|
||||
|
||||
sid.fields.bus = bus;
|
||||
sid.fields.devfun = devfun;
|
||||
|
||||
if (dmar_unit == NULL) {
|
||||
pr_err("no dmar unit found for device: %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||
pr_err("no dmar unit found for device: %x:%x.%x", bus, sid.bits.d, sid.bits.f);
|
||||
ret = -EINVAL;
|
||||
} else if (dmar_unit->drhd->ignore) {
|
||||
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, sid.bits.d, sid.bits.f);
|
||||
} else {
|
||||
root_table = (struct dmar_entry *)hpa2hva(dmar_unit->root_table_addr);
|
||||
root_entry = root_table + bus;
|
||||
@ -1179,7 +1191,8 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
|
||||
pr_err("dmar root table entry is invalid\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
context_table_addr = dmar_get_bitslice(root_entry->lo_64, ROOT_ENTRY_LOWER_CTP_MASK, ROOT_ENTRY_LOWER_CTP_POS);
|
||||
context_table_addr = dmar_get_bitslice(root_entry->lo_64, ROOT_ENTRY_LOWER_CTP_MASK,
|
||||
ROOT_ENTRY_LOWER_CTP_POS);
|
||||
context_table_addr = context_table_addr << PAGE_SHIFT;
|
||||
context = (struct dmar_entry *)hpa2hva(context_table_addr);
|
||||
|
||||
@ -1188,7 +1201,8 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
|
||||
if ((context == NULL) || (context_entry == NULL)) {
|
||||
pr_err("dmar context entry is invalid");
|
||||
ret = -EINVAL;
|
||||
} else if ((uint16_t)dmar_get_bitslice(context_entry->hi_64, CTX_ENTRY_UPPER_DID_MASK, CTX_ENTRY_UPPER_DID_POS) != vmid_to_domainid(domain->vm_id)) {
|
||||
} else if ((uint16_t)dmar_get_bitslice(context_entry->hi_64, CTX_ENTRY_UPPER_DID_MASK,
|
||||
CTX_ENTRY_UPPER_DID_POS) != vmid_to_domainid(domain->vm_id)) {
|
||||
pr_err("%s: domain id mismatch", __func__);
|
||||
ret = -EPERM;
|
||||
} else {
|
||||
@ -1197,11 +1211,10 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
|
||||
context_entry->hi_64 = 0UL;
|
||||
iommu_flush_cache(context_entry, sizeof(struct dmar_entry));
|
||||
|
||||
sid.bits.b = bus;
|
||||
sid.bits.d = pci_slot(devfun);
|
||||
sid.bits.f = pci_func(devfun);
|
||||
dmar_invalid_context_cache(dmar_unit, vmid_to_domainid(domain->vm_id), sid.value, 0U, DMAR_CIRG_DEVICE);
|
||||
dmar_invalid_iotlb(dmar_unit, vmid_to_domainid(domain->vm_id), 0UL, 0U, false, DMAR_IIRG_DOMAIN);
|
||||
dmar_invalid_context_cache(dmar_unit, vmid_to_domainid(domain->vm_id), sid.value, 0U,
|
||||
DMAR_CIRG_DEVICE);
|
||||
dmar_invalid_iotlb(dmar_unit, vmid_to_domainid(domain->vm_id), 0UL, 0U, false,
|
||||
DMAR_IIRG_DOMAIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1345,7 +1358,7 @@ int32_t dmar_assign_irte(struct intr_source intr_src, union dmar_ir_entry irte,
|
||||
int32_t ret = 0;
|
||||
|
||||
if (intr_src.is_msi) {
|
||||
dmar_unit = device_to_dmaru(0U, (uint8_t)intr_src.src.msi.bits.b, pci_devfn(intr_src.src.msi.value));
|
||||
dmar_unit = device_to_dmaru(0U, (uint8_t)intr_src.src.msi.bits.b, intr_src.src.msi.fields.devfun);
|
||||
sid.value = intr_src.src.msi.value;
|
||||
trigger_mode = 0x0UL;
|
||||
} else {
|
||||
@ -1389,7 +1402,7 @@ void dmar_free_irte(struct intr_source intr_src, uint16_t index)
|
||||
union pci_bdf sid;
|
||||
|
||||
if (intr_src.is_msi) {
|
||||
dmar_unit = device_to_dmaru(0U, (uint8_t)intr_src.src.msi.bits.b, pci_devfn(intr_src.src.msi.value));
|
||||
dmar_unit = device_to_dmaru(0U, (uint8_t)intr_src.src.msi.bits.b, intr_src.src.msi.fields.devfun);
|
||||
} else {
|
||||
dmar_unit = ioapic_to_dmaru(intr_src.src.ioapic_id, &sid);
|
||||
}
|
||||
|
@ -830,13 +830,13 @@ int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
int32_t hcall_assign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
{
|
||||
int32_t ret;
|
||||
uint16_t bdf;
|
||||
union pci_bdf bdf;
|
||||
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
|
||||
bool bdf_valid = true;
|
||||
|
||||
if (!is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) {
|
||||
if (param < 0x10000UL) {
|
||||
bdf = (uint16_t) param;
|
||||
bdf.value = (uint16_t)param;
|
||||
} else {
|
||||
if (copy_from_gpa(vm, &bdf, param, sizeof(bdf)) != 0) {
|
||||
pr_err("%s: Unable copy param from vm %d\n",
|
||||
@ -847,8 +847,7 @@ int32_t hcall_assign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
}
|
||||
|
||||
if (bdf_valid) {
|
||||
ret = move_pt_device(vm->iommu, target_vm->iommu,
|
||||
(uint8_t)(bdf >> 8U), (uint8_t)(bdf & 0xffU));
|
||||
ret = move_pt_device(vm->iommu, target_vm->iommu, bdf.fields.bus, bdf.fields.devfun);
|
||||
}
|
||||
} else {
|
||||
pr_err("%s, target vm is invalid\n", __func__);
|
||||
@ -873,13 +872,13 @@ int32_t hcall_assign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
int32_t hcall_deassign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
uint16_t bdf;
|
||||
union pci_bdf bdf;
|
||||
bool bdf_valid = true;
|
||||
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
|
||||
|
||||
if (!is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) {
|
||||
if (param < 0x10000UL) {
|
||||
bdf = (uint16_t) param;
|
||||
bdf.value = (uint16_t)param;
|
||||
} else {
|
||||
if (copy_from_gpa(vm, &bdf, param, sizeof(bdf)) != 0) {
|
||||
pr_err("%s: Unable copy param to vm\n", __func__);
|
||||
@ -888,8 +887,7 @@ int32_t hcall_deassign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
}
|
||||
|
||||
if (bdf_valid) {
|
||||
ret = move_pt_device(target_vm->iommu, vm->iommu,
|
||||
(uint8_t)(bdf >> 8U), (uint8_t)(bdf & 0xffU));
|
||||
ret = move_pt_device(target_vm->iommu, vm->iommu, bdf.fields.bus, bdf.fields.devfun);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1032,7 @@ static void get_ptdev_info(char *str_arg, size_t str_max)
|
||||
uint64_t dest;
|
||||
bool lvl_tm;
|
||||
uint32_t pin, vpin;
|
||||
uint32_t bdf, vbdf;
|
||||
union pci_bdf bdf, vbdf;
|
||||
|
||||
len = snprintf(str, size, "\r\nVM\tTYPE\tIRQ\tVEC\tDEST\tTM\tPIN\tVPIN\tBDF\tVBDF");
|
||||
if (len >= size) {
|
||||
@ -1044,9 +1044,8 @@ static void get_ptdev_info(char *str_arg, size_t str_max)
|
||||
for (idx = 0U; idx < CONFIG_MAX_PT_IRQ_ENTRIES; idx++) {
|
||||
entry = &ptirq_entries[idx];
|
||||
if (is_entry_active(entry)) {
|
||||
get_entry_info(entry, type, &irq, &vector,
|
||||
&dest, &lvl_tm, &pin, &vpin,
|
||||
&bdf, &vbdf);
|
||||
get_entry_info(entry, type, &irq, &vector, &dest, &lvl_tm, &pin, &vpin,
|
||||
(uint32_t *)&bdf, (uint32_t *)&vbdf);
|
||||
len = snprintf(str, size, "\r\n%d\t%s\t%d\t0x%X\t0x%X",
|
||||
entry->vm->vm_id, type, irq, vector, dest);
|
||||
if (len >= size) {
|
||||
@ -1057,10 +1056,8 @@ static void get_ptdev_info(char *str_arg, size_t str_max)
|
||||
|
||||
len = snprintf(str, size, "\t%s\t%hhu\t%hhu\t%x:%x.%x\t%x:%x.%x",
|
||||
is_entry_active(entry) ? (lvl_tm ? "level" : "edge") : "none",
|
||||
pin, vpin, (bdf & 0xff00U) >> 8U,
|
||||
(bdf & 0xf8U) >> 3U, bdf & 0x7U,
|
||||
(vbdf & 0xff00U) >> 8U,
|
||||
(vbdf & 0xf8U) >> 3U, vbdf & 0x7U);
|
||||
pin, vpin, bdf.bits.b, bdf.bits.d, bdf.bits.f,
|
||||
vbdf.bits.b, vbdf.bits.d, vbdf.bits.f);
|
||||
if (len >= size) {
|
||||
goto overflow;
|
||||
}
|
||||
|
@ -141,6 +141,10 @@ union pci_bdf {
|
||||
uint8_t d : 5; /* BITs 3-7 */
|
||||
uint8_t b; /* BITs 8-15 */
|
||||
} bits;
|
||||
struct {
|
||||
uint8_t devfun; /* BITs 0-7 */
|
||||
uint8_t bus; /* BITs 8-15 */
|
||||
} fields;
|
||||
};
|
||||
|
||||
enum pci_bar_type {
|
||||
@ -278,26 +282,6 @@ static inline uint64_t git_size_masked_bar_base(uint64_t size, uint64_t val)
|
||||
return (mask & val);
|
||||
}
|
||||
|
||||
static inline uint8_t pci_bus(uint16_t bdf)
|
||||
{
|
||||
return (uint8_t)((bdf >> 8U) & 0xFFU);
|
||||
}
|
||||
|
||||
static inline uint8_t pci_slot(uint16_t bdf)
|
||||
{
|
||||
return (uint8_t)((bdf >> 3U) & 0x1FU);
|
||||
}
|
||||
|
||||
static inline uint8_t pci_func(uint16_t bdf)
|
||||
{
|
||||
return (uint8_t)(bdf & 0x7U);
|
||||
}
|
||||
|
||||
static inline uint8_t pci_devfn(uint16_t bdf)
|
||||
{
|
||||
return (uint8_t)(bdf & 0xFFU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @pre a != NULL
|
||||
* @pre b != NULL
|
||||
|
Loading…
Reference in New Issue
Block a user