[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v1 19/23] xen/pt: Fake capability id
From: |
Joel Upham |
Subject: |
[PATCH v1 19/23] xen/pt: Fake capability id |
Date: |
Tue, 20 Jun 2023 13:24:53 -0400 |
Some PCIe capabilities needed to be faked for the xen implementation to work.
This is the situation when we were asked to hide (aka
"hardwire to 0") some PCIe ext capability, but it was located
at offset 0x100 in PCIe config space. In this case we can't
simply exclude it from the linked list of capabilities
(as it is the first entry in the list), so we must fake its
Capability ID in PCIe Extended Capability header, leaving
the Next Ptr field intact while returning zeroes on attempts
to read capability body (writes are ignored).
Signed-off-by: Alexey Gerasimenko <x1917x@xxxxxxxxx>
Signed-off-by: Joel Upham <jupham125@gmail.com>
---
hw/xen/xen_pt_config_init.c | 72 ++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 4e14adf2b2..41b43b9445 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -16,6 +16,7 @@
#include "qapi/error.h"
#include "qemu/timer.h"
#include "xen_pt.h"
+#include "xen-host-pci-device.h"
#include "hw/xen/xen-legacy-backend.h"
#define XEN_PT_MERGE_VALUE(value, data, val_mask) \
@@ -31,6 +32,10 @@ static int
xen_pt_ext_cap_ptr_reg_init(XenPCIPassthroughState *s,
XenPTRegInfo *reg,
uint32_t real_offset,
uint32_t *data);
+static int xen_pt_ext_cap_capid_reg_init(XenPCIPassthroughState *s,
+ XenPTRegInfo *reg,
+ uint32_t real_offset,
+ uint32_t *data);
/* helper */
@@ -995,6 +1000,17 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
.u.b.read = xen_pt_byte_reg_read,
.u.b.write = xen_pt_byte_reg_write,
},
+ /* PCI Express Capabilities Register */
+ {
+ .offset = PCI_EXP_FLAGS,
+ .size = 2,
+ .init_val = 0x0000,
+ .ro_mask = 0xFFFF,
+ .emu_mask = 0xFFFF,
+ .init = xen_pt_pcie_capabilities_reg_init,
+ .u.w.read = xen_pt_word_reg_read,
+ .u.w.write = xen_pt_word_reg_write,
+ },
/* Device Capabilities reg */
{
.offset = PCI_EXP_DEVCAP,
@@ -1633,6 +1649,54 @@ static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
},
};
+/****************************
+ * Emulated registers for
+ * PCIe Extended Capabilities
+ */
+
+static uint16_t fake_cap_id = XEN_PCIE_FAKE_CAP_ID_BASE;
+
+/* PCIe Extended Capability ID reg */
+static int xen_pt_ext_cap_capid_reg_init(XenPCIPassthroughState *s,
+ XenPTRegInfo *reg,
+ uint32_t real_offset,
+ uint32_t *data)
+{
+ uint16_t reg_field;
+ int rc;
+ XenPTRegGroup *reg_grp_entry = NULL;
+
+ /* use real device register's value as initial value */
+ rc = xen_host_pci_get_word(&s->real_device, real_offset, ®_field);
+ if (rc) {
+ return rc;
+ }
+
+ reg_grp_entry = xen_pt_find_reg_grp(s, real_offset);
+
+ if (reg_grp_entry) {
+ if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED &&
+ reg_grp_entry->base_offset == PCI_CONFIG_SPACE_SIZE) {
+ /*
+ * This is the situation when we were asked to hide (aka
+ * "hardwire to 0") some PCIe ext capability, but it was located
+ * at offset 0x100 in PCIe config space. In this case we can't
+ * simply exclude it from the linked list of capabilities
+ * (as it is the first entry in the list), so we must fake its
+ * Capability ID in PCIe Extended Capability header, leaving
+ * the Next Ptr field intact while returning zeroes on attempts
+ * to read capability body (writes are ignored).
+ */
+ reg_field = fake_cap_id;
+ /* increment the value in order to have unique Capability IDs */
+ fake_cap_id++;
+ }
+ }
+
+ *data = reg_field;
+ return 0;
+}
+
/* Vendor-specific Ext Capability Structure reg static information table */
static XenPTRegInfo xen_pt_ext_cap_emu_reg_vendor[] = {
{
@@ -2938,7 +3002,13 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error
**errp)
}
}
- if (xen_pt_emu_reg_grps[i].grp_type == XEN_PT_GRP_TYPE_EMU) {
+ if (xen_pt_emu_reg_grps[i].grp_type == XEN_PT_GRP_TYPE_EMU ||
+ /*
+ * We need to always emulate the PCIe Extended Capability
+ * header for a hidden capability which starts at offset 0x100
+ */
+ (xen_pt_emu_reg_grps[i].grp_type == XEN_PT_GRP_TYPE_HARDWIRED &&
+ reg_grp_offset == 0x100)) {
if (xen_pt_emu_reg_grps[i].emu_regs) {
int j = 0;
XenPTRegInfo *regs = xen_pt_emu_reg_grps[i].emu_regs;
--
2.34.1
- Re: [PATCH v1 02/23] pc/q35: Apply PCI bus BSEL property for Xen PCI device hotplug, (continued)
[PATCH v1 03/23] q35/acpi/xen: Provide ACPI PCI hotplug interface for Xen on Q35, Joel Upham, 2023/06/20
[PATCH v1 04/23] q35/xen: Add Xen platform device support for Q35, Joel Upham, 2023/06/20
[PATCH v1 05/23] q35: Fix incorrect values for PCIEXBAR masks, Joel Upham, 2023/06/20
[PATCH v1 11/23] xen/pt: handle PCIe Extended Capabilities Next register, Joel Upham, 2023/06/20
[PATCH v1 14/23] xen/pt: add fixed-size PCIe Extended Capabilities descriptors, Joel Upham, 2023/06/20
[PATCH v1 16/23] xen/pt: add descriptors and size calculation for RCLD/ACS/PMUX/DPA/MCAST/TPH/DPC PCIe Extended Capabilities, Joel Upham, 2023/06/20
[PATCH v1 19/23] xen/pt: Fake capability id,
Joel Upham <=
[PATCH v1 22/23] qdev-monitor/pt: bypass root device check, Joel Upham, 2023/06/20
[PATCH v1 09/23] xen/pt: Xen PCIe passthrough support for Q35: bypass PCIe topology check, Joel Upham, 2023/06/20
[PATCH v1 08/23] xen/pt: determine the legacy/PCIe mode for a passed through device, Joel Upham, 2023/06/20
[PATCH v1 21/23] pc/q35: setup q35 for xen, Joel Upham, 2023/06/20
[PATCH v1 23/23] s3 support: enabling s3 with q35, Joel Upham, 2023/06/20
[PATCH v1 06/23] xen/pt: XenHostPCIDevice: provide functions for PCI Capabilities and PCIe Extended Capabilities enumeration, Joel Upham, 2023/06/20
[PATCH v1 13/23] xen/pt: add Vendor-specific PCIe Extended Capability descriptor and sizing, Joel Upham, 2023/06/20
Re: [PATCH v1 00/23] Q35 support for Xen, Bernhard Beschow, 2023/06/22