[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stable-9.1.3 06/58] qdev: Fix set_pci_devfn() to visit option only once
From: |
Michael Tokarev |
Subject: |
[Stable-9.1.3 06/58] qdev: Fix set_pci_devfn() to visit option only once |
Date: |
Mon, 27 Jan 2025 23:24:52 +0300 |
pci_devfn properties accept either a string or an integer as input. To
implement this, set_pci_devfn() first tries to visit the option as a
string, and if that fails, it visits it as an integer instead. While the
QemuOpts visitor happens to accept this, it is invalid according to the
visitor interface. QObject input visitors run into an assertion failure
when this is done.
QObject input visitors are used with the JSON syntax version of -device
on the command line:
$ ./qemu-system-x86_64 -enable-kvm -M q35 -device
pcie-pci-bridge,id=pci.1,bus=pcie.0 -blockdev null-co,node-name=disk -device '{
"driver": "virtio-blk-pci", "drive": "disk", "id": "virtio-disk0", "bus":
"pci.1", "addr": 1 }'
qemu-system-x86_64: ../qapi/qobject-input-visitor.c:143: QObject
*qobject_input_try_get_object(QObjectInputVisitor *, const char *, _Bool):
Assertion `removed' failed.
The proper way to accept both strings and integers is using the
alternate mechanism, which tells us the type of the input before it's
visited. With this information, we can directly visit it as the right
type.
This fixes set_pci_devfn() by using the alternate mechanism.
Cc: qemu-stable@nongnu.org
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20241119120353.57812-1-kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 5102f9df4a9a7adfbd902f9515c3f8f53dba288e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index f13350b4fb..30e040f98e 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -794,39 +794,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const
char *name,
void *opaque, Error **errp)
{
Property *prop = opaque;
+ g_autofree GenericAlternate *alt;
int32_t value, *ptr = object_field_prop_ptr(obj, prop);
unsigned int slot, fn, n;
- char *str;
+ g_autofree char *str = NULL;
+
+ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) {
+ return;
+ }
+
+ switch (alt->type) {
+ case QTYPE_QSTRING:
+ if (!visit_type_str(v, name, &str, errp)) {
+ goto out;
+ }
- if (!visit_type_str(v, name, &str, NULL)) {
+ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
+ fn = 0;
+ if (sscanf(str, "%x%n", &slot, &n) != 1) {
+ goto invalid;
+ }
+ }
+ if (str[n] != '\0' || fn > 7 || slot > 31) {
+ goto invalid;
+ }
+ *ptr = slot << 3 | fn;
+ break;
+
+ case QTYPE_QNUM:
if (!visit_type_int32(v, name, &value, errp)) {
- return;
+ goto out;
}
if (value < -1 || value > 255) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name ? name : "null", "a value between -1 and 255");
- return;
+ goto out;
}
*ptr = value;
- return;
- }
+ break;
- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
- fn = 0;
- if (sscanf(str, "%x%n", &slot, &n) != 1) {
- goto invalid;
- }
- }
- if (str[n] != '\0' || fn > 7 || slot > 31) {
- goto invalid;
+ default:
+ error_setg(errp, "Invalid parameter type for '%s', expected int or
str",
+ name ? name : "null");
+ goto out;
}
- *ptr = slot << 3 | fn;
- g_free(str);
- return;
+
+ goto out;
invalid:
error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
- g_free(str);
+out:
+ visit_end_alternate(v, (void **) &alt);
}
static int print_pci_devfn(Object *obj, Property *prop, char *dest,
--
2.39.5
- [Stable-9.1.3 00/58] Patch Round-up for stable 9.1.3, freeze on 2025-02-06, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 02/58] bitops.h: Define bit operations on 'uint32_t' arrays, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 03/58] hw/intc/loongarch_extioi: Use set_bit32() and clear_bit32() for s->isr, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 04/58] linux-user: Fix strace output for s390x mmap(), Michael Tokarev, 2025/01/28
- [Stable-9.1.3 01/58] hw/intc/openpic: Avoid taking address of out-of-bounds array index, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 09/58] migration: Allow pipes to keep working for fd migrations, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 05/58] virtio-net: Fix size check in dhclient workaround, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 06/58] qdev: Fix set_pci_devfn() to visit option only once,
Michael Tokarev <=
- [Stable-9.1.3 07/58] ssh: Do not switch session to non-blocking mode, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 08/58] plugins: add missing export for qemu_plugin_num_vcpus, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 10/58] virtio-net: Add queues before loading them, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 11/58] ppc/spapr: fix drc index mismatch for partially enabled vcpus, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 12/58] scsi: megasas: Internal cdbs have 16-byte length, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 13/58] tests/9p: fix Rreaddir response name, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 14/58] tests/9p: add missing Rgetattr response name, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 16/58] 9pfs: remove obsolete comment in v9fs_getattr(), Michael Tokarev, 2025/01/28
- [Stable-9.1.3 15/58] tests/9p: add 'use-after-unlink' test, Michael Tokarev, 2025/01/28
- [Stable-9.1.3 17/58] 9pfs: fix 'Tgetattr' after unlink, Michael Tokarev, 2025/01/28