qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: alex.williamson@redhat.com
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 17/17] vfio/pci: Add emulated PCI IDs
Date: Wed, 09 Sep 2015 12:31:18 -0600	[thread overview]
Message-ID: <20150909183117.8470.35588.stgit@gimli.home> (raw)
In-Reply-To: <20150909180219.8470.68096.stgit@gimli.home>

Specifying an emulated PCI vendor/device ID can be useful for testing
various quirk paths, even though the behavior and functionality of
the device with bogus IDs is fully unsupportable.  We need to use a
uint32_t for the vendor/device IDs, even though the registers
themselves are only 16-bit in order to be able to determine whether
the value is valid and user set.

The same support is added for subsystem vendor/device ID, though these
have the possibility of being useful and supported for more than a
testing tool.  An emulated platform might want to impose their own
subsystem IDs or at least hide the physical subsystem ID.  Windows
guests will often reinstall drivers due to a change in subsystem IDs,
something that VM users may want to avoid.  Of course careful
attention would be required to ensure that guest drivers do not rely
on the subsystem ID as a basis for device driver quirks.

All of these options are added using the standard experimental option
prefix and should not be considered stable.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 hw/vfio/pci-quirks.c |    2 --
 hw/vfio/pci.c        |   55 ++++++++++++++++++++++++++++++++++++++++++++++++--
 hw/vfio/pci.h        |    8 +++++--
 trace-events         |    4 ++++
 4 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 753a6c9..9fc9855 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -14,8 +14,6 @@
 #include "trace.h"
 #include "qemu/range.h"
 
-#define PCI_ANY_ID (~0)
-
 /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
 static bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t device)
 {
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 97547a8..58144d8 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2405,8 +2405,53 @@ static int vfio_initfn(PCIDevice *pdev)
     /* QEMU can choose to expose the ROM or not */
     memset(vdev->emulated_config_bits + PCI_ROM_ADDRESS, 0xff, 4);
 
-    vdev->vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
-    vdev->device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
+    /*
+     * The PCI spec reserves vendor ID 0xffff as an invalid value.  The
+     * device ID is managed by the vendor and need only be a 16-bit value.
+     * Allow any 16-bit value for subsystem so they can be hidden or changed.
+     */
+    if (vdev->vendor_id != PCI_ANY_ID) {
+        if (vdev->vendor_id >= 0xffff) {
+            error_report("vfio: Invalid PCI vendor ID provided");
+            return -EINVAL;
+        }
+        vfio_add_emulated_word(vdev, PCI_VENDOR_ID, vdev->vendor_id, ~0);
+        trace_vfio_pci_emulated_vendor_id(vdev->vbasedev.name, vdev->vendor_id);
+    } else {
+        vdev->vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
+    }
+
+    if (vdev->device_id != PCI_ANY_ID) {
+        if (vdev->device_id > 0xffff) {
+            error_report("vfio: Invalid PCI device ID provided");
+            return -EINVAL;
+        }
+        vfio_add_emulated_word(vdev, PCI_DEVICE_ID, vdev->device_id, ~0);
+        trace_vfio_pci_emulated_device_id(vdev->vbasedev.name, vdev->device_id);
+    } else {
+        vdev->device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
+    }
+
+    if (vdev->sub_vendor_id != PCI_ANY_ID) {
+        if (vdev->sub_vendor_id > 0xffff) {
+            error_report("vfio: Invalid PCI subsystem vendor ID provided");
+            return -EINVAL;
+        }
+        vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_VENDOR_ID,
+                               vdev->sub_vendor_id, ~0);
+        trace_vfio_pci_emulated_sub_vendor_id(vdev->vbasedev.name,
+                                              vdev->sub_vendor_id);
+    }
+
+    if (vdev->sub_device_id != PCI_ANY_ID) {
+        if (vdev->sub_device_id > 0xffff) {
+            error_report("vfio: Invalid PCI subsystem device ID provided");
+            return -EINVAL;
+        }
+        vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_ID, vdev->sub_device_id, ~0);
+        trace_vfio_pci_emulated_sub_device_id(vdev->vbasedev.name,
+                                              vdev->sub_device_id);
+    }
 
     /* QEMU can change multi-function devices to single function, or reverse */
     vdev->emulated_config_bits[PCI_HEADER_TYPE] =
@@ -2561,6 +2606,12 @@ static Property vfio_pci_dev_properties[] = {
     DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
     DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
     DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
+    DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, vendor_id, PCI_ANY_ID),
+    DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, device_id, PCI_ANY_ID),
+    DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
+                       sub_vendor_id, PCI_ANY_ID),
+    DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
+                       sub_device_id, PCI_ANY_ID),
     /*
      * TODO - support passed fds... is this necessary?
      * DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 797e083..f004d52 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -20,6 +20,8 @@
 #include "qemu/queue.h"
 #include "qemu/timer.h"
 
+#define PCI_ANY_ID (~0)
+
 struct VFIOPCIDevice;
 
 typedef struct VFIOQuirk {
@@ -116,8 +118,10 @@ typedef struct VFIOPCIDevice {
     EventNotifier err_notifier;
     EventNotifier req_notifier;
     int (*resetfn)(struct VFIOPCIDevice *);
-    uint16_t vendor_id;
-    uint16_t device_id;
+    uint32_t vendor_id;
+    uint32_t device_id;
+    uint32_t sub_vendor_id;
+    uint32_t sub_device_id;
     uint32_t features;
 #define VFIO_FEATURE_ENABLE_VGA_BIT 0
 #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
diff --git a/trace-events b/trace-events
index 9b630c1..7b4e9af 100644
--- a/trace-events
+++ b/trace-events
@@ -1547,6 +1547,10 @@ vfio_initfn(const char *name, int group_id) " (%s) group %d"
 vfio_pci_reset(const char *name) " (%s)"
 vfio_pci_reset_flr(const char *name) "%s FLR/VFIO_DEVICE_RESET"
 vfio_pci_reset_pm(const char *name) "%s PCI PM Reset"
+vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s %04x"
 
 # hw/vfio/pci-quirks.
 vfio_quirk_rom_blacklisted(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"

      parent reply	other threads:[~2015-09-09 18:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-09 18:29 [Qemu-devel] [PATCH 00/17] vfio: quirks & tracing refactoring Alex Williamson
2015-09-09 18:29 ` [Qemu-devel] [PATCH 01/17] vfio/pci: Rename INTx functions for easier tracing Alex Williamson
2015-09-09 18:29 ` [Qemu-devel] [PATCH 02/17] vfio/pci: Rename MSI/X " Alex Williamson
2015-09-09 18:29 ` [Qemu-devel] [PATCH 03/17] vfio/pci: Make interrupt bypass runtime configurable Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 04/17] vfio: Change polarity of our no-mmap option Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 05/17] vfio/pci: Extract PCI structures to a separate header Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 06/17] vfio/pci: Split quirks to a separate file Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 07/17] vfio/pci: Cleanup ROM blacklist quirk Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 08/17] vfio/pci: Foundation for new quirk structure Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 09/17] vfio/pci: Cleanup ATI 0x3c3 quirk Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 10/17] vfio/pci: Cleanup Nvidia 0x3d0 quirk Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 11/17] vfio/pci: Rework RTL8168 quirk Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 12/17] vfio/pci: Config window quirks Alex Williamson
2015-09-09 18:30 ` [Qemu-devel] [PATCH 13/17] vfio/pci: Config mirror quirk Alex Williamson
2015-09-09 18:31 ` [Qemu-devel] [PATCH 14/17] vfio/pci: Remove old config window and mirror quirks Alex Williamson
2015-09-09 18:31 ` [Qemu-devel] [PATCH 15/17] vfio/pci: Move AMD device specific reset to quirks Alex Williamson
2015-09-09 18:31 ` [Qemu-devel] [PATCH 16/17] vfio/pci: Cache vendor and device ID Alex Williamson
2015-09-09 18:31 ` Alex Williamson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150909183117.8470.35588.stgit@gimli.home \
    --to=alex.williamson@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).