summaryrefslogtreecommitdiffstats
path: root/hw/smbios/smbios.c
diff options
context:
space:
mode:
authorPeter Maydell2021-05-16 18:22:46 +0200
committerPeter Maydell2021-05-16 18:22:46 +0200
commit6005ee07c380cbde44292f5f6c96e7daa70f4f7d (patch)
tree97a653b8b4d6c3e631b4a0c97897fb6564e8e309 /hw/smbios/smbios.c
parentMerge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2021-05-... (diff)
parentFix build with 64 bits time_t (diff)
downloadqemu-6005ee07c380cbde44292f5f6c96e7daa70f4f7d.tar.gz
qemu-6005ee07c380cbde44292f5f6c96e7daa70f4f7d.tar.xz
qemu-6005ee07c380cbde44292f5f6c96e7daa70f4f7d.zip
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc,pci,virtio: bugfixes, improvements Fixes all over the place. Faster boot for virtio. ioeventfd support for mmio. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 14 May 2021 15:27:13 BST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: Fix build with 64 bits time_t vhost-vdpa: Make vhost_vdpa_get_device_id() static hw/virtio: enable ioeventfd configuring for mmio hw/smbios: support for type 41 (onboard devices extended information) checkpatch: Fix use of uninitialized value virtio-scsi: Configure all host notifiers in a single MR transaction virtio-scsi: Set host notifiers and callbacks separately virtio-blk: Configure all host notifiers in a single MR transaction virtio-blk: Fix rollback path in virtio_blk_data_plane_start() pc-dimm: remove unnecessary get_vmstate_memory_region() method amd_iommu: fix wrong MMIO operations virtio-net: Constify VirtIOFeature feature_sizes[] virtio-blk: Constify VirtIOFeature feature_sizes[] hw/virtio: Pass virtio_feature_get_config_size() a const argument x86: acpi: use offset instead of pointer when using build_header() amd_iommu: Fix pte_override_page_mask() Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # hw/arm/virt.c
Diffstat (limited to 'hw/smbios/smbios.c')
-rw-r--r--hw/smbios/smbios.c124
1 files changed, 123 insertions, 1 deletions
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index f22c4f5b73..7397e56737 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -27,6 +27,7 @@
#include "hw/firmware/smbios.h"
#include "hw/loader.h"
#include "hw/boards.h"
+#include "hw/pci/pci_bus.h"
#include "smbios_build.h"
/* legacy structures and constants for <= 2.0 machines */
@@ -118,6 +119,28 @@ static struct {
uint16_t speed;
} type17;
+static QEnumLookup type41_kind_lookup = {
+ .array = (const char *const[]) {
+ "other",
+ "unknown",
+ "video",
+ "scsi",
+ "ethernet",
+ "tokenring",
+ "sound",
+ "pata",
+ "sata",
+ "sas",
+ },
+ .size = 10
+};
+struct type41_instance {
+ const char *designation, *pcidev;
+ uint8_t instance, kind;
+ QTAILQ_ENTRY(type41_instance) next;
+};
+static QTAILQ_HEAD(, type41_instance) type41 = QTAILQ_HEAD_INITIALIZER(type41);
+
static QemuOptsList qemu_smbios_opts = {
.name = "smbios",
.head = QTAILQ_HEAD_INITIALIZER(qemu_smbios_opts.head),
@@ -358,6 +381,32 @@ static const QemuOptDesc qemu_smbios_type17_opts[] = {
{ /* end of list */ }
};
+static const QemuOptDesc qemu_smbios_type41_opts[] = {
+ {
+ .name = "type",
+ .type = QEMU_OPT_NUMBER,
+ .help = "SMBIOS element type",
+ },{
+ .name = "designation",
+ .type = QEMU_OPT_STRING,
+ .help = "reference designation string",
+ },{
+ .name = "kind",
+ .type = QEMU_OPT_STRING,
+ .help = "device type",
+ .def_value_str = "other",
+ },{
+ .name = "instance",
+ .type = QEMU_OPT_NUMBER,
+ .help = "device type instance",
+ },{
+ .name = "pcidev",
+ .type = QEMU_OPT_STRING,
+ .help = "PCI device",
+ },
+ { /* end of list */ }
+};
+
static void smbios_register_config(void)
{
qemu_add_opts(&qemu_smbios_opts);
@@ -773,6 +822,53 @@ static void smbios_build_type_32_table(void)
SMBIOS_BUILD_TABLE_POST;
}
+static void smbios_build_type_41_table(Error **errp)
+{
+ unsigned instance = 0;
+ struct type41_instance *t41;
+
+ QTAILQ_FOREACH(t41, &type41, next) {
+ SMBIOS_BUILD_TABLE_PRE(41, 0x2900 + instance, true);
+
+ SMBIOS_TABLE_SET_STR(41, reference_designation_str, t41->designation);
+ t->device_type = t41->kind;
+ t->device_type_instance = t41->instance;
+ t->segment_group_number = cpu_to_le16(0);
+ t->bus_number = 0;
+ t->device_number = 0;
+
+ if (t41->pcidev) {
+ PCIDevice *pdev = NULL;
+ int rc = pci_qdev_find_device(t41->pcidev, &pdev);
+ if (rc != 0) {
+ error_setg(errp,
+ "No PCI device %s for SMBIOS type 41 entry %s",
+ t41->pcidev, t41->designation);
+ return;
+ }
+ /*
+ * We only handle the case were the device is attached to
+ * the PCI root bus. The general case is more complex as
+ * bridges are enumerated later and the table would need
+ * to be updated at this moment.
+ */
+ if (!pci_bus_is_root(pci_get_bus(pdev))) {
+ error_setg(errp,
+ "Cannot create type 41 entry for PCI device %s: "
+ "not attached to the root bus",
+ t41->pcidev);
+ return;
+ }
+ t->segment_group_number = cpu_to_le16(0);
+ t->bus_number = pci_dev_bus_num(pdev);
+ t->device_number = pdev->devfn;
+ }
+
+ SMBIOS_BUILD_TABLE_POST;
+ instance++;
+ }
+}
+
static void smbios_build_type_127_table(void)
{
SMBIOS_BUILD_TABLE_PRE(127, 0x7F00, true); /* required */
@@ -883,7 +979,8 @@ void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
uint8_t **tables, size_t *tables_len,
- uint8_t **anchor, size_t *anchor_len)
+ uint8_t **anchor, size_t *anchor_len,
+ Error **errp)
{
unsigned i, dimm_cnt;
@@ -928,6 +1025,7 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_32_table();
smbios_build_type_38_table();
+ smbios_build_type_41_table(errp);
smbios_build_type_127_table();
smbios_validate_table(ms);
@@ -1224,6 +1322,30 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type17.part, opts, "part");
type17.speed = qemu_opt_get_number(opts, "speed", 0);
return;
+ case 41: {
+ struct type41_instance *t;
+ Error *local_err = NULL;
+
+ if (!qemu_opts_validate(opts, qemu_smbios_type41_opts, errp)) {
+ return;
+ }
+ t = g_new0(struct type41_instance, 1);
+ save_opt(&t->designation, opts, "designation");
+ t->kind = qapi_enum_parse(&type41_kind_lookup,
+ qemu_opt_get(opts, "kind"),
+ 0, &local_err) + 1;
+ t->kind |= 0x80; /* enabled */
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ g_free(t);
+ return;
+ }
+ t->instance = qemu_opt_get_number(opts, "instance", 1);
+ save_opt(&t->pcidev, opts, "pcidev");
+
+ QTAILQ_INSERT_TAIL(&type41, t, next);
+ return;
+ }
default:
error_setg(errp,
"Don't know how to build fields for SMBIOS type %ld",