From 0c49c9180c5498bcd55edc1bfb12b0466e08575c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Sep 2023 17:41:17 +0200 Subject: [PATCH 1/9] target/i386: enumerate bit 56 of MSR_IA32_VMX_BASIC On parts that enumerate IA32_VMX_BASIC MSR bit as 1, any exception vector can be delivered with or without an error code if the other consistency checks are satisfied. Signed-off-by: Paolo Bonzini --- scripts/kvm/vmxcap | 1 + target/i386/cpu.c | 1 + target/i386/cpu.h | 1 + 3 files changed, 3 insertions(+) diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index ce27f5e635..3fb4d5b342 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -115,6 +115,7 @@ controls = [ (50, 53): 'VMCS memory type', 54: 'INS/OUTS instruction information', 55: 'IA32_VMX_TRUE_*_CTLS support', + 56: 'Skip checks on event error code', }, msr = MSR_IA32_VMX_BASIC, ), diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b2a20365e1..d48607b4e1 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1340,6 +1340,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .feat_names = { [54] = "vmx-ins-outs", [55] = "vmx-true-ctls", + [56] = "vmx-any-errcode", }, .msr = { .index = MSR_IA32_VMX_BASIC, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index fbb05eace5..d1ffadd78b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1039,6 +1039,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, #define MSR_VMX_BASIC_DUAL_MONITOR (1ULL << 49) #define MSR_VMX_BASIC_INS_OUTS (1ULL << 54) #define MSR_VMX_BASIC_TRUE_CTLS (1ULL << 55) +#define MSR_VMX_BASIC_ANY_ERRCODE (1ULL << 56) #define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK 0x1Full #define MSR_VMX_MISC_STORE_LMA (1ULL << 5) From 3a2a1f97ea349745094e789e6b0768dbd92d0dcd Mon Sep 17 00:00:00 2001 From: Pawan Gupta Date: Mon, 14 Aug 2023 21:54:27 -0700 Subject: [PATCH 2/9] target/i386: Export GDS_NO bit to guests Gather Data Sampling (GDS) is a side-channel attack using Gather instructions. Some Intel processors will set ARCH_CAP_GDS_NO bit in MSR IA32_ARCH_CAPABILITIES to report that they are not vulnerable to GDS. Make this bit available to guests. Closes: https://lore.kernel.org/qemu-devel/CAMGffEmG6TNq0n3+4OJAgXc8J0OevY60KHZekXCBs3LoK9vehA@mail.gmail.com/ Reported-by: Jack Wang Signed-off-by: Pawan Gupta Tested-by: Jack Wang Tested-by: Daniel Sneddon Message-ID: Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index d48607b4e1..f9e51a9d87 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1155,7 +1155,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", NULL, "fb-clear", NULL, NULL, NULL, NULL, NULL, NULL, - "pbrsb-no", NULL, NULL, NULL, + "pbrsb-no", NULL, "gds-no", NULL, NULL, NULL, NULL, NULL, }, .msr = { From e8eed838ec93314c164bf3416d80c9c893a2e8ee Mon Sep 17 00:00:00 2001 From: LIU Zhiwei Date: Mon, 11 Sep 2023 14:32:23 +0800 Subject: [PATCH 3/9] qemu/timer: Add host ticks function for RISC-V Signed-off-by: LIU Zhiwei Message-ID: <20230911063223.742-1-zhiwei_liu@linux.alibaba.com> Signed-off-by: Paolo Bonzini --- include/qemu/timer.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 9a91cb1248..9a366e551f 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -979,6 +979,28 @@ static inline int64_t cpu_get_host_ticks(void) return cur - ofs; } +#elif defined(__riscv) && __riscv_xlen == 32 +static inline int64_t cpu_get_host_ticks(void) +{ + uint32_t lo, hi, tmph; + do { + asm volatile("RDTIMEH %0\n\t" + "RDTIME %1\n\t" + "RDTIMEH %2" + : "=r"(hi), "=r"(lo), "=r"(tmph)); + } while (unlikely(tmph != hi)); + return lo | (uint64_t)hi << 32; +} + +#elif defined(__riscv) && __riscv_xlen > 32 +static inline int64_t cpu_get_host_ticks(void) +{ + int64_t val; + + asm volatile("RDTIME %0" : "=r"(val)); + return val; +} + #else /* The host CPU doesn't have an easily accessible cycle counter. Just return a monotonically increasing value. This will be From 38e476e88e7d5294c194d36d33e12f3d936a7e6a Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Mon, 25 Apr 2022 10:21:45 +0200 Subject: [PATCH 4/9] hw/input/tsc210x: Extract common init code into new function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This deduplicates several lines and will make future changes more concise. Signed-off-by: Martin Kletzander Reviewed-by: Daniel P. Berrangé Message-ID: <1d75877cf4cc2a38f87633ff16f9fea3e1bb0c03.1650874791.git.mkletzan@redhat.com> Signed-off-by: Paolo Bonzini --- hw/input/tsc210x.c | 68 ++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c index 7eae5989f7..f568759e05 100644 --- a/hw/input/tsc210x.c +++ b/hw/input/tsc210x.c @@ -30,6 +30,7 @@ #include "hw/input/tsc2xxx.h" #include "hw/irq.h" #include "migration/vmstate.h" +#include "qapi/error.h" #define TSC_DATA_REGISTERS_PAGE 0x0 #define TSC_CONTROL_REGISTERS_PAGE 0x1 @@ -1069,20 +1070,10 @@ static const VMStateDescription vmstate_tsc2301 = { .fields = vmstatefields_tsc210x, }; -uWireSlave *tsc2102_init(qemu_irq pint) +static void tsc210x_init(TSC210xState *s, + const char *name, + const VMStateDescription *vmsd) { - TSC210xState *s; - - s = g_new0(TSC210xState, 1); - s->x = 160; - s->y = 160; - s->pressure = 0; - s->precision = s->nextprecision = 0; - s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s); - s->pint = pint; - s->model = 0x2102; - s->name = "tsc2102"; - s->tr[0] = 0; s->tr[1] = 1; s->tr[2] = 1; @@ -1104,13 +1095,29 @@ uWireSlave *tsc2102_init(qemu_irq pint) tsc210x_reset(s); - qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, - "QEMU TSC2102-driven Touchscreen"); + qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, name); AUD_register_card(s->name, &s->card); qemu_register_reset((void *) tsc210x_reset, s); - vmstate_register(NULL, 0, &vmstate_tsc2102, s); + vmstate_register(NULL, 0, vmsd, s); +} + +uWireSlave *tsc2102_init(qemu_irq pint) +{ + TSC210xState *s; + + s = g_new0(TSC210xState, 1); + s->x = 160; + s->y = 160; + s->pressure = 0; + s->precision = s->nextprecision = 0; + s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s); + s->pint = pint; + s->model = 0x2102; + s->name = "tsc2102"; + + tsc210x_init(s, "QEMU TSC2102-driven Touchscreen", &vmstate_tsc2102); return &s->chip; } @@ -1131,34 +1138,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav) s->model = 0x2301; s->name = "tsc2301"; - s->tr[0] = 0; - s->tr[1] = 1; - s->tr[2] = 1; - s->tr[3] = 0; - s->tr[4] = 1; - s->tr[5] = 0; - s->tr[6] = 1; - s->tr[7] = 0; - - s->chip.opaque = s; - s->chip.send = (void *) tsc210x_write; - s->chip.receive = (void *) tsc210x_read; - - s->codec.opaque = s; - s->codec.tx_swallow = (void *) tsc210x_i2s_swallow; - s->codec.set_rate = (void *) tsc210x_i2s_set_rate; - s->codec.in.fifo = s->in_fifo; - s->codec.out.fifo = s->out_fifo; - - tsc210x_reset(s); - - qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, - "QEMU TSC2301-driven Touchscreen"); - - AUD_register_card(s->name, &s->card); - - qemu_register_reset((void *) tsc210x_reset, s); - vmstate_register(NULL, 0, &vmstate_tsc2301, s); + tsc210x_init(s, "QEMU TSC2301-driven Touchscreen", &vmstate_tsc2301); return &s->chip; } From b7639b7dd05de6d4f5ac2a30bb4a7a789286992f Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Mon, 25 Apr 2022 10:21:46 +0200 Subject: [PATCH 5/9] hw/audio: Simplify hda audio init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No return values are used anywhere, so switch the functions to be void and add support for error reporting using errp for use in next patches. Signed-off-by: Martin Kletzander Reviewed-by: Daniel P. Berrangé Message-ID: Signed-off-by: Paolo Bonzini --- hw/audio/hda-codec.c | 32 ++++++++++++++++++-------------- hw/audio/intel-hda.c | 4 +--- hw/audio/intel-hda.h | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index c51d8ba617..a26048cf15 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -675,7 +675,9 @@ static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, b } } -static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) +static void hda_audio_init(HDACodecDevice *hda, + const struct desc_codec *desc, + Error **errp) { HDAAudioState *a = HDA_AUDIO(hda); HDAAudioStream *st; @@ -718,7 +720,6 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) break; } } - return 0; } static void hda_audio_exit(HDACodecDevice *hda) @@ -848,37 +849,40 @@ static Property hda_audio_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static int hda_audio_init_output(HDACodecDevice *hda) +static void hda_audio_init_output(HDACodecDevice *hda, Error **errp) { HDAAudioState *a = HDA_AUDIO(hda); + const struct desc_codec *desc = &output_nomixemu; if (!a->mixer) { - return hda_audio_init(hda, &output_nomixemu); - } else { - return hda_audio_init(hda, &output_mixemu); + desc = &output_mixemu; } + + hda_audio_init(hda, desc, errp); } -static int hda_audio_init_duplex(HDACodecDevice *hda) +static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp) { HDAAudioState *a = HDA_AUDIO(hda); + const struct desc_codec *desc = &duplex_nomixemu; if (!a->mixer) { - return hda_audio_init(hda, &duplex_nomixemu); - } else { - return hda_audio_init(hda, &duplex_mixemu); + desc = &duplex_mixemu; } + + hda_audio_init(hda, desc, errp); } -static int hda_audio_init_micro(HDACodecDevice *hda) +static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp) { HDAAudioState *a = HDA_AUDIO(hda); + const struct desc_codec *desc = µ_nomixemu; if (!a->mixer) { - return hda_audio_init(hda, µ_nomixemu); - } else { - return hda_audio_init(hda, µ_mixemu); + desc = µ_mixemu; } + + hda_audio_init(hda, desc, errp); } static void hda_audio_base_class_init(ObjectClass *klass, void *data) diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index b9ed231fe8..78ff9f9a68 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -71,9 +71,7 @@ static void hda_codec_dev_realize(DeviceState *qdev, Error **errp) return; } bus->next_cad = dev->cad + 1; - if (cdc->init(dev) != 0) { - error_setg(errp, "HDA audio init failed"); - } + cdc->init(dev, errp); } static void hda_codec_dev_unrealize(DeviceState *qdev) diff --git a/hw/audio/intel-hda.h b/hw/audio/intel-hda.h index f78c1833e3..8d710eee5d 100644 --- a/hw/audio/intel-hda.h +++ b/hw/audio/intel-hda.h @@ -31,7 +31,7 @@ struct HDACodecBus { struct HDACodecDeviceClass { DeviceClass parent_class; - int (*init)(HDACodecDevice *dev); + void (*init)(HDACodecDevice *dev, Error **errp); void (*exit)(HDACodecDevice *dev); void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data); void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output); From 79d3e56c2071d402fd55f135aea872d8fe24d269 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Mon, 25 Apr 2022 10:21:47 +0200 Subject: [PATCH 6/9] hw/audio/lm4549: Add errp error reporting to init function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used in future commit. Signed-off-by: Martin Kletzander Reviewed-by: Daniel P. Berrangé Message-ID: Signed-off-by: Paolo Bonzini --- hw/audio/lm4549.c | 3 ++- hw/audio/lm4549.h | 3 ++- hw/audio/pl041.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/audio/lm4549.c b/hw/audio/lm4549.c index 32b1481b56..418041bc9c 100644 --- a/hw/audio/lm4549.c +++ b/hw/audio/lm4549.c @@ -276,7 +276,8 @@ static int lm4549_post_load(void *opaque, int version_id) return 0; } -void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque) +void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque, + Error **errp) { struct audsettings as; diff --git a/hw/audio/lm4549.h b/hw/audio/lm4549.h index aba9bb5b07..61c3ab12dd 100644 --- a/hw/audio/lm4549.h +++ b/hw/audio/lm4549.h @@ -36,7 +36,8 @@ typedef struct { extern const VMStateDescription vmstate_lm4549_state; -void lm4549_init(lm4549_state *s, lm4549_callback data_req, void *opaque); +void lm4549_init(lm4549_state *s, lm4549_callback data_req, void *opaque, + Error **errp); uint32_t lm4549_read(lm4549_state *s, hwaddr offset); void lm4549_write(lm4549_state *s, hwaddr offset, uint32_t value); uint32_t lm4549_write_samples(lm4549_state *s, uint32_t left, uint32_t right); diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index 03acd4fe34..868dffbfd3 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -564,7 +564,7 @@ static void pl041_realize(DeviceState *dev, Error **errp) } /* Init the codec */ - lm4549_init(&s->codec, &pl041_request_data, (void *)s); + lm4549_init(&s->codec, &pl041_request_data, (void *)s, errp); } static const VMStateDescription vmstate_pl041_regfile = { From fac7e497ca3ee088330b19b915ed09e67fcfce4c Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Mon, 25 Apr 2022 10:21:52 +0200 Subject: [PATCH 7/9] hw/display/xlnx_dp.c: Add audiodev property There was no way to set this and we need that for it to be able to properly initialise. Signed-off-by: Martin Kletzander Message-ID: <16963256573fcbfa7720aa2fd000ba74a4055222.1650874791.git.mkletzan@redhat.com> Signed-off-by: Paolo Bonzini --- hw/display/xlnx_dp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 43c7dd8e9c..341e91e886 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1385,6 +1385,11 @@ static void xlnx_dp_reset(DeviceState *dev) xlnx_dp_update_irq(s); } +static Property xlnx_dp_device_properties[] = { + DEFINE_AUDIO_PROPERTIES(XlnxDPState, aud_card), + DEFINE_PROP_END_OF_LIST(), +}; + static void xlnx_dp_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -1392,6 +1397,7 @@ static void xlnx_dp_class_init(ObjectClass *oc, void *data) dc->realize = xlnx_dp_realize; dc->vmsd = &vmstate_dp; dc->reset = xlnx_dp_reset; + device_class_set_props(dc, xlnx_dp_device_properties); } static const TypeInfo xlnx_dp_info = { From 50333482e16939cfeaed722e22f7b0798e5b3821 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Mon, 25 Apr 2022 10:21:48 +0200 Subject: [PATCH 8/9] tests/qtest: Specify audiodev= and -audiodev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will enable removing deprecated default audiodev support. I did not figure out how to make the audiodev represented as an interface node, so this is a workaround. I am not sure what would be the proper way. Signed-off-by: Martin Kletzander Reviewed-by: Daniel P. Berrangé Message-ID: <6e7f2808dd40679a415812767b88f2a411fc137f.1650874791.git.mkletzan@redhat.com> Signed-off-by: Paolo Bonzini --- tests/qtest/es1370-test.c | 3 ++- tests/qtest/fuzz/generic_fuzz_configs.h | 6 ++++-- tests/qtest/intel-hda-test.c | 15 ++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/qtest/es1370-test.c b/tests/qtest/es1370-test.c index 97ab65c435..8387e74193 100644 --- a/tests/qtest/es1370-test.c +++ b/tests/qtest/es1370-test.c @@ -46,7 +46,8 @@ static void *es1370_create(void *pci_bus, QGuestAllocator *alloc, void *addr) static void es1370_register_nodes(void) { QOSGraphEdgeOptions opts = { - .extra_device_opts = "addr=04.0", + .extra_device_opts = "addr=04.0,audiodev=audio0", + .before_cmd_line = "-audiodev driver=none,id=audio0", }; add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) }); diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index 50689da653..4d7c8ca4ec 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -106,8 +106,10 @@ const generic_fuzz_config predefined_configs[] = { },{ .name = "intel-hda", .args = "-machine q35 -nodefaults -device intel-hda,id=hda0 " - "-device hda-output,bus=hda0.0 -device hda-micro,bus=hda0.0 " - "-device hda-duplex,bus=hda0.0", + "-audiodev driver=none,id=audio0", + "-device hda-output,bus=hda0.0,audiodev=audio0 " + "-device hda-micro,bus=hda0.0,audiodev=audio0 " + "-device hda-duplex,bus=hda0.0,audiodev=audio0", .objects = "intel-hda", },{ .name = "ide-hd", diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c index d4a8db6fd6..663bb6c485 100644 --- a/tests/qtest/intel-hda-test.c +++ b/tests/qtest/intel-hda-test.c @@ -11,20 +11,24 @@ #include "libqtest-single.h" #define HDA_ID "hda0" -#define CODEC_DEVICES " -device hda-output,bus=" HDA_ID ".0" \ - " -device hda-micro,bus=" HDA_ID ".0" \ - " -device hda-duplex,bus=" HDA_ID ".0" +#define AUDIODEV " -audiodev driver=none,id=audio0 " +#define AUDIODEV_REF "audiodev=audio0" +#define CODEC_DEVICES " -device hda-output,bus=" HDA_ID ".0," AUDIODEV_REF \ + " -device hda-micro,bus=" HDA_ID ".0," AUDIODEV_REF \ + " -device hda-duplex,bus=" HDA_ID ".0," AUDIODEV_REF /* Tests only initialization so far. TODO: Replace with functional tests */ static void ich6_test(void) { - qtest_start("-machine pc -device intel-hda,id=" HDA_ID CODEC_DEVICES); + qtest_start(AUDIODEV "-machine pc -device intel-hda,id=" HDA_ID CODEC_DEVICES); qtest_end(); } static void ich9_test(void) { - qtest_start("-machine q35 -device ich9-intel-hda,bus=pcie.0,addr=1b.0,id=" + qtest_start("-machine q35" + AUDIODEV + "-device ich9-intel-hda,bus=pcie.0,addr=1b.0,id=" HDA_ID CODEC_DEVICES); qtest_end(); } @@ -39,6 +43,7 @@ static void test_issue542_ich6(void) QTestState *s; s = qtest_init("-nographic -nodefaults -M pc-q35-6.2 " + AUDIODEV "-device intel-hda,id=" HDA_ID CODEC_DEVICES); qtest_outl(s, 0xcf8, 0x80000804); From adf7f6b72fb6d10e00e93d04dfa33ce8c5e384c8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 21 Sep 2023 14:04:39 +0200 Subject: [PATCH 9/9] vl: recognize audiodev groups in configuration files This is necessary for the q35 configuration tests to pass, once audiodev becomes mandatory. Signed-off-by: Paolo Bonzini --- docs/config/q35-emulated.cfg | 4 ++++ docs/config/q35-virtio-graphical.cfg | 4 ++++ softmmu/vl.c | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/docs/config/q35-emulated.cfg b/docs/config/q35-emulated.cfg index c8806e6d36..b4bd7e858a 100644 --- a/docs/config/q35-emulated.cfg +++ b/docs/config/q35-emulated.cfg @@ -288,3 +288,7 @@ driver = "hda-duplex" bus = "ich9-hda-audio.0" cad = "0" + audiodev = "audiodev0" + +[audiodev "audiodev0"] + driver = "none" # CHANGE ME diff --git a/docs/config/q35-virtio-graphical.cfg b/docs/config/q35-virtio-graphical.cfg index 148b5d2c5e..820860aefe 100644 --- a/docs/config/q35-virtio-graphical.cfg +++ b/docs/config/q35-virtio-graphical.cfg @@ -248,3 +248,7 @@ driver = "hda-duplex" bus = "sound.0" cad = "0" + audiodev = "audiodev0" + +[audiodev "audiodev0"] + driver = "none" # CHANGE ME diff --git a/softmmu/vl.c b/softmmu/vl.c index 3db4fd2680..db04f98c36 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2125,6 +2125,7 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) static bool is_qemuopts_group(const char *group) { if (g_str_equal(group, "object") || + g_str_equal(group, "audiodev") || g_str_equal(group, "machine") || g_str_equal(group, "smp-opts") || g_str_equal(group, "boot-opts")) { @@ -2140,6 +2141,15 @@ static void qemu_record_config_group(const char *group, QDict *dict, Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict)); object_option_add_visitor(v); visit_free(v); + + } else if (g_str_equal(group, "audiodev")) { + Audiodev *dev = NULL; + Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict)); + if (visit_type_Audiodev(v, NULL, &dev, errp)) { + audio_define(dev); + } + visit_free(v); + } else if (g_str_equal(group, "machine")) { /* * Cannot merge string-valued and type-safe dictionaries, so JSON