Re: Intention to work on GSoC project
Hi, Thank you for your email. On Thursday, March 14, 2024 8:39:45 PM IST Eugenio Perez Martin wrote: > Hi Sahil, > > It's being hard to find a good self-contained small task related to > the project to be honest. As it would be out of SVQ, would it be ok > for you if we start straight to the task of adding the packed vq > format to SVQ? > > Thanks! Sure, this works too! I would love to get started with the project. I have a small update as well. I have read through a few docs and articles to familiarize myself with the relevant terminology and technicalities. 1. "About", "system emulation" and "user mode emulation" sections of the user documentation [1] 2. The migration subsystem [2] Some sections in the above docs were difficult to grasp. For the time being, I have focused on those parts that I thought were relevant to the project. I have also read through the following articles: 1. Introduction to virtio-networking and vhost-net [3] 2. Deep dive into Virtio-networking and vhost-net [4] 3. Virtualized Hardware Devices [5] 4. VFIO - "Virtual Function I/O" (Just the introduction) [6] 5. Virtio-net failover: An introduction [7] I hope I haven't gone off on a tangent. I was planning to finish reading up on the following articles as well: 1. Virtqueues and virtio ring: How the data travels [8] 2. Packed virtqueue: How to reduce overhead with virtio [9] 3. Virtio live migration technical deep dive [10] 4. Hands on vDPA: what do you do when you ain't got the hardware v2 (Part 1) [11] I believe the hands-on vPDA article will have me set up a development environment for the project as well. Please let me know if I should amend my roadmap. I am excited to get started :) Thanks, Sahil [1] https://www.qemu.org/docs/master/index.html [2] https://www.qemu.org/docs/master/devel/migration/index.html [3] https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net [4] https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net [5] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_getting_started_guide/sec-virtualization_getting_started-products-virtualized-hardware-devices [6] https://www.kernel.org/doc/html/latest/driver-api/vfio.html [7] https://www.redhat.com/en/blog/virtio-net-failover-introduction [8] https://www.redhat.com/en/blog/virtqueues-and-virtio-ring-how-data-travels [9] https://developers.redhat.com/articles/2024/02/21/virtio-live-migration-technical-deep-dive [10] https://www.redhat.com/en/blog/packed-virtqueue-how-reduce-overhead-virtio [11] https://www.redhat.com/en/blog/hands-vdpa-what-do-you-do-when-you-aint-got-hardware-part-1
[PATCH V5] target/loongarch: Fix tlb huge page loading issue
When we use qemu tcg simulation, the page size of bios is 4KB. When using the level 2 super huge page (page size is 1G) to create the page table, it is found that the content of the corresponding address space is abnormal, resulting in the bios can not start the operating system and graphical interface normally. The lddir and ldpte instruction emulation has a problem with the use of super huge page processing above level 2. The page size is not correctly calculated, resulting in the wrong page size of the table entry found by tlb. Signed-off-by: Xianglai Li --- target/loongarch/cpu-csr.h| 3 + target/loongarch/internals.h | 5 -- target/loongarch/tcg/tlb_helper.c | 111 +- 3 files changed, 80 insertions(+), 39 deletions(-) Changes log: V4->V5: Modifying the patch Title. Fix incorrect usage of FIELD macro and code logic errors in patch. V3->V4: Optimize the huge page calculation method, use the FIELD macro for bit calculation. V2->V3: Delete the intermediate variable LDDIR_PS, and implement lddir and ldpte huge pages by referring to the latest architecture reference manual. V1->V2: Modified the patch title format and Enrich the commit mesg description diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h index c59d7a9fcb..0834e91f30 100644 --- a/target/loongarch/cpu-csr.h +++ b/target/loongarch/cpu-csr.h @@ -67,6 +67,9 @@ FIELD(TLBENTRY, D, 1, 1) FIELD(TLBENTRY, PLV, 2, 2) FIELD(TLBENTRY, MAT, 4, 2) FIELD(TLBENTRY, G, 6, 1) +FIELD(TLBENTRY, HUGE, 6, 1) +FIELD(TLBENTRY, HGLOBAL, 12, 1) +FIELD(TLBENTRY, LEVEL, 13, 2) FIELD(TLBENTRY_32, PPN, 8, 24) FIELD(TLBENTRY_64, PPN, 12, 36) FIELD(TLBENTRY_64, NR, 61, 1) diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index a2fc54c8a7..944153b180 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -16,11 +16,6 @@ #define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS) #define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS) -/* Global bit used for lddir/ldpte */ -#define LOONGARCH_PAGE_HUGE_SHIFT 6 -/* Global bit for huge page */ -#define LOONGARCH_HGLOBAL_SHIFT 12 - void loongarch_translate_init(void); void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 22be031ac7..1d22afddd3 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -17,6 +17,34 @@ #include "exec/log.h" #include "cpu-csr.h" +static void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, + uint64_t *dir_width, target_ulong level) +{ +switch (level) { +case 1: +*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); +*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); +break; +case 2: +*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); +*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); +break; +case 3: +*dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); +*dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); +break; +case 4: +*dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); +*dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); +break; +default: +/* level may be zero for ldpte */ +*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); +*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); +break; +} +} + static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, MMUAccessType access_type, int tlb_error) { @@ -485,7 +513,23 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, target_ulong badvaddr, index, phys, ret; int shift; uint64_t dir_base, dir_width; -bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1; + +if (unlikely((level == 0) || (level > 4))) { +return base; +} + +if (FIELD_EX64(base, TLBENTRY, HUGE)) { +if (unlikely(level == 4)) { +qemu_log_mask(LOG_GUEST_ERROR, + "Attempted use of level %lu huge page\n", level); +} + +if (FIELD_EX64(base, TLBENTRY, LEVEL)) { +return base; +} else { +return FIELD_DP64(base, TLBENTRY, LEVEL, level); +} +} badvaddr = env->CSR_TLBRBADV; base = base & TARGET_PHYS_MASK; @@ -494,30 +538,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); shift = (shift + 1) * 3; -if (huge) { -return base; -} -switch (level) { -case 1: -dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); -dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_W
Re: [PATCH] target/i386: Export RFDS bit to guests
Hi Pawan, On Wed, Mar 13, 2024 at 07:53:23AM -0700, Pawan Gupta wrote: > Date: Wed, 13 Mar 2024 07:53:23 -0700 > From: Pawan Gupta > Subject: [PATCH] target/i386: Export RFDS bit to guests > > Register File Data Sampling (RFDS) is a CPU side-channel vulnerability > that may expose stale register value. CPUs that set RFDS_NO bit in MSR > IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS. > Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has > the microcode to help mitigate RFDS. > > Make RFDS_CLEAR and RFDS_NO bits available to guests. Are these two bits going to be supported by microcode updates to existing products? (Let me aslo attach the related spec to make it easy for more people to learn about backgrounds: https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/register-file-data-sampling.html) > Signed-off-by: Pawan Gupta > --- > target/i386/cpu.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) LGTM, Reviewed-by: Zhao Liu
Re: [PATCH for 9.0 v15 03/10] target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
On 3/14/24 07:56, Daniel Henrique Barboza wrote: vmvr_v isn't handling the case where the host might be big endian and the bytes to be copied aren't sequential. Suggested-by: Richard Henderson Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR") Signed-off-by: Daniel Henrique Barboza --- target/riscv/vector_helper.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) Reviewed-by: Richard Henderson r~
Re: [PATCH for 9.0 v15 04/10] target/riscv: always clear vstart in whole vec move insns
On 3/14/24 07:56, Daniel Henrique Barboza wrote: These insns have 2 paths: we'll either have vstart already cleared if vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call the 'vmvr_v' helper. The helper will clear vstart if it executes until the end, or if vstart >= vl. For starters, the check itself is wrong: we're checking vstart >= maxsz, when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is calling, to do the comparison. But even after fixing the comparison we'll still need to clear vstart in the end, which isn't happening too. We want to make the helpers responsible to manage vstart, including these corner cases, precisely to avoid these situations: - remove the wrong vstart >= maxsz cond from the translation; - add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that happens. This way we're now sure that vstart is being cleared in the end of the execution, regardless of the path taken. Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR") Signed-off-by: Daniel Henrique Barboza --- target/riscv/insn_trans/trans_rvv.c.inc | 3 --- target/riscv/vector_helper.c| 5 + 2 files changed, 5 insertions(+), 3 deletions(-) Reviewed-by: Richard Henderson r~
Re: [PATCH V4 1/1] target/loongarch: Fixed tlb huge page loading issue
On 3/14/24 20:22, lixianglai wrote: Hi Richard: On 3/13/24 15:33, Xianglai Li wrote: + if (unlikely((level == 0) || (level > 4))) { + return base; + } ... Perhaps it would be worthwhile to add another for the level==0 or > 4 case above? A normal level 4 page table should not print an error log, only if a level 4 page is large, so we should put it in if (FIELD_EX64(base, TLBENTRY, HUGE)) { if (unlikely(level == 4)) { qemu_log_mask(LOG_GUEST_ERROR, "Attempted use of level %lu huge page\n", level); } if (FIELD_EX64(base, TLBENTRY, LEVEL)) { return base; } else { return FIELD_DP64(base, TLBENTRY, LEVEL, level); } } A level 5 page table is not normal, nor is a level 0 lddir. r~
Re: [PATCH v4 0/3] Adjust the output of x-query-virtio-status
"Michael S. Tsirkin" writes: > On Wed, Mar 13, 2024 at 10:40:21AM +0100, Markus Armbruster wrote: >> I could be awkward for the use case described in PATCH 1's commit >> message: >> >> However, we sometimes want to compare features and status bits without >> caring for their exact meaning. Say we want to verify the correctness >> of the virtio negotiation between guest, QEMU, and OVS-DPDK. We can use >> QMP command x-query-virtio-status to retrieve vhost-user net device >> features, and the "ovs-vsctl list interface" command to retrieve >> interface features. Without commit f3034ad71fc, we could then simply >> compare the numbers. With this commit, we first have to map from the >> strings back to the numeric encoding. > > So, consider how guest kernel presents features then. Do you happen to know? > It's actually a binary string: > > static ssize_t features_show(struct device *_d, > struct device_attribute *attr, char *buf) > { > struct virtio_device *dev = dev_to_virtio(_d); > unsigned int i; > ssize_t len = 0; > > /* We actually represent this as a bitstring, as it could be > * arbitrary length in future. */ > for (i = 0; i < sizeof(dev->features)*8; i++) > len += sysfs_emit_at(buf, len, "%c", >__virtio_test_bit(dev, i) ? '1' : '0'); > len += sysfs_emit_at(buf, len, "\n"); > return len; > } > static DEVICE_ATTR_RO(features); I'm willing to accept any reasonably compact representation of the bits that is easy to use for the comparison use case. I strongly prefer integers as long as their width suffices. Since out integers are limited to 64 bits, and you want us to design for more, we need something else. I'm fine with array of integers, but you don't like it. We generally avoid encoding stuff in strings, but using strings for "overwide" integers isn't as bad as using them for structured data. I guess I'd be okay with it. I'd use decimal simply to keep these "overwide" integers as close as possible to regular ones. If using base 2 enables string compare for the comparison use case, that's an argument for base 2. Hyman Huang, can you show us example output of "ovs-vsctl list interface"?
Re: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err check
On Thu, Feb 29, 2024 at 11:37:38AM +0800, Zhenzhong Duan wrote: > Date: Thu, 29 Feb 2024 11:37:38 +0800 > From: Zhenzhong Duan > Subject: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err > check > X-Mailer: git-send-email 2.34.1 > > In the error return path, local_err is always set, no need to check it. The original error handling code indicates "local_err is always set", and error_propagate() can handle the case that local_err is NULL. > Signed-off-by: Zhenzhong Duan > --- > qom/object_interfaces.c | 10 -- > 1 file changed, 4 insertions(+), 6 deletions(-) > > diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c > index e0833c8bfe..255a7bf659 100644 > --- a/qom/object_interfaces.c > +++ b/qom/object_interfaces.c > @@ -128,13 +128,11 @@ Object *user_creatable_add_type(const char *type, const > char *id, > } > goto out; > } > -out: > -if (local_err) { > -error_propagate(errp, local_err); > -object_unref(obj); > -return NULL; > -} > return obj; > +out: Maybe rename this to "err:"? Since now it's just used to handle error, and "goto err" seems more clear. > +error_propagate(errp, local_err); > +object_unref(obj); > +return NULL; > } > > void user_creatable_add_qapi(ObjectOptions *options, Error **errp) > -- > 2.34.1 > Otherwise, Reviewed-by: Zhao Liu
Re: [PATCH 2/2] qom/object_interfaces: Remove local_err in user_creatable_add_type
On Thu, Feb 29, 2024 at 11:37:39AM +0800, Zhenzhong Duan wrote: > Date: Thu, 29 Feb 2024 11:37:39 +0800 > From: Zhenzhong Duan > Subject: [PATCH 2/2] qom/object_interfaces: Remove local_err in > user_creatable_add_type > X-Mailer: git-send-email 2.34.1 > > In user_creatable_add_type, there is mixed usage of ERRP_GUARD and > local_err. This makes error_abort not taking effect in those callee > functions with local_err passed. > > Now that we already has ERRP_GUARD, remove local_err and use *errp > instead. > > Signed-off-by: Zhenzhong Duan > --- > qom/object_interfaces.c | 12 +--- > 1 file changed, 5 insertions(+), 7 deletions(-) > > diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c > index 255a7bf659..165cd433e7 100644 > --- a/qom/object_interfaces.c > +++ b/qom/object_interfaces.c > @@ -81,7 +81,6 @@ Object *user_creatable_add_type(const char *type, const > char *id, > ERRP_GUARD(); > Object *obj; > ObjectClass *klass; > -Error *local_err = NULL; > > if (id != NULL && !id_wellformed(id)) { > error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an > identifier"); > @@ -109,20 +108,20 @@ Object *user_creatable_add_type(const char *type, const > char *id, > > assert(qdict); > obj = object_new(type); > -object_set_properties_from_qdict(obj, qdict, v, &local_err); > -if (local_err) { > +object_set_properties_from_qdict(obj, qdict, v, errp); It's better to make object_set_properties_from_qdict someting (e.g., boolean). Maybe an extra cleanup? > +if (*errp) { > goto out; > } > > if (id != NULL) { > object_property_try_add_child(object_get_objects_root(), > - id, obj, &local_err); > -if (local_err) { > + id, obj, errp); > +if (*errp) { > goto out; > } > } Here we could check whether the returned ObjectProperty* is NULL instaed of dereferencing errp. Thanks, Zhao
Re: [PATCH] vhost-vdpa: check vhost_vdpa_set_vring_ready() return value
On Thu, Mar 14, 2024 at 11:17:01AM +0800, Jason Wang wrote: On Wed, Feb 7, 2024 at 5:27 PM Stefano Garzarella wrote: vhost_vdpa_set_vring_ready() could already fail, but if Linux's patch [1] will be merged, it may fail with more chance if userspace does not activate virtqueues before DRIVER_OK when VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK is not negotiated. I wonder what happens if we just leave it as is. Are you referring to this patch or the kernel patch? Here I'm just checking the return value of vhost_vdpa_set_vring_ready(). It can return an error also without that kernel patch, so IMHO is better to check the return value here in QEMU. What issue do you see with this patch applied? VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK: We do know enabling could be done after driver_ok. Without VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK: We don't know whether enabling could be done after driver_ok or not. I see your point, indeed I didn't send a v2 of that patch. Maybe we should document that, because it could be interpreted that if VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK is not negotiated the enabling should always be done before driver_ok (which is true for example in VDUSE). BTW I think we should discuss it in the kernel patch. Thanks, Stefano Thanks So better check its return value anyway. [1] https://lore.kernel.org/virtualization/20240206145154.118044-1-sgarz...@redhat.com/T/#u Signed-off-by: Stefano Garzarella --- Note: This patch conflicts with [2], but the resolution is simple, so for now I sent a patch for the current master, but I'll rebase this patch if we merge the other one first. [2] https://lore.kernel.org/qemu-devel/20240202132521.32714-1-kw...@redhat.com/ --- hw/virtio/vdpa-dev.c | 8 +++- net/vhost-vdpa.c | 15 --- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c index eb9ecea83b..d57cd76c18 100644 --- a/hw/virtio/vdpa-dev.c +++ b/hw/virtio/vdpa-dev.c @@ -259,7 +259,11 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp) goto err_guest_notifiers; } for (i = 0; i < s->dev.nvqs; ++i) { -vhost_vdpa_set_vring_ready(&s->vdpa, i); +ret = vhost_vdpa_set_vring_ready(&s->vdpa, i); +if (ret < 0) { +error_setg_errno(errp, -ret, "Error starting vring %d", i); +goto err_dev_stop; +} } s->started = true; @@ -274,6 +278,8 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp) return ret; +err_dev_stop: +vhost_dev_stop(&s->dev, vdev, false); err_guest_notifiers: k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); err_host_notifiers: diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 3726ee5d67..e3d8036479 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -381,7 +381,10 @@ static int vhost_vdpa_net_data_load(NetClientState *nc) } for (int i = 0; i < v->dev->nvqs; ++i) { -vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index); +int ret = vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index); +if (ret < 0) { +return ret; +} } return 0; } @@ -1213,7 +1216,10 @@ static int vhost_vdpa_net_cvq_load(NetClientState *nc) assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); -vhost_vdpa_set_vring_ready(v, v->dev->vq_index); +r = vhost_vdpa_set_vring_ready(v, v->dev->vq_index); +if (unlikely(r < 0)) { +return r; +} if (v->shadow_vqs_enabled) { n = VIRTIO_NET(v->dev->vdev); @@ -1252,7 +1258,10 @@ static int vhost_vdpa_net_cvq_load(NetClientState *nc) } for (int i = 0; i < v->dev->vq_index; ++i) { -vhost_vdpa_set_vring_ready(v, i); +r = vhost_vdpa_set_vring_ready(v, i); +if (unlikely(r < 0)) { +return r; +} } return 0; -- 2.43.0
Re: [PATCH v5 49/65] i386/tdx: handle TDG.VP.VMCALL
On 3/13/2024 11:31 PM, Daniel P. Berrangé wrote: On Tue, Mar 12, 2024 at 03:44:32PM +0800, Xiaoyao Li wrote: On 3/11/2024 5:27 PM, Daniel P. Berrangé wrote: On Thu, Feb 29, 2024 at 01:37:10AM -0500, Xiaoyao Li wrote: From: Isaku Yamahata Add property "quote-generation-socket" to tdx-guest, which is a property of type SocketAddress to specify Quote Generation Service(QGS). On request of GetQuote, it connects to the QGS socket, read request data from shared guest memory, send the request data to the QGS, and store the response into shared guest memory, at last notify TD guest by interrupt. command line example: qemu-system-x86_64 \ -object '{"qom-type":"tdx-guest","id":"tdx0","quote-generation-socket":{"type": "vsock", "cid":"1","port":"1234"}}' \ Can you illustrate this with 'unix' sockets, not 'vsock'. Are you suggesting only updating the commit message to an example of unix socket? Or you want the code to test with some unix socket QGS? (It seems the QGS I got for testing, only supports vsock socket. Because at the time when it got developed, it was supposed to communicate with drivers inside TD guest directly not via VMM (KVM+QEMU). Anyway, I will talk to internal folks to see if any plan to support unix socket.) The QGS provided as part of DCAP supports running with both UNIX sockets and VSOCK, and I would expect QEMU to be made to work with this, since its is Intel's OSS reference impl. After synced with internal folks, yes, the QGS I used does support unix socket. I tested it and it worked. -object '{"qom-type":"tdx-guest","id":"tdx","quote-generation-socket":{"type":"unix", "path":"/var/run/tdx-qgs/qgs.socket"}}' Exposing QGS to the guest when we only intend for it to be used by the host QEMU is needlessly expanding the attack surface. With regards, Daniel
Re: [RFC PATCH v3 3/3] migration: Add fd to FileMigrationArgs
On Fri, Mar 15, 2024 at 12:20:40AM -0300, Fabiano Rosas wrote: > The fd: URI has supported migration to a file or socket since before > QEMU 8.2. In 8.2 we added the file: URI that supported migration to a > file. So now we have two ways (three if you count exec:>cat) to > migrate to a file. Fine. > > However, > > In 8.2 we also added the new qmp_migrate API that uses a JSON channel > list instead of the URI. It added two migration transports SOCKET and > FILE. It was decided that the new API would classify the fd migration > as a type of socket migration, neglecting the fact that the fd.c code > also supported file migrations. > > In 9.0 we're adding support for fd + multifd + mapped-ram, which is > tied to the file migration. This was implemented in fd.c, which is > only reachable when the SOCKET address type is used. > > The result of this is that we're asking users of the new API to create (1) > something called a "socket" to perform migration to a plain file. And > creating something called a "file" provides no way of passing in a > file descriptor. This is confusing. The 'file:' protocol eventually calls into qemu_open, and this transparently allows for FD passing using /dev/fdset/NNN syntax to pass in FDs. > diff --git a/qapi/migration.json b/qapi/migration.json > index aa1b39bce1..37f4b9c6fb 100644 > --- a/qapi/migration.json > +++ b/qapi/migration.json > @@ -1656,13 +1656,20 @@ > # > # @filename: The file to receive the migration stream > # > +# @fd: A file descriptor name or number. File descriptors must be > +# first added with the 'getfd' command. (since 9.0). > +# > # @offset: The file offset where the migration stream will start > # > +# Since 9.0, all members are optional, but at least one of @filename > +# or @fd are required. > +# > # Since: 8.2 > ## > { 'struct': 'FileMigrationArgs', > - 'data': { 'filename': 'str', > -'offset': 'uint64' } } > + 'data': { '*filename': 'str', > +'*fd': 'str', > +'*offset': 'uint64' } } Adding 'fd' here is not desirable, because 'filename' is resolved via qemu_open which allows for FD passing without introducing any new syntax in interfaces which take filenames. With regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
[PATCH v3] block: Use LVM tools for LV block device truncation
If a block device is an LVM logical volume we can resize it using standard LVM tools. Add a helper to detect if a device is a DM device. In raw_co_truncate() check if the block device is DM and resize it executing lvresize. Signed-off-by: Alexander Ivanov --- block/file-posix.c | 61 ++ 1 file changed, 61 insertions(+) diff --git a/block/file-posix.c b/block/file-posix.c index 35684f7e21..af17a43fe9 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2642,6 +2642,38 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset, return raw_thread_pool_submit(handle_aiocb_truncate, &acb); } +static bool device_is_dm(struct stat *st) +{ +unsigned int maj, maj2; +char line[32], devname[16]; +bool ret = false; +FILE *f; + +if (!S_ISBLK(st->st_mode)) { +return false; +} + +f = fopen("/proc/devices", "r"); +if (!f) { +return false; +} + +maj = major(st->st_rdev); + +while (fgets(line, sizeof(line), f)) { +if (sscanf(line, "%u %15s", &maj2, devname) != 2) { +continue; +} +if (strcmp(devname, "device-mapper") == 0) { +ret = (maj == maj2); +break; +} +} + +fclose(f); +return ret; +} + static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp) @@ -2670,6 +2702,35 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { int64_t cur_length = raw_getlength(bs); +/* + * Try to resize an LVM device using LVM tools. + */ +if (device_is_dm(&st) && offset > 0) { +int spawn_flags = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL; +int status; +bool success; +char *err; +GError *gerr = NULL, *gerr_exit = NULL; +g_autofree char *size_str = g_strdup_printf("%" PRId64 "B", offset); +const char *cmd[] = {"lvresize", "-f", "-L", + size_str, bs->filename, NULL}; + +success = g_spawn_sync(NULL, (gchar **)cmd, NULL, spawn_flags, + NULL, NULL, NULL, &err, &status, &gerr); + +if (success && g_spawn_check_exit_status(status, &gerr_exit)) { +return 0; +} + +if (success) { +error_setg(errp, "%s: %s", gerr_exit->message, err); +} else { +error_setg(errp, "lvresize execution error: %s", gerr->message); +} + +return -EINVAL; +} + if (offset != cur_length && exact) { error_setg(errp, "Cannot resize device files"); return -ENOTSUP; -- 2.40.1
Re: [PATCH V4 1/1] target/loongarch: Fixed tlb huge page loading issue
Hi Richard : On 3/14/24 20:22, lixianglai wrote: Hi Richard: On 3/13/24 15:33, Xianglai Li wrote: + if (unlikely((level == 0) || (level > 4))) { + return base; + } ... Perhaps it would be worthwhile to add another for the level==0 or > 4 case above? A normal level 4 page table should not print an error log, only if a level 4 page is large, so we should put it in if (FIELD_EX64(base, TLBENTRY, HUGE)) { if (unlikely(level == 4)) { qemu_log_mask(LOG_GUEST_ERROR, "Attempted use of level %lu huge page\n", level); } if (FIELD_EX64(base, TLBENTRY, LEVEL)) { return base; } else { return FIELD_DP64(base, TLBENTRY, LEVEL, level); } } A level 5 page table is not normal, nor is a level 0 lddir. We communicate with the hardware guys that the behavior above level 4 and lddir 0 is undefined behavior. The result of our test on 3A5000 is that it has no any effect on "base", however in future chips the behavior may change since it may support 5-level page table and width for level[13:14] may change also. So in this context,I am not sure which level to use to print logs, which content to print, and where to add these prints, any more detailed advice? Thanks! Xianglai. r~
Re: [PATCH v3] block: Use LVM tools for LV block device truncation
On Fri, Mar 15, 2024 at 09:58:38AM +0100, Alexander Ivanov wrote: > If a block device is an LVM logical volume we can resize it using > standard LVM tools. > > Add a helper to detect if a device is a DM device. In raw_co_truncate() > check if the block device is DM and resize it executing lvresize. > > Signed-off-by: Alexander Ivanov > --- > block/file-posix.c | 61 ++ > 1 file changed, 61 insertions(+) Reviewed-by: Daniel P. Berrangé > > diff --git a/block/file-posix.c b/block/file-posix.c > index 35684f7e21..af17a43fe9 100644 > --- a/block/file-posix.c > +++ b/block/file-posix.c > @@ -2642,6 +2642,38 @@ raw_regular_truncate(BlockDriverState *bs, int fd, > int64_t offset, > return raw_thread_pool_submit(handle_aiocb_truncate, &acb); > } > > +static bool device_is_dm(struct stat *st) > +{ > +unsigned int maj, maj2; > +char line[32], devname[16]; > +bool ret = false; > +FILE *f; > + > +if (!S_ISBLK(st->st_mode)) { > +return false; > +} > + > +f = fopen("/proc/devices", "r"); > +if (!f) { > +return false; > +} > + > +maj = major(st->st_rdev); > + > +while (fgets(line, sizeof(line), f)) { > +if (sscanf(line, "%u %15s", &maj2, devname) != 2) { > +continue; > +} > +if (strcmp(devname, "device-mapper") == 0) { > +ret = (maj == maj2); > +break; > +} > +} > + > +fclose(f); > +return ret; > +} > + > static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, > bool exact, PreallocMode prealloc, > BdrvRequestFlags flags, Error **errp) > @@ -2670,6 +2702,35 @@ static int coroutine_fn > raw_co_truncate(BlockDriverState *bs, int64_t offset, > if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { > int64_t cur_length = raw_getlength(bs); > > +/* > + * Try to resize an LVM device using LVM tools. > + */ > +if (device_is_dm(&st) && offset > 0) { > +int spawn_flags = G_SPAWN_SEARCH_PATH | > G_SPAWN_STDOUT_TO_DEV_NULL; > +int status; > +bool success; > +char *err; > +GError *gerr = NULL, *gerr_exit = NULL; > +g_autofree char *size_str = g_strdup_printf("%" PRId64 "B", > offset); > +const char *cmd[] = {"lvresize", "-f", "-L", > + size_str, bs->filename, NULL}; > + > +success = g_spawn_sync(NULL, (gchar **)cmd, NULL, spawn_flags, > + NULL, NULL, NULL, &err, &status, &gerr); > + > +if (success && g_spawn_check_exit_status(status, &gerr_exit)) { > +return 0; > +} > + > +if (success) { > +error_setg(errp, "%s: %s", gerr_exit->message, err); > +} else { > +error_setg(errp, "lvresize execution error: %s", > gerr->message); > +} > + > +return -EINVAL; > +} > + > if (offset != cur_length && exact) { > error_setg(errp, "Cannot resize device files"); > return -ENOTSUP; > -- > 2.40.1 > > With regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
On Thu, Mar 14, 2024 at 9:24 PM Jonah Palmer wrote: > > > > On 3/14/24 3:05 PM, Eugenio Perez Martin wrote: > > On Thu, Mar 14, 2024 at 5:06 PM Jonah Palmer > > wrote: > >> > >> > >> > >> On 3/14/24 10:55 AM, Eugenio Perez Martin wrote: > >>> On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer > >>> wrote: > > > > On 3/13/24 11:01 PM, Jason Wang wrote: > > On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer > > wrote: > >> > >> Add support to virtio-pci devices for handling the extra data sent > >> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA > >> transport feature has been negotiated. > >> > >> The extra data that's passed to the virtio-pci device when this > >> feature is enabled varies depending on the device's virtqueue > >> layout. > >> > >> In a split virtqueue layout, this data includes: > >> - upper 16 bits: shadow_avail_idx > >> - lower 16 bits: virtqueue index > >> > >> In a packed virtqueue layout, this data includes: > >> - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx > >> - lower 16 bits: virtqueue index > >> > >> Tested-by: Lei Yang > >> Reviewed-by: Eugenio Pérez > >> Signed-off-by: Jonah Palmer > >> --- > >> hw/virtio/virtio-pci.c | 10 +++--- > >> hw/virtio/virtio.c | 18 ++ > >> include/hw/virtio/virtio.h | 1 + > >> 3 files changed, 26 insertions(+), 3 deletions(-) > >> > >> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > >> index cb6940fc0e..0f5c3c3b2f 100644 > >> --- a/hw/virtio/virtio-pci.c > >> +++ b/hw/virtio/virtio-pci.c > >> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, > >> uint32_t addr, uint32_t val) > >> { > >> VirtIOPCIProxy *proxy = opaque; > >> VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); > >> -uint16_t vector; > >> +uint16_t vector, vq_idx; > >> hwaddr pa; > >> > >> switch (addr) { > >> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, > >> uint32_t addr, uint32_t val) > >> vdev->queue_sel = val; > >> break; > >> case VIRTIO_PCI_QUEUE_NOTIFY: > >> -if (val < VIRTIO_QUEUE_MAX) { > >> -virtio_queue_notify(vdev, val); > >> +vq_idx = val; > >> +if (vq_idx < VIRTIO_QUEUE_MAX) { > >> +if (virtio_vdev_has_feature(vdev, > >> VIRTIO_F_NOTIFICATION_DATA)) { > >> +virtio_queue_set_shadow_avail_data(vdev, val); > >> +} > >> +virtio_queue_notify(vdev, vq_idx); > >> } > >> break; > >> case VIRTIO_PCI_STATUS: > >> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c > >> index d229755eae..bcb9e09df0 100644 > >> --- a/hw/virtio/virtio.c > >> +++ b/hw/virtio/virtio.c > >> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, > >> int n, int align) > >> } > >> } > >> > >> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t > >> data) > >>> > >>> Maybe I didn't explain well, but I think it is better to pass directly > >>> idx to a VirtQueue *. That way only the caller needs to check for a > >>> valid vq idx, and (my understanding is) the virtio.c interface is > >>> migrating to VirtQueue * use anyway. > >>> > >> > >> Oh, are you saying to just pass in a VirtQueue *vq instead of > >> VirtIODevice *vdev and get rid of the vq->vring.desc check in the function? > >> > > > > No, that needs to be kept. I meant the access to vdev->vq[i] without > > checking for a valid i. > > > > Ahh okay I see what you mean. But I thought the following was checking > for a valid VQ index: > > if (vq_idx < VIRTIO_QUEUE_MAX) > Right, but then the (potentially multiple) callers are responsible to check for that. If we accept a VirtQueue *, it is assumed it is valid already. > Of course the virtio device may not have up to VIRTIO_QUEUE_MAX > virtqueues, so maybe we should be checking for validity like this? > > if (vdev->vq[i].vring.num == 0) > Actually yes, if you're going to send a new version I think checking against num is better. Good find! > Or was there something else you had in mind? Apologies for the confusion. > No worries, virtio.c is full of checks like that :). Thanks! > > You can get the VirtQueue in the caller with virtio_get_queue. Which > > also does not check for a valid index, but that way is clearer the > > caller needs to check it. > > > > Roger, I'll use this instead for clarity. > > > As a side note, the check for desc != 0 is widespread in QEMU but the > > driver may use 0 address for desc, so it's not 100% valid. But to > > change that now requires a deeper change out of the scope of this >
RE: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err check
>-Original Message- >From: Liu, Zhao1 >Subject: Re: [PATCH 1/2] qom/object_interfaces: Remove unnecessary >local_err check > >On Thu, Feb 29, 2024 at 11:37:38AM +0800, Zhenzhong Duan wrote: >> Date: Thu, 29 Feb 2024 11:37:38 +0800 >> From: Zhenzhong Duan >> Subject: [PATCH 1/2] qom/object_interfaces: Remove unnecessary >local_err >> check >> X-Mailer: git-send-email 2.34.1 >> >> In the error return path, local_err is always set, no need to check it. > >The original error handling code indicates "local_err is always set", >and error_propagate() can handle the case that local_err is NULL. Will do. > >> Signed-off-by: Zhenzhong Duan >> --- >> qom/object_interfaces.c | 10 -- >> 1 file changed, 4 insertions(+), 6 deletions(-) >> >> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c >> index e0833c8bfe..255a7bf659 100644 >> --- a/qom/object_interfaces.c >> +++ b/qom/object_interfaces.c >> @@ -128,13 +128,11 @@ Object *user_creatable_add_type(const char >*type, const char *id, >> } >> goto out; >> } >> -out: >> -if (local_err) { >> -error_propagate(errp, local_err); >> -object_unref(obj); >> -return NULL; >> -} >> return obj; >> +out: > >Maybe rename this to "err:"? Since now it's just used to handle error, >and "goto err" seems more clear. Good suggestion, will do. Thanks Zhenzhong > >> +error_propagate(errp, local_err); >> +object_unref(obj); >> +return NULL; >> } >> >> void user_creatable_add_qapi(ObjectOptions *options, Error **errp) >> -- >> 2.34.1 >> > >Otherwise, > >Reviewed-by: Zhao Liu >
RE: [PATCH 2/2] qom/object_interfaces: Remove local_err in user_creatable_add_type
>-Original Message- >From: Liu, Zhao1 >Subject: Re: [PATCH 2/2] qom/object_interfaces: Remove local_err in >user_creatable_add_type > >On Thu, Feb 29, 2024 at 11:37:39AM +0800, Zhenzhong Duan wrote: >> Date: Thu, 29 Feb 2024 11:37:39 +0800 >> From: Zhenzhong Duan >> Subject: [PATCH 2/2] qom/object_interfaces: Remove local_err in >> user_creatable_add_type >> X-Mailer: git-send-email 2.34.1 >> >> In user_creatable_add_type, there is mixed usage of ERRP_GUARD and >> local_err. This makes error_abort not taking effect in those callee >> functions with local_err passed. >> >> Now that we already has ERRP_GUARD, remove local_err and use *errp >> instead. >> >> Signed-off-by: Zhenzhong Duan >> --- >> qom/object_interfaces.c | 12 +--- >> 1 file changed, 5 insertions(+), 7 deletions(-) >> >> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c >> index 255a7bf659..165cd433e7 100644 >> --- a/qom/object_interfaces.c >> +++ b/qom/object_interfaces.c >> @@ -81,7 +81,6 @@ Object *user_creatable_add_type(const char *type, >const char *id, >> ERRP_GUARD(); >> Object *obj; >> ObjectClass *klass; >> -Error *local_err = NULL; >> >> if (id != NULL && !id_wellformed(id)) { >> error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an >identifier"); >> @@ -109,20 +108,20 @@ Object *user_creatable_add_type(const char >*type, const char *id, >> >> assert(qdict); >> obj = object_new(type); >> -object_set_properties_from_qdict(obj, qdict, v, &local_err); >> -if (local_err) { >> +object_set_properties_from_qdict(obj, qdict, v, errp); > >It's better to make object_set_properties_from_qdict someting (e.g., >boolean). Maybe an extra cleanup? OK, will do. > >> +if (*errp) { >> goto out; >> } >> >> if (id != NULL) { >> object_property_try_add_child(object_get_objects_root(), >> - id, obj, &local_err); >> -if (local_err) { >> + id, obj, errp); >> +if (*errp) { >> goto out; >> } >> } > >Here we could check whether the returned ObjectProperty* is NULL instaed >of dereferencing errp. Indeed, that's better, will do. Thanks Zhenzhong
Another CXL/MMIO tcg tlb corner case
Hi, While doing some testing using numactl-based interleaving of application memory across regular memory and CXL-based memory using QEMU with tcg, I ran into an issue similar to what we saw a while back - link to old issue: https://lore.kernel.org/qemu-devel/CAFEAcA_a_AyQ=epz3_+cheat8crsk9mou894wbnw_fywamk...@mail.gmail.com/#t. When running: numactl --interleave 0,1 ./cachebench … I hit the following: numactl --interleave 0,1 ./cachebench --json_test_config ../test_configs/hit_ratio/graph_cache_follower_assocs/config.json qemu: fatal: cpu_io_recompile: could not find TB for pc=0x7fffc3926dd4 RAX=7f65df55ba18 RBX=7f65df55ba60 RCX=7f65df221620 RDX= RSI=011c0260 RDI=7f65df55ba60 RBP=7ffdb4b4b280 RSP=7ffdb4b4b1d0 R8 =011c02c0 R9 =7f65debf6b20 R10=011bf5d0 R11=7f65deb7d300 R12=7ffdb4b4b260 R13=7ffdb4b4b200 R14=7ffdb4b4b220 R15=011bf5a0 RIP=7f65df18affc RFL=0246 [---Z-P-] CPL=3 II=0 A20=1 SMM=0 HLT=0 ES = CS =0033 00affb00 DPL=3 CS64 [-RA] SS =002b 00cff300 DPL=3 DS [-WA] DS = FS = 7f65de2f64c0 GS = LDT= 8200 DPL=0 LDT TR =0040 fe6c3799 4087 8900 DPL=0 TSS64-avl GDT= fe6c3798e000 007f IDT= fe00 0fff CR0=80050033 CR2=7f65df1b3eb0 CR3=000152a1e000 CR4=00350ef0 DR0= DR1= DR2= DR3= DR6=0ff0 DR7=0400 CCS= CCD=0001 CCO=CLR EFER=0d01 FCW=037f FSW= [ST=0] FTW=00 MXCSR=1f80 FPR0= FPR1= FPR2= FPR3= FPR4= FPR5= FPR6= FPR7= YMM00= 7f65df2233e0 7f65df221620 YMM01= 43e0 YMM02= YMM03= YMM04= 3ff0 YMM05= 7f65df2233e0 YMM06= 7f65df2233b0 YMM07= 62694c6568636143 2f65636170736b72 YMM08= 6d622070656d7320 327876612031696d YMM09= 0004 0004 YMM10= 0002 0002 YMM11= 0010 0010 YMM12= 00ff00fb 00fe00fa YMM13= 00ff00fd00fb00f9 YMM14= YMM15= The backtrace is (using Jonathans cxl-2024-03-05 branch): (gdb) bt #0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737297516096) at ./nptl/pthread_kill.c:44 #1 __pthread_kill_internal (signo=6, threadid=140737297516096) at ./nptl/pthread_kill.c:78 #2 __GI___pthread_kill (threadid=140737297516096, signo=signo@entry=6) at ./nptl/pthread_kill.c:89 #3 0x77642476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #4 0x776287f3 in __GI_abort () at ./stdlib/abort.c:79 #5 0x55c5a9df in cpu_abort (cpu=cpu@entry=0x578c19c0, fmt=fmt@entry=0x5605d100 "cpu_io_recompile: could not find TB for pc=%p") at ../cpu-target.c:371 #6 0x55caa065 in cpu_io_recompile (cpu=cpu@entry=0x578c19c0, retaddr=140736474541524) at ../accel/tcg/translate-all.c:610 #7 0x55cacee7 in io_prepare (retaddr=140736474541524, addr=140075515361944, attrs=..., xlat=, cpu=0x578c19c0, out_offset=) at ../accel/tcg/cputlb.c:1336 #8 do_st_mmio_leN (cpu=0x578c19c0, full=0x7ffd1a1554d0, val_le=140075515361816, addr=140075515361944, size=8, mmu_idx=3, ra=140736474541524) at ../accel/tcg/cputlb.c:2591 #9 0x55cb179d in do_st_8 (ra=, memop=, mmu_idx=, val=140075515361816, p=, cpu=) at ../accel/tcg/cputlb.c:2784 #10 do_st8_mmu (cpu=0x578c19c0, addr=39050, val=140075515361816, oi=6, ra=140736474541524) at ../accel/tcg/cputlb.c:2862 #11 0x7fffc3926e15 in code_gen_buffer () #12 0x55ca0e5b in cpu_tb_exec (cpu=cpu@entry=0x578c19c0, itb=itb@entry=0x7fffc3926cc0 , tb_exit=tb_exit@entry=0x749ff6d8) at ../accel/tcg/cpu-exec.c:449 #13 0x55ca13ac in cpu_loop_exec_tb (tb_exit=0x749ff6d8, last_tb=, pc=, tb=0x7fffc3926cc0 , cpu=0x578c19c0) at ../accel/tcg/cpu-exe
Re: [PATCH v3] blockcommit: Reopen base image as RO after abort
On 2/28/24 17:48, Vladimir Sementsov-Ogievskiy wrote: On 09.02.24 15:29, Alexander Ivanov wrote: Could you please review the patch? Sorry for long delay. Honestly, I don't like refcnt in block-driver. It violate incapsulation, refcnt is interal thing of common block layer. And actually, you can't make any assumptions from value of refcnt, as you don't know which additional parents were created and why, and when they are going unref their children. Hmmm... Maybe I can just exclude refcnt check from the condition, can't I. If BDS will be removed it doesn't matter if we make it RO. What do you think? What was wrong with v2? My bad, it seems, I didn't send v2 before I decided to change the patch. On 1/30/24 10:14, Alexander Ivanov wrote: If a blockcommit is aborted the base image remains in RW mode, that leads to a fail of subsequent live migration. How to reproduce: $ virsh snapshot-create-as vm snp1 --disk-only *** write something to the disk inside the guest *** $ virsh blockcommit vm vda --active --shallow && virsh blockjob vm vda --abort $ lsof /vzt/vm.qcow2 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME qemu-syst 433203 root 45u REG 253,0 1724776448 133 /vzt/vm.qcow2 $ cat /proc/433203/fdinfo/45 pos: 0 flags: 02140002 < The last 2 means RW mode If the base image is in RW mode at the end of blockcommit and was in RO mode before blockcommit, check if src BDS has refcnt > 1. If so, the BDS will not be removed after blockcommit, and we should make the base image RO. Otherwise check recursively if there is a parent BDS of src BDS and reopen the base BDS in RO in this case. Signed-off-by: Alexander Ivanov --- block/mirror.c | 38 -- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index 5145eb53e1..52a7fee75e 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -93,6 +93,7 @@ typedef struct MirrorBlockJob { int64_t active_write_bytes_in_flight; bool prepared; bool in_drain; + bool base_ro; } MirrorBlockJob; typedef struct MirrorBDSOpaque { @@ -652,6 +653,32 @@ static void coroutine_fn mirror_wait_for_all_io(MirrorBlockJob *s) } } +/* + * Check recursively if there is a parent BDS referenced more than + * min_refcnt times. This argument is needed because at the first + * call there is a bds referenced in blockcommit. + */ +static bool bdrv_chain_has_significant_parent(BlockDriverState *bs) +{ + BdrvChild *parent; + BlockDriverState *parent_bs; + + QLIST_FOREACH(parent, &bs->parents, next) { + if (!(parent->klass->parent_is_bds)) { + continue; + } + parent_bs = parent->opaque; + if (parent_bs->drv && !parent_bs->drv->is_filter) { + return true; + } + if (bdrv_chain_has_significant_parent(parent_bs)) { + return true; + } + } + + return false; +} + /** * mirror_exit_common: handle both abort() and prepare() cases. * for .prepare, returns 0 on success and -errno on failure. @@ -793,6 +820,11 @@ static int mirror_exit_common(Job *job) bdrv_drained_end(target_bs); bdrv_unref(target_bs); + if (s->base_ro && !bdrv_is_read_only(target_bs) && + (src->refcnt > 1 || bdrv_chain_has_significant_parent(src))) { + bdrv_reopen_set_read_only(target_bs, true, NULL); + } + bs_opaque->job = NULL; bdrv_drained_end(src); @@ -1715,6 +1747,7 @@ static BlockJob *mirror_start_job( bool is_none_mode, BlockDriverState *base, bool auto_complete, const char *filter_node_name, bool is_mirror, MirrorCopyMode copy_mode, + bool base_ro, Error **errp) { MirrorBlockJob *s; @@ -1798,6 +1831,7 @@ static BlockJob *mirror_start_job( bdrv_unref(mirror_top_bs); s->mirror_top_bs = mirror_top_bs; + s->base_ro = base_ro; /* No resize for the target either; while the mirror is still running, a * consistent read isn't necessarily possible. We could possibly allow @@ -2027,7 +2061,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, speed, granularity, buf_size, backing_mode, zero_target, on_source_error, on_target_error, unmap, NULL, NULL, &mirror_job_driver, is_none_mode, base, false, - filter_node_name, true, copy_mode, errp); + filter_node_name, true, copy_mode, false, errp); } BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, @@ -2056,7 +2090,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, on_error, on_error, true, cb, opaque, &commit_active_job_driver, false, base, auto_complete,
Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()
On 3/12/24 19:28, Fabiano Rosas wrote: Peter Xu writes: On Tue, Mar 12, 2024 at 11:24:39AM -0300, Fabiano Rosas wrote: Cédric Le Goater writes: On 3/12/24 14:34, Cédric Le Goater wrote: On 3/12/24 13:32, Cédric Le Goater wrote: On 3/11/24 20:03, Fabiano Rosas wrote: Cédric Le Goater writes: On 3/8/24 15:36, Fabiano Rosas wrote: Cédric Le Goater writes: This prepares ground for the changes coming next which add an Error** argument to the .save_setup() handler. Callers of qemu_savevm_state_setup() now handle the error and fail earlier setting the migration state from MIGRATION_STATUS_SETUP to MIGRATION_STATUS_FAILED. In qemu_savevm_state(), move the cleanup to preserve the error reported by .save_setup() handlers. Since the previous behavior was to ignore errors at this step of migration, this change should be examined closely to check that cleanups are still correctly done. Signed-off-by: Cédric Le Goater --- Changes in v4: - Merged cleanup change in qemu_savevm_state() Changes in v3: - Set migration state to MIGRATION_STATUS_FAILED - Fixed error handling to be done under lock in bg_migration_thread() - Made sure an error is always set in case of failure in qemu_savevm_state_setup() migration/savevm.h | 2 +- migration/migration.c | 27 --- migration/savevm.c | 26 +++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/migration/savevm.h b/migration/savevm.h index 74669733dd63a080b765866c703234a5c4939223..9ec96a995c93a42aad621595f0ed58596c532328 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -32,7 +32,7 @@ bool qemu_savevm_state_blocked(Error **errp); void qemu_savevm_non_migratable_list(strList **reasons); int qemu_savevm_state_prepare(Error **errp); -void qemu_savevm_state_setup(QEMUFile *f); +int qemu_savevm_state_setup(QEMUFile *f, Error **errp); bool qemu_savevm_state_guest_unplug_pending(void); int qemu_savevm_state_resume_prepare(MigrationState *s); void qemu_savevm_state_header(QEMUFile *f); diff --git a/migration/migration.c b/migration/migration.c index a49fcd53ee19df1ce0182bc99d7e064968f0317b..6d1544224e96f5edfe56939a9c8395d88ef29581 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3408,6 +3408,8 @@ static void *migration_thread(void *opaque) int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST); MigThrError thr_error; bool urgent = false; + Error *local_err = NULL; + int ret; thread = migration_threads_add("live_migration", qemu_get_thread_id()); @@ -3451,9 +3453,17 @@ static void *migration_thread(void *opaque) } bql_lock(); - qemu_savevm_state_setup(s->to_dst_file); + ret = qemu_savevm_state_setup(s->to_dst_file, &local_err); bql_unlock(); + if (ret) { + migrate_set_error(s, local_err); + error_free(local_err); + migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_FAILED); + goto out; + } + qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE); This^ should be before the new block it seems: GOOD: migrate_set_state new state setup migrate_set_state new state wait-unplug migrate_fd_cancel migrate_set_state new state cancelling migrate_fd_cleanup migrate_set_state new state cancelled migrate_fd_cancel ok 1 /x86_64/failover-virtio-net/migrate/abort/wait-unplug BAD: migrate_set_state new state setup migrate_fd_cancel migrate_set_state new state cancelling migrate_fd_cleanup migrate_set_state new state cancelled qemu-system-x86_64: ram_save_setup failed: Input/output error ** ERROR:../tests/qtest/virtio-net-failover.c:1203:test_migrate_abort_wait_unplug: assertion failed (status == "cancelling"): ("cancelled" == "cancelling") Otherwise migration_iteration_finish() will schedule the cleanup BH and that will run concurrently with migrate_fd_cancel() issued by the test and bad things happens. This hack makes things work : @@ -3452,6 +3452,9 @@ static void *migration_thread(void *opaq qemu_savevm_send_colo_enable(s->to_dst_file); } + qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_SETUP); + Why move it all the way up here? Has moving the wait_unplug before the 'if (ret)' block not worked for you? We could be sleeping while holding the BQL. It looked wrong. Sorry wrong answer. Yes I can try moving it before the 'if (ret)' block. I can reproduce easily with an x86 guest running on PPC64. That works just the same. Peter, Fabiano, What would you prefer ? 1. move qemu_savevm_wait_unplug() before qemu_savevm_state_setup(), means one new patch. Is there a point to this except "because we can"? Honest question, I might have missed the motivation. My previous point was, it avoids holding the resources (that wil
Re: [PATCH v2 2/2] hmat acpi: Fix out of bounds access due to missing use of indirection
On Wed, 13 Mar 2024 21:24:06 +0300 Michael Tokarev wrote: > 07.03.2024 19:03, Jonathan Cameron via wrote: > > With a numa set up such as > > > > -numa nodeid=0,cpus=0 \ > > -numa nodeid=1,memdev=mem \ > > -numa nodeid=2,cpus=1 > > > > and appropriate hmat_lb entries the initiator list is correctly > > computed and writen to HMAT as 0,2 but then the LB data is accessed > > using the node id (here 2), landing outside the entry_list array. > > > > Stash the reverse lookup when writing the initiator list and use > > it to get the correct array index index. > > > > Fixes: 4586a2cb83 ("hmat acpi: Build System Locality Latency and Bandwidth > > Information Structure(s)") > > Signed-off-by: Jonathan Cameron > > This seems like a -stable material, is it not? Yes. Use case is obscure, but indeed seems suitable for stable. Thanks. Jonathan > > Thanks, > > /mjt > > > --- > > hw/acpi/hmat.c | 6 +- > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c > > index 723ae28d32..b933ae3c06 100644 > > --- a/hw/acpi/hmat.c > > +++ b/hw/acpi/hmat.c > > @@ -78,6 +78,7 @@ static void build_hmat_lb(GArray *table_data, > > HMAT_LB_Info *hmat_lb, > > uint32_t *initiator_list) > > { > > int i, index; > > +uint32_t initiator_to_index[MAX_NODES] = {}; > > HMAT_LB_Data *lb_data; > > uint16_t *entry_list; > > uint32_t base; > > @@ -121,6 +122,8 @@ static void build_hmat_lb(GArray *table_data, > > HMAT_LB_Info *hmat_lb, > > /* Initiator Proximity Domain List */ > > for (i = 0; i < num_initiator; i++) { > > build_append_int_noprefix(table_data, initiator_list[i], 4); > > +/* Reverse mapping for array possitions */ > > +initiator_to_index[initiator_list[i]] = i; > > } > > > > /* Target Proximity Domain List */ > > @@ -132,7 +135,8 @@ static void build_hmat_lb(GArray *table_data, > > HMAT_LB_Info *hmat_lb, > > entry_list = g_new0(uint16_t, num_initiator * num_target); > > for (i = 0; i < hmat_lb->list->len; i++) { > > lb_data = &g_array_index(hmat_lb->list, HMAT_LB_Data, i); > > -index = lb_data->initiator * num_target + lb_data->target; > > +index = initiator_to_index[lb_data->initiator] * num_target + > > +lb_data->target; > > > > entry_list[index] = (uint16_t)(lb_data->data / hmat_lb->base); > > } >
Re: [PATCH v9 0/7] QEMU CXL Provide mock CXL events and irq support
On Fri, 15 Mar 2024 09:52:28 +0800 Yuquan Wang wrote: > Hello, Jonathan > > When during the test of qmps of CXL events like > "cxl-inject-general-media-event", > I am confuesd about the argument "flags". According to "qapi/cxl.json" in > qemu, > this argument represents "Event Record Flags" in Common Event Record Format. > However, it seems like the specific 'Event Record Severity' in this field can > be > different from the value of 'Event Status' in "Event Status Register". > > For instance (take an injection example in the coverlatter): > > { "execute": "cxl-inject-general-media-event", > "arguments": { > "path": "/machine/peripheral/cxl-mem0", > "log": "informational", > "flags": 1, > "dpa": 1000, > "descriptor": 3, > "type": 3, > "transaction-type": 192, > "channel": 3, > "device": 5, > "component-id": "iras mem" > }} > > In my understanding, the 'Event Status' is informational and the > 'Event Record Severity' is Warning event, which means these two arguments are > independent of each other. Is my understanding correct? The event status registers dictates the notification path (which log). So I think that's "informational" here. Whereas flags is about the specific error. One case where they might be different is where the Related Event Record Handle is set. An error might be reported as 1) Several things that were non fatal (each with their own record) 2) In combination they result in a fatal situation (also has it's own record). The QEMU injection shouldn't restrict these combinations more than the spec does (which is not at all!). This same disconnect in error severity is seen in UEFI CPER records for example where there is a containing record with one severity field, but more specific parts of record can have lower (or in theory higher) severity. Jonathan > > Many thanks > Yuquan >
[PATCH 0/1] cxl/mem: Fix for the index of Clear Event Record Handle
This is a simple fix for the index of 'Clear Event Record' Handle. The print content of dev_dbg from Clear Event Records mailbox command would report the handle of the next record to clear not the current one. The problem was found when I was doing the debug of CXL Event Error on Qemu. I injected an individual event through QMP 'cxl-inject-general-media-event': { "execute": "cxl-inject-general-media-event", "arguments": { "path": "/machine/peripheral/cxl-mem0", "log": "informational", "flags": 1, "dpa": 1000, "descriptor": 3, "type": 3, "transaction-type": 192, "channel": 3, "device": 5, "component-id": "iras mem" }} Then the kernel printed: [ 1639.106181] cxl_pci :0d:00.0: Event log '0': Clearing 0 However, the line 36 in 'hw/cxl/cxl-events.c': log->next_handle = 1; It will set the actual handle value of injected event to '1'. With this fix, the kernel will print: [ 122.456750] cxl_pci :0d:00.0: Event log '0': Clearing 1 which is in line with the simulated value in Qemu. Yuquan Wang (1): cxl/mem: Fix for the index of Clear Event Record Handle drivers/cxl/core/mbox.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) -- 2.34.1
[PATCH 1/1] cxl/mem: Fix for the index of Clear Event Record Handle
The dev_dbg info for Clear Event Records mailbox command would report the handle of the next record to clear not the current one. This was because the index 'i' had incremented before printing the current handle value. This fix also adjusts the index variable name from 'i' to 'clear_cnt' which can be easier for developers to distinguish and understand. Signed-off-by: Yuquan Wang --- drivers/cxl/core/mbox.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 9adda4795eb7..3ca2845ae6aa 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -881,7 +881,7 @@ static int cxl_clear_event_record(struct cxl_memdev_state *mds, struct cxl_mbox_cmd mbox_cmd; u16 cnt; int rc = 0; - int i; + int clear_cnt; /* Payload size may limit the max handles */ if (pl_size > mds->payload_size) { @@ -908,28 +908,29 @@ static int cxl_clear_event_record(struct cxl_memdev_state *mds, * Clear Event Records uses u8 for the handle cnt while Get Event * Record can return up to 0x records. */ - i = 0; + clear_cnt = 0; for (cnt = 0; cnt < total; cnt++) { struct cxl_event_record_raw *raw = &get_pl->records[cnt]; struct cxl_event_generic *gen = &raw->event.generic; - payload->handles[i++] = gen->hdr.handle; + payload->handles[clear_cnt] = gen->hdr.handle; dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log, - le16_to_cpu(payload->handles[i])); + le16_to_cpu(payload->handles[clear_cnt])); - if (i == max_handles) { - payload->nr_recs = i; + clear_cnt++; + if (clear_cnt == max_handles) { + payload->nr_recs = clear_cnt; rc = cxl_internal_send_cmd(mds, &mbox_cmd); if (rc) goto free_pl; - i = 0; + clear_cnt = 0; } } /* Clear what is left if any */ - if (i) { - payload->nr_recs = i; - mbox_cmd.size_in = struct_size(payload, handles, i); + if (clear_cnt) { + payload->nr_recs = clear_cnt; + mbox_cmd.size_in = struct_size(payload, handles, clear_cnt); rc = cxl_internal_send_cmd(mds, &mbox_cmd); if (rc) goto free_pl; -- 2.34.1
Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()
On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote: > > migrate_set_state is also unintuitive because it ignores invalid state > > transitions and we've been using that property to deal with special > > states such as POSTCOPY_PAUSED and FAILED: > > > > - After the migration goes into POSTCOPY_PAUSED, the resumed migration's > >migrate_init() will try to set the state NONE->SETUP, which is not > >valid. > > > > - After save_setup fails, the migration goes into FAILED, but wait_unplug > >will try to transition SETUP->ACTIVE, which is also not valid. > > > > I am not sure I understand what the plan is. Both solutions are problematic > regarding the state transitions. > > Should we consider that waiting for failover devices to unplug is an internal > step of the SETUP phase not transitioning to ACTIVE ? If to unblock this series, IIUC the simplest solution is to do what Fabiano suggested, that we move qemu_savevm_wait_unplug() to be before the check of setup() ret. In that case, the state change in qemu_savevm_wait_unplug() should be benign and we should see a super small window it became ACTIVE but then it should be FAILED (and IIUC the patch itself will need to use ACTIVE as "old_state", not SETUP anymore). For the long term, maybe we can remove the WAIT_UNPLUG state? The only Libvirt support seems to be here: commit 8a226ddb3602586a2ba2359afc4448c02f566a0e Author: Laine Stump Date: Wed Jan 15 16:38:57 2020 -0500 qemu: add wait-unplug to qemu migration status enum Considering that qemu_savevm_wait_unplug() can be a noop if the device is already unplugged, I think it means no upper layer app should rely on this state to present. Thanks, -- Peter Xu
Re: Any interest in the QEMU community attending DVCon Europe October 2024?
Alex Bennée writes: > Hi, > > Over recent years there has been a push to make QEMU more flexible for > EDA type applications. As long time developers know there are a number > of downstream forks of QEMU which have their own solutions for modelling > heterogeneous systems and integrating with hardware models. The work by > Philippe, Anton and others to build a single binary with composable > hardware is aiming at least to solve the heterogeneous modelling problem > in the upstream project. > > While we do discuss these "TCG" topics during KVM Forum the project may > benefit from doing some outreach at some conferences where simulation > and emulation are the primary focus. > > The Design and Verification Conference & Exhibition Europe (DVCon > Europe) is the premier European technical conference on system, > software, design, verification, validation and integration. This year it > will be on the 15-16 October 2024 in Munich. See: https://dvcon-europe.org/ > > There have been a number of papers and workshops on QEMU/KVM topics over > the years. Unfortunately the website doesn't provide slides or videos of > the talks but topics have included how QEMU can be used as a fast > instruction simulator alongside things such as SystemC models or > virtualisation can be leveraged to accelerate full system emulation. > > The main tracks are fairly academic where engineering and research > papers are submitted and if accepted can then be presented at the > conference. This is probably over the top for QEMU related stuff but > their is a tutorial track (deadline for Abstracts 1st July) which could > be a good target for a introduction to the features and capabilities of > the QEMU upstream. I suspect there would be interest in the wider > modelling community to find out more about how to use the upstream > project directly. > > There is a co-located "SystemC Evolution Day" on the 17th where there > might well be a strong overlap between SystemC users and QEMU. Mark > Burton is involved with that and is keen for proposals talking about > integrating SystemC models with QEMU. Please send a message to > mbur...@quicinc.com if you're interested. > > So is anyone interested? > > Should we do more within the community to network and discuss our plans > for QEMU as a modelling solution? > > Any other thoughts? Gentle ping, any interest? -- Alex Bennée Virtualisation Tech Lead @ Linaro
[PATCH 5/9] tests/qemu-iotests: Restrict test 134 and 158 to the 'file' protocol
Commit b25b387fa592 updated the iotests 134 and 158 to use the --image-opts parameter for qemu-io with file protocol related options, but forgot to update the _supported_proto line accordingly. So let's do that now. Fixes: b25b387fa5 ("qcow2: convert QCow2 to use QCryptoBlock for encryption") Signed-off-by: Thomas Huth --- tests/qemu-iotests/134 | 2 +- tests/qemu-iotests/158 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134 index ded153c0b9..b2c3c03f08 100755 --- a/tests/qemu-iotests/134 +++ b/tests/qemu-iotests/134 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow qcow2 -_supported_proto generic +_supported_proto file size=128M diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158 index a95878e4ce..3a9ad7eed0 100755 --- a/tests/qemu-iotests/158 +++ b/tests/qemu-iotests/158 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow qcow2 -_supported_proto generic +_supported_proto file size=128M -- 2.44.0
[PATCH 9/9] tests/qemu-iotests: Restrict tests using "--blockdev file" to the file protocol
Tests that use "--blockdev" with the "file" driver cannot work with other protocols, so we should mark them accordingly. Signed-off-by: Thomas Huth --- tests/qemu-iotests/tests/qcow2-internal-snapshots | 2 +- tests/qemu-iotests/tests/qsd-jobs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/tests/qcow2-internal-snapshots b/tests/qemu-iotests/tests/qcow2-internal-snapshots index 36523aba06..9f83aa8903 100755 --- a/tests/qemu-iotests/tests/qcow2-internal-snapshots +++ b/tests/qemu-iotests/tests/qcow2-internal-snapshots @@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # This tests qcow2-specific low-level functionality _supported_fmt qcow2 -_supported_proto generic +_supported_proto file # Internal snapshots are (currently) impossible with refcount_bits=1, # and generally impossible with external data files _unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file diff --git a/tests/qemu-iotests/tests/qsd-jobs b/tests/qemu-iotests/tests/qsd-jobs index 510bf0a9dc..9b843af631 100755 --- a/tests/qemu-iotests/tests/qsd-jobs +++ b/tests/qemu-iotests/tests/qsd-jobs @@ -40,7 +40,7 @@ cd .. . ./common.filter _supported_fmt qcow2 -_supported_proto generic +_supported_proto file size=128M -- 2.44.0
[PATCH 4/9] tests/qemu-iotests: Restrict test 130 to the 'file' protocol
Using "-drive ...,backing.file.filename=..." only works with the file protocol, but not with URIs, so mark this test accordingly. Signed-off-by: Thomas Huth --- tests/qemu-iotests/130 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130 index 7257f09677..7af85d20a8 100755 --- a/tests/qemu-iotests/130 +++ b/tests/qemu-iotests/130 @@ -42,7 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.qemu _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux # We are going to use lazy-refcounts _unsupported_imgopts 'compat=0.10' -- 2.44.0
[PATCH 8/9] tests/qemu-iotests: Fix some tests that use --image-opts for other protocols
Tests 263, 284 and detect-zeroes-registered-buf use qemu-io with --image-opts so we have to enforce IMGOPTSSYNTAX=true here to get $TEST_IMG in shape for other protocols than "file". Signed-off-by: Thomas Huth --- tests/qemu-iotests/263| 6 -- tests/qemu-iotests/284| 7 +++ tests/qemu-iotests/tests/detect-zeroes-registered-buf | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/qemu-iotests/263 b/tests/qemu-iotests/263 index ec09b41405..44fdada0d6 100755 --- a/tests/qemu-iotests/263 +++ b/tests/qemu-iotests/263 @@ -34,6 +34,8 @@ _cleanup() } trap "_cleanup; exit \$status" 0 1 2 3 15 +IMGOPTSSYNTAX=true + # get standard environment, filters and checks . ./common.rc . ./common.filter @@ -73,7 +75,7 @@ echo "testing LUKS qcow2 encryption" echo _make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=64K" $size -_run_test "driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG" +_run_test "$TEST_IMG,encrypt.key-secret=sec0" _cleanup_test_img echo @@ -82,7 +84,7 @@ echo _make_test_img --object $SECRET -o "encrypt.format=aes,encrypt.key-secret=sec0,cluster_size=64K" $size -_run_test "driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG" +_run_test "$TEST_IMG,encrypt.key-secret=sec0" _cleanup_test_img diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284 index 5a82639e7f..722267486d 100755 --- a/tests/qemu-iotests/284 +++ b/tests/qemu-iotests/284 @@ -33,6 +33,8 @@ _cleanup() } trap "_cleanup; exit \$status" 0 1 2 3 15 +IMGOPTSSYNTAX=true + # get standard environment, filters and checks . ./common.rc . ./common.filter @@ -47,14 +49,12 @@ size=1M SECRET="secret,id=sec0,data=astrochicken" -IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0" QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT _run_test() { -IMGOPTSSYNTAX=true OLD_TEST_IMG="$TEST_IMG" - TEST_IMG="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0" +TEST_IMG="$TEST_IMG,encrypt.key-secret=sec0" QEMU_IMG_EXTRA_ARGS="--image-opts --object $SECRET" echo @@ -78,7 +78,6 @@ _run_test() TEST_IMG="$OLD_TEST_IMG" QEMU_IMG_EXTRA_ARGS= -IMGOPTSSYNTAX= } diff --git a/tests/qemu-iotests/tests/detect-zeroes-registered-buf b/tests/qemu-iotests/tests/detect-zeroes-registered-buf index edb5f2cee5..5eaf34e5a6 100755 --- a/tests/qemu-iotests/tests/detect-zeroes-registered-buf +++ b/tests/qemu-iotests/tests/detect-zeroes-registered-buf @@ -36,6 +36,8 @@ _cleanup() } trap "_cleanup; exit \$status" 0 1 2 3 15 +IMGOPTSSYNTAX=true + # get standard environment, filters and checks cd .. . ./common.rc @@ -46,7 +48,7 @@ _supported_proto generic size=128M _make_test_img $size -IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,discard=unmap,detect-zeroes=unmap" +IMGSPEC="$TEST_IMG,discard=unmap,detect-zeroes=unmap" echo echo "== writing zero buffer to image ==" -- 2.44.0
[PATCH 1/9] tests/qemu-iotests: Fix test 033 for running with non-file protocols
When running iotest 033 with the ssh protocol, it fails with: 033 fail [14:48:31] [14:48:41] 10.2soutput mismatch --- /.../tests/qemu-iotests/033.out +++ /.../tests/qemu-iotests/scratch/qcow2-ssh-033/033.out.bad @@ -174,6 +174,7 @@ 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 512/512 bytes at offset 2097152 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io: warning: Failed to truncate the tail of the image: ssh driver does not support shrinking files read 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) We already check for the qcow2 format here, so let's simply also add a check for the protocol here, too, to only test the truncation with the file protocol. Signed-off-by: Thomas Huth --- tests/qemu-iotests/033 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033 index da9133c44b..4bc7a071bd 100755 --- a/tests/qemu-iotests/033 +++ b/tests/qemu-iotests/033 @@ -123,9 +123,9 @@ do_test 512 "write -P 1 0 0x200" "$TEST_IMG" | _filter_qemu_io # next L2 table do_test 512 "write -P 1 $L2_COVERAGE 0x200" "$TEST_IMG" | _filter_qemu_io -# only interested in qcow2 here; also other formats might respond with -# "not supported" error message -if [ $IMGFMT = "qcow2" ]; then +# only interested in qcow2 with file protocol here; also other formats +# might respond with "not supported" error message +if [ $IMGFMT = "qcow2" ] && [ $IMGPROTO = "file" ]; then do_test 512 "truncate $L2_COVERAGE" "$TEST_IMG" | _filter_qemu_io fi -- 2.44.0
[PATCH 3/9] tests/qemu-iotests: Restrict test 114 to the 'file' protocol
iotest 114 uses "truncate" and the qcow2.py script on the destination file, which both cannot deal with URIs. Thus this test needs the "file" protocol, otherwise it fails with an error message like this: truncate: cannot open 'ssh://127.0.0.1/tmp/qemu-build/tests/qemu-iotests/scratch/qcow2-ssh-114/t.qcow2.orig' for writing: No such file or directory Thus mark this test for "file protocol only" accordingly. Signed-off-by: Thomas Huth --- tests/qemu-iotests/114 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114 index de6fd327ee..dccc71008b 100755 --- a/tests/qemu-iotests/114 +++ b/tests/qemu-iotests/114 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow2 -_supported_proto generic +_supported_proto file # At least OpenBSD doesn't seem to have truncate _supported_os Linux # qcow2.py does not work too well with external data files -- 2.44.0
[PATCH 6/9] tests/qemu-iotests: Restrict test 156 to the 'file' protocol
The test fails completely when you try to use it with a different protocol, e.g. with "./check -ssh -qcow2 156". The test uses some hand-crafted JSON statements which cannot work with other protocols, thus let's change this test to only support the 'file' protocol. Signed-off-by: Thomas Huth --- tests/qemu-iotests/156 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156 index a9540bd80d..97c2d86ce5 100755 --- a/tests/qemu-iotests/156 +++ b/tests/qemu-iotests/156 @@ -50,7 +50,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.qemu _supported_fmt qcow2 qed -_supported_proto generic +_supported_proto file # Copying files around with cp does not work with external data files _unsupported_imgopts data_file -- 2.44.0
Re: [PATCH v2 7/7] qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper
On 3/5/24 20:38, Daniel P. Berrangé wrote: > On Fri, Mar 01, 2024 at 07:28:58PM +0200, Andrey Drobyshev wrote: >> There's no need to check for the existence of the "chpasswd", "pw" >> executables, as the exec() call will do that for us. >> >> Signed-off-by: Andrey Drobyshev >> --- >> qga/commands-posix.c | 96 ++-- >> 1 file changed, 13 insertions(+), 83 deletions(-) >> >> diff --git a/qga/commands-posix.c b/qga/commands-posix.c >> index f3f4a05e2d..f2e9496b80 100644 >> --- a/qga/commands-posix.c >> +++ b/qga/commands-posix.c >> @@ -2144,14 +2144,8 @@ void qmp_guest_set_user_password(const char *username, >> Error **errp) >> { >> Error *local_err = NULL; >> -char *passwd_path = NULL; >> -pid_t pid; >> -int status; >> -int datafd[2] = { -1, -1 }; >> -char *rawpasswddata = NULL; >> +g_autofree char *rawpasswddata = NULL; >> size_t rawpasswdlen; >> -char *chpasswddata = NULL; >> -size_t chpasswdlen; >> >> rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, >> errp); >> if (!rawpasswddata) { >> @@ -2162,95 +2156,31 @@ void qmp_guest_set_user_password(const char >> *username, >> >> if (strchr(rawpasswddata, '\n')) { >> error_setg(errp, "forbidden characters in raw password"); >> -goto out; >> +return; >> } >> >> if (strchr(username, '\n') || >> strchr(username, ':')) { >> error_setg(errp, "forbidden characters in username"); >> -goto out; >> +return; >> } >> >> #ifdef __FreeBSD__ >> -chpasswddata = g_strdup(rawpasswddata); >> -passwd_path = g_find_program_in_path("pw"); >> +g_autofree char *chpasswdata = g_strdup(rawpasswddata); >> +const char *crypt_flag = (crypted) ? "-H" : "-h"; >> +const char *argv[] = {"pw", "usermod", "-n", username, >> + crypt_flag, "0", NULL}; >> #else >> -chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata); >> -passwd_path = g_find_program_in_path("chpasswd"); >> +g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username, >> +rawpasswddata); >> +const char *crypt_flag = (crypted) ? "-e" : NULL; > > Style nit-pick - no '(...)' around 'crypted' is needed here, or > the other place later in this method. > > Yes, that was a pre-existing issue, but since you're refactoring > the code, might as well kill the redundant brackets. > > [...] Sure, let's get rid of them. Thanks.
[PATCH 2/9] tests/qemu-iotests: Restrict test 066 to the 'file' protocol
The hand-crafted json statement in this test only works if the test is run with the "file" protocol, so mark this test accordingly. Signed-off-by: Thomas Huth --- tests/qemu-iotests/066 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066 index cf63144cb9..336d8565dd 100755 --- a/tests/qemu-iotests/066 +++ b/tests/qemu-iotests/066 @@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # This tests qcow2-specific low-level functionality _supported_fmt qcow2 -_supported_proto generic +_supported_proto file # We need zero clusters and snapshots # (TODO: Consider splitting the snapshot part into a separate test #file, so this one runs with refcount_bits=1 and data_file) -- 2.44.0
[PATCH 7/9] tests/qemu-iotests: Restrict tests that use --image-opts to the 'file' protocol
These tests 188, 189 and 198 use qemu-io with --image-opts with additional hard-coded parameters for the file protocol, so they cannot work for other protocols. Thus we have to limit these tests to the file protocol only. Signed-off-by: Thomas Huth --- tests/qemu-iotests/188 | 2 +- tests/qemu-iotests/189 | 2 +- tests/qemu-iotests/198 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188 index ce087d1873..2950b1dc31 100755 --- a/tests/qemu-iotests/188 +++ b/tests/qemu-iotests/188 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux _require_working_luks diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189 index 801494c6b9..008f73b07d 100755 --- a/tests/qemu-iotests/189 +++ b/tests/qemu-iotests/189 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux _require_working_luks diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198 index 1c93dea1f7..6ddeffddd2 100755 --- a/tests/qemu-iotests/198 +++ b/tests/qemu-iotests/198 @@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux _require_working_luks -- 2.44.0
Re: [PATCH v2 2/7] qga: introduce ga_run_command() helper for guest cmd execution
On 3/5/24 19:58, Daniel P. Berrangé wrote: > On Fri, Mar 01, 2024 at 07:28:53PM +0200, Andrey Drobyshev wrote: >> When executing guest commands in *nix environment, we repeat the same >> fork/exec pattern multiple times. Let's just separate it into a single >> helper which would also be able to feed input data into the launched >> process' stdin. This way we can avoid code duplication. >> >> To keep the history more bisectable, let's replace qmp commands >> implementations one by one. Also add G_GNUC_UNUSED attribute to the >> helper and remove it in the next commit. >> >> Originally-by: Yuri Pudgorodskiy >> Signed-off-by: Andrey Drobyshev >> --- >> qga/commands-posix.c | 140 +++ >> 1 file changed, 140 insertions(+) >> >> diff --git a/qga/commands-posix.c b/qga/commands-posix.c >> index 8207c4c47e..781498418f 100644 >> --- a/qga/commands-posix.c >> +++ b/qga/commands-posix.c >> @@ -76,6 +76,146 @@ static void ga_wait_child(pid_t pid, int *status, Error >> **errp) >> g_assert(rpid == pid); >> } >> >> +static void ga_pipe_read_str(int fd[2], char **str, size_t *len) >> +{ >> +ssize_t n; >> +char buf[1024]; >> +close(fd[1]); >> +fd[1] = -1; >> +while ((n = read(fd[0], buf, sizeof(buf))) != 0) { >> +if (n < 0) { >> +if (errno == EINTR) { >> +continue; >> +} else { >> +break; > > This is a fatal error condition > >> +} >> +} >> +*str = g_realloc(*str, *len + n); >> +memcpy(*str + *len, buf, n); >> +*len += n; >> +} >> +close(fd[0]); >> +fd[0] = -1; > > and yet as far as the caller is concerned we're not indicating > any sense of failure here. They're just being returned a partially > read data stream as if it were successful. IMHO this needs to be > reported properly. > Agreed. We might make this helper return -errno in case of an erroneous read from pipe, check the value in the caller and do error_setg_errno() if smth went wrong. > > Nothing in this method has NUL terminated 'str', so we are > relying on the caller *always* honouring 'len', but. > Agreed as well. Let's allocate +1 additional byte and store '\0' in there on every iteration, making sure our result is always null-terminated. That way we won't need to check 'len' in the caller. >> +} >> + >> +/* >> + * Helper to run command with input/output redirection, >> + * sending string to stdin and taking error message from >> + * stdout/err. >> + */ >> +G_GNUC_UNUSED >> +static int ga_run_command(const char *argv[], const char *in_str, >> + const char *action, Error **errp) >> +{ >> +pid_t pid; >> +int status; >> +int retcode = -1; >> +int infd[2] = { -1, -1 }; >> +int outfd[2] = { -1, -1 }; >> +char *str = NULL; >> +size_t len = 0; >> + >> +if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) || >> +!g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) { >> +error_setg(errp, "cannot create pipe FDs"); >> +goto out; >> +} >> + >> +pid = fork(); >> +if (pid == 0) { >> +char *cherr = NULL; >> + >> +setsid(); >> + >> +if (in_str) { >> +/* Redirect stdin to infd. */ >> +close(infd[1]); >> +dup2(infd[0], 0); >> +close(infd[0]); >> +} else { >> +reopen_fd_to_null(0); >> +} >> + >> +/* Redirect stdout/stderr to outfd. */ >> +close(outfd[0]); >> +dup2(outfd[1], 1); >> +dup2(outfd[1], 2); >> +close(outfd[1]); >> + >> +execvp(argv[0], (char *const *)argv); >> + >> +/* Write the cause of failed exec to pipe for the parent to read >> it. */ >> +cherr = g_strdup_printf("failed to exec '%s'", argv[0]); >> +perror(cherr); >> +g_free(cherr); >> +_exit(EXIT_FAILURE); >> +} else if (pid < 0) { >> +error_setg_errno(errp, errno, "failed to create child process"); >> +goto out; >> +} >> + >> +if (in_str) { >> +close(infd[0]); >> +infd[0] = -1; >> +if (qemu_write_full(infd[1], in_str, strlen(in_str)) != >> +strlen(in_str)) { >> +error_setg_errno(errp, errno, "%s: cannot write to stdin pipe", >> + action); >> +goto out; >> +} >> +close(infd[1]); >> +infd[1] = -1; >> +} >> + >> +ga_pipe_read_str(outfd, &str, &len); >> + >> +ga_wait_child(pid, &status, errp); >> +if (*errp) { >> +goto out; >> +} >> + >> +if (!WIFEXITED(status)) { >> +if (len) { >> +error_setg(errp, "child process has terminated abnormally: %s", >> + str); > > ...this is reading 'str' without honouring 'len', so is likely > an array out of bounds read. > >> +} else { >> +error_setg(errp, "child p
[PATCH 0/9] tests/qemu-iotests: Fix running with "check -ssh -qcow2"
I recently wanted to check for some changes that I did to the URI handling in the block layer code, but I had to discover that a lot of iotests only work with the raw file format when using a protocol that is not "file", i.e. "./check -ssh -qcow2" shows a lot of failures. While some tests could be fixed to work with the "ssh" protocol, too, many other tests seem to be written for the "file" protocol only and thus have to be marked accordingly. After applying these patches, there is still one failure left in test 181 where I'm unsure whether it's a real bug or whether this test should also simply be marked to work with the "file" protocol only. Suggestions are welcome! Thomas Huth (9): tests/qemu-iotests: Fix test 033 for running with non-file protocols tests/qemu-iotests: Restrict test 066 to the 'file' protocol tests/qemu-iotests: Restrict test 114 to the 'file' protocol tests/qemu-iotests: Restrict test 130 to the 'file' protocol tests/qemu-iotests: Restrict test 134 and 158 to the 'file' protocol tests/qemu-iotests: Restrict test 156 to the 'file' protocol tests/qemu-iotests: Restrict tests that use --image-opts to the 'file' protocol tests/qemu-iotests: Fix some tests that use --image-opts for other protocols tests/qemu-iotests: Restrict tests using "--blockdev file" to the file protocol tests/qemu-iotests/033| 6 +++--- tests/qemu-iotests/066| 2 +- tests/qemu-iotests/114| 2 +- tests/qemu-iotests/130| 2 +- tests/qemu-iotests/134| 2 +- tests/qemu-iotests/156| 2 +- tests/qemu-iotests/158| 2 +- tests/qemu-iotests/188| 2 +- tests/qemu-iotests/189| 2 +- tests/qemu-iotests/198| 2 +- tests/qemu-iotests/263| 6 -- tests/qemu-iotests/284| 7 +++ tests/qemu-iotests/tests/detect-zeroes-registered-buf | 4 +++- tests/qemu-iotests/tests/qcow2-internal-snapshots | 2 +- tests/qemu-iotests/tests/qsd-jobs | 2 +- 15 files changed, 24 insertions(+), 21 deletions(-) -- 2.44.0
Re: [PATCH v4 13/25] memory: Add Error** argument to .log_global_start() handler
On Wed, Mar 06, 2024 at 02:34:28PM +0100, Cédric Le Goater wrote: > diff --git a/system/memory.c b/system/memory.c > index > a229a79988fce2aa3cb77e3a130db4c694e8cd49..3600e716149407c10a1f6bf8f0a81c2611cf15ba > 100644 > --- a/system/memory.c > +++ b/system/memory.c > @@ -2914,9 +2914,27 @@ static unsigned int postponed_stop_flags; > static VMChangeStateEntry *vmstate_change; > static void memory_global_dirty_log_stop_postponed_run(void); > > +/* > + * Stop dirty logging on all listeners where it was previously enabled. > + */ > +static void memory_global_dirty_log_rollback(MemoryListener *listener, > + unsigned int flags) > +{ > +global_dirty_tracking &= ~flags; Having a hook rollback function to touch the global_dirty_tracking flag is IMHO tricky. Can we instead provide a helper to call all log_global_start() hooks, but allow a gracefully fail (so rollback will be called if it fails)? bool memory_global_dirty_log_start_hooks(...) Or any better names.. Leaving global_dirty_tracking rollback to memory_global_dirty_log_start() when it returns false. Would this be cleaner? > +trace_global_dirty_changed(global_dirty_tracking); > + > +while (listener) { > +if (listener->log_global_stop) { > +listener->log_global_stop(listener); > +} > +listener = QTAILQ_PREV(listener, link); > +} > +} > + > void memory_global_dirty_log_start(unsigned int flags) > { > unsigned int old_flags; > +Error *local_err = NULL; > > assert(flags && !(flags & (~GLOBAL_DIRTY_MASK))); > > @@ -2936,7 +2954,25 @@ void memory_global_dirty_log_start(unsigned int flags) > trace_global_dirty_changed(global_dirty_tracking); > > if (!old_flags) { > -MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); > +MemoryListener *listener; > +bool ret = true; > + > +QTAILQ_FOREACH(listener, &memory_listeners, link) { > +if (listener->log_global_start) { > +ret = listener->log_global_start(listener, &local_err); > +if (!ret) { > +break; > +} > +} > +} > + > +if (!ret) { > +memory_global_dirty_log_rollback(QTAILQ_PREV(listener, link), > + flags); > +error_report_err(local_err); > +return; > +} > + > memory_region_transaction_begin(); > memory_region_update_pending = true; > memory_region_transaction_commit(); > @@ -3009,13 +3045,16 @@ static void listener_add_address_space(MemoryListener > *listener, > { > FlatView *view; > FlatRange *fr; > +Error *local_err = NULL; > > if (listener->begin) { > listener->begin(listener); > } > if (global_dirty_tracking) { > if (listener->log_global_start) { > -listener->log_global_start(listener); > +if (!listener->log_global_start(listener, &local_err)) { > +error_report_err(local_err); > +} IMHO we should assert here instead of error report. We have this to guard hot-plug during migration so I think the assert is justified: qdev_device_add_from_qdict(): if (!migration_is_idle()) { error_setg(errp, "device_add not allowed while migrating"); return NULL; } If it really happens it's a bug, as listener_add_address_space() will still keep the rest things around even if the hook failed. It'll start to be a total mess.. Thanks, > } > } > > -- > 2.44.0 > -- Peter Xu
Re: [PATCH for 9.0 v15 05/10] target/riscv: always clear vstart for ldst_whole insns
Reviewed-by: Max Chou On 2024/3/15 1:56 AM, Daniel Henrique Barboza wrote: Commit 8ff8ac6329 added a conditional to guard the vext_ldst_whole() helper if vstart >= evl. But by skipping the helper we're also not setting vstart = 0 at the end of the insns, which is incorrect. We'll move the conditional to vext_ldst_whole(), following in line with the removal of all brconds vstart >= vl that the next patch will do. The idea is to make the helpers responsible for their own vstart management. Fix ldst_whole isns by: - remove the brcond that skips the helper if vstart is >= evl; - vext_ldst_whole() now does an early exit with the same check, where evl = (vlenb * nf) >> log2_esz, but the early exit will also clear vstart. The 'width' param is now unneeded in ldst_whole_trans() and is also removed. It was used for the evl calculation for the brcond and has no other use now. The 'width' is reflected in vext_ldst_whole() via log2_esz, which is encoded by GEN_VEXT_LD_WHOLE() as "ctzl(sizeof(ETYPE))". Suggested-by: Max Chou Fixes: 8ff8ac6329 ("target/riscv: rvv: Add missing early exit condition for whole register load/store") Signed-off-by: Daniel Henrique Barboza --- target/riscv/insn_trans/trans_rvv.c.inc | 52 +++-- target/riscv/vector_helper.c| 5 +++ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 52c26a7834..1366445e1f 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -1097,13 +1097,9 @@ GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check) typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32); static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, - uint32_t width, gen_helper_ldst_whole *fn, + gen_helper_ldst_whole *fn, DisasContext *s) { -uint32_t evl = s->cfg_ptr->vlenb * nf / width; -TCGLabel *over = gen_new_label(); -tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over); - TCGv_ptr dest; TCGv base; TCGv_i32 desc; @@ -1120,8 +1116,6 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, fn(dest, base, tcg_env, desc); -gen_set_label(over); - return true; } @@ -1129,42 +1123,42 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, * load and store whole register instructions ignore vtype and vl setting. * Thus, we don't need to check vill bit. (Section 7.9) */ -#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, WIDTH) \ +#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF)\ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ { \ if (require_rvv(s) && \ QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \ -return ldst_whole_trans(a->rd, a->rs1, ARG_NF, WIDTH, \ +return ldst_whole_trans(a->rd, a->rs1, ARG_NF,\ gen_helper_##NAME, s);\ } \ return false; \ } -GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, 1) -GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, 2) -GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, 4) -GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, 8) -GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, 1) -GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, 2) -GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, 4) -GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, 8) -GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, 1) -GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, 2) -GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, 4) -GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, 8) -GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, 1) -GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, 2) -GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, 4) -GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, 8) +GEN_LDST_WHOLE_TRANS(vl1re8_v, 1) +GEN_LDST_WHOLE_TRANS(vl1re16_v, 1) +GEN_LDST_WHOLE_TRANS(vl1re32_v, 1) +GEN_LDST_WHOLE_TRANS(vl1re64_v, 1) +GEN_LDST_WHOLE_TRANS(vl2re8_v, 2) +GEN_LDST_WHOLE_TRANS(vl2re16_v, 2) +GEN_LDST_WHOLE_TRANS(vl2re32_v, 2) +GEN_LDST_WHOLE_TRANS(vl2re64_v, 2) +GEN_LDST_WHOLE_TRANS(vl4re8_v, 4) +GEN_LDST_WHOLE_TRANS(vl4re16_v, 4) +GEN_LDST_WHOLE_TRANS(vl4re32_v, 4) +GEN_LDST_WHOLE_TRANS(vl4re64_v, 4) +GEN_LDST_WHOLE_TRANS(vl8re8_v, 8) +GEN_LDST_WHOLE_TRANS(vl8re16_v, 8) +GEN_LDST_WHOLE_TRANS(vl8re32_v, 8) +GEN_LDST_WHOLE_TRANS(vl8re64_v, 8) /* * The vector whole register store instructions are encoded similar to * unmasked unit-stride store of elements with EEW=8. */ -GEN_LDST_WHOLE_TRANS(vs1r_v, 1, 1) -GEN_LDST_WHOLE_TRANS(vs2r_v, 2, 1) -GEN_LDST_WHOLE_TRANS(vs4r_v, 4, 1) -GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1) +GEN_
Re: Intention to work on GSoC project
On Fri, Mar 15, 2024 at 8:15 AM Sahil wrote: > > Hi, > > Thank you for your email. > > On Thursday, March 14, 2024 8:39:45 PM IST Eugenio Perez Martin wrote: > > Hi Sahil, > > > > It's being hard to find a good self-contained small task related to > > the project to be honest. As it would be out of SVQ, would it be ok > > for you if we start straight to the task of adding the packed vq > > format to SVQ? > > > > Thanks! > > Sure, this works too! I would love to get started with the project. > > I have a small update as well. I have read through a few docs and > articles to familiarize myself with the relevant terminology and > technicalities. > > 1. "About", "system emulation" and "user mode emulation" sections of > the user documentation [1] > 2. The migration subsystem [2] > > Some sections in the above docs were difficult to grasp. For the time > being, I have focused on those parts that I thought were relevant > to the project. > Please feel free to ask any questions, maybe we can improve the doc :). > I have also read through the following articles: > > 1. Introduction to virtio-networking and vhost-net [3] > 2. Deep dive into Virtio-networking and vhost-net [4] > 3. Virtualized Hardware Devices [5] > 4. VFIO - "Virtual Function I/O" (Just the introduction) [6] > 5. Virtio-net failover: An introduction [7] > > I hope I haven't gone off on a tangent. I was planning to finish reading > up on the following articles as well: > There is a post before the first in the series: https://www.redhat.com/en/blog/virtio-devices-and-drivers-overview-headjack-and-phone > 1. Virtqueues and virtio ring: How the data travels [8] > 2. Packed virtqueue: How to reduce overhead with virtio [9] > 3. Virtio live migration technical deep dive [10] > 4. Hands on vDPA: what do you do when you ain't got the hardware v2 (Part 1) > [11] > I think it's a good plan! If you feel like you're reading a lot of theory and want to get your hands dirty already, you can also start messing with the code with the blogs you already read. Or, maybe, after reading the Packed virtqueue one, your call. In a very brute-forced description, you can start trying to copy all the *packed* stuff of kernel's drivers/virtio/virtio_ring.c into vhost_shadow_virtqueue.c. There is a lot more in the task, and I can get into more detail if you want either here or in a meeting. If you prefer to continue with the theory it is ok too. > I believe the hands-on vPDA article will have me set up a development > environment for the project as well. > Yes, that's right. > Please let me know if I should amend my roadmap. I am > excited to get started :) > I think it is a great plan! Thanks! > Thanks, > Sahil > > [1] https://www.qemu.org/docs/master/index.html > [2] https://www.qemu.org/docs/master/devel/migration/index.html > [3] > https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net > [4] https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net > [5] > https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_getting_started_guide/sec-virtualization_getting_started-products-virtualized-hardware-devices > [6] https://www.kernel.org/doc/html/latest/driver-api/vfio.html > [7] https://www.redhat.com/en/blog/virtio-net-failover-introduction > [8] https://www.redhat.com/en/blog/virtqueues-and-virtio-ring-how-data-travels > [9] > https://developers.redhat.com/articles/2024/02/21/virtio-live-migration-technical-deep-dive > [10] > https://www.redhat.com/en/blog/packed-virtqueue-how-reduce-overhead-virtio > [11] > https://www.redhat.com/en/blog/hands-vdpa-what-do-you-do-when-you-aint-got-hardware-part-1 > >
Re: [PATCH v4 14/25] memory: Add Error** argument to the global_dirty_log routines
On Wed, Mar 06, 2024 at 02:34:29PM +0100, Cédric Le Goater wrote: > Now that the log_global*() handlers take an Error** parameter and > return a bool, do the same for memory_global_dirty_log_start() and > memory_global_dirty_log_stop(). The error is reported in the callers > for now and it will be propagated in the call stack in the next > changes. > > To be noted a functional change in ram_init_bitmaps(), if the dirty > pages logger fails to start, there is no need to synchronize the dirty > pages bitmaps. colo_incoming_start_dirty_log() could be modified in a > similar way. > > Cc: Stefano Stabellini > Cc: Anthony Perard > Cc: Paul Durrant > Cc: "Michael S. Tsirkin" > Cc: Paolo Bonzini > Cc: David Hildenbrand > Cc: Hyman Huang > Reviewed-by: Hyman Huang > Signed-off-by: Cédric Le Goater > --- > > Changes in v4: > > - Dropped log_global_stop() and log_global_sync() changes > > include/exec/memory.h | 5 - > hw/i386/xen/xen-hvm.c | 2 +- > migration/dirtyrate.c | 13 +++-- > migration/ram.c | 22 -- > system/memory.c | 11 +-- > 5 files changed, 41 insertions(+), 12 deletions(-) > > diff --git a/include/exec/memory.h b/include/exec/memory.h > index > 567bc4c9fdb53e8f63487f1400980275687d..c129ee6db7162504bd72d4cfc69b5affb2cd87e8 > 100644 > --- a/include/exec/memory.h > +++ b/include/exec/memory.h > @@ -2570,8 +2570,11 @@ void memory_listener_unregister(MemoryListener > *listener); > * memory_global_dirty_log_start: begin dirty logging for all regions > * > * @flags: purpose of starting dirty log, migration or dirty rate > + * @errp: pointer to Error*, to store an error if it happens. > + * > + * Return: true on success, else false setting @errp with error. > */ > -void memory_global_dirty_log_start(unsigned int flags); > +bool memory_global_dirty_log_start(unsigned int flags, Error **errp); > > /** > * memory_global_dirty_log_stop: end dirty logging for all regions > diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c > index > 0608ca99f5166fd6379ee674442484e805eff9c0..57cb7df50788a6c31eff68c95e8eaa856fdebede > 100644 > --- a/hw/i386/xen/xen-hvm.c > +++ b/hw/i386/xen/xen-hvm.c > @@ -654,7 +654,7 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t > length) > void qmp_xen_set_global_dirty_log(bool enable, Error **errp) > { > if (enable) { > -memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION); > +memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION, errp); > } else { > memory_global_dirty_log_stop(GLOBAL_DIRTY_MIGRATION); > } > diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c > index > 1d2e85746fb7b10eb7f149976970f9a92125af8a..d02d70b7b4b86a29d4d5540ded416543536d8f98 > 100644 > --- a/migration/dirtyrate.c > +++ b/migration/dirtyrate.c > @@ -90,9 +90,15 @@ static int64_t do_calculate_dirtyrate(DirtyPageRecord > dirty_pages, > > void global_dirty_log_change(unsigned int flag, bool start) > { > +Error *local_err = NULL; > +bool ret; > + > bql_lock(); > if (start) { > -memory_global_dirty_log_start(flag); > +ret = memory_global_dirty_log_start(flag, &local_err); > +if (!ret) { > +error_report_err(local_err); > +} > } else { > memory_global_dirty_log_stop(flag); > } > @@ -608,9 +614,12 @@ static void calculate_dirtyrate_dirty_bitmap(struct > DirtyRateConfig config) > { > int64_t start_time; > DirtyPageRecord dirty_pages; > +Error *local_err = NULL; > > bql_lock(); > -memory_global_dirty_log_start(GLOBAL_DIRTY_DIRTY_RATE); > +if (!memory_global_dirty_log_start(GLOBAL_DIRTY_DIRTY_RATE, &local_err)) > { > +error_report_err(local_err); > +} > > /* > * 1'round of log sync may return all 1 bits with > diff --git a/migration/ram.c b/migration/ram.c > index > c5149b7d717aefad7f590422af0ea4a40e7507be..397b4c0f218a66d194e44f9c5f9fe8e9885c48b6 > 100644 > --- a/migration/ram.c > +++ b/migration/ram.c > @@ -2836,18 +2836,31 @@ static void > migration_bitmap_clear_discarded_pages(RAMState *rs) > > static void ram_init_bitmaps(RAMState *rs) > { > +Error *local_err = NULL; > +bool ret = true; > + > qemu_mutex_lock_ramlist(); > > WITH_RCU_READ_LOCK_GUARD() { > ram_list_init_bitmaps(); > /* We don't use dirty log with background snapshots */ > if (!migrate_background_snapshot()) { > -memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION); > +ret = memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION, > +&local_err); > +if (!ret) { > +error_report_err(local_err); > +goto out_unlock; Here we may need to free the bitmaps created in ram_list_init_bitmaps(). We can have a helper ram_bitmaps_destroy() for that. One thing be careful is the new file_bmap can be cre
Re: [PATCH v3 1/3] migration/multifd: Ensure we're not given a socket for file migration
On Fri, Mar 15, 2024 at 12:20:38AM -0300, Fabiano Rosas wrote: > When doing migration using the fd: URI, QEMU will fetch the file > descriptor passed in via the monitor at > fd_start_outgoing|incoming_migration(), which means the checks at > migration_channels_and_transport_compatible() happen too soon and we > don't know at that point whether the FD refers to a plain file or a > socket. > > For this reason, we've been allowing a migration channel of type > SOCKET_ADDRESS_TYPE_FD to pass the initial verifications in scenarios > where the socket migration is not supported, such as with fd + multifd. > > The commit decdc76772 ("migration/multifd: Add mapped-ram support to > fd: URI") was supposed to add a second check prior to starting > migration to make sure a socket fd is not passed instead of a file fd, > but failed to do so. > > Add the missing verification and update the comment explaining this > situation which is currently incorrect. > > Fixes: decdc76772 ("migration/multifd: Add mapped-ram support to fd: URI") > Signed-off-by: Fabiano Rosas Reviewed-by: Peter Xu -- Peter Xu
Re: [PATCH v3 2/3] migration/multifd: Duplicate the fd for the outgoing_args
On Fri, Mar 15, 2024 at 12:20:39AM -0300, Fabiano Rosas wrote: > We currently store the file descriptor used during the main outgoing > channel creation to use it again when creating the multifd > channels. > > Since this fd is used for the first iochannel, there's risk that the > QIOChannel gets freed and the fd closed while outgoing_args.fd still > has it available. This could lead to an fd-reuse bug. > > Duplicate the outgoing_args fd to avoid this issue. > > Suggested-by: Peter Xu > Signed-off-by: Fabiano Rosas Reviewed-by: Peter Xu -- Peter Xu
Re: [PATCH v2 6/7] qga/commands-posix: use ga_run_command helper when suspending via sysfs
On 3/5/24 20:34, Daniel P. Berrangé wrote: > [Вы нечасто получаете письма от berra...@redhat.com. Узнайте, почему это > важно, по адресу https://aka.ms/LearnAboutSenderIdentification ] > > On Fri, Mar 01, 2024 at 07:28:57PM +0200, Andrey Drobyshev wrote: >> We replace the direct call to open() with a "sh -c 'echo ...'" call, so >> that it becomes an executable command. > > Introduced an indirection via the shell is a significant step > backwards IMHO. > >> >> Signed-off-by: Andrey Drobyshev >> --- >> qga/commands-posix.c | 36 >> 1 file changed, 4 insertions(+), 32 deletions(-) >> >> diff --git a/qga/commands-posix.c b/qga/commands-posix.c >> index dd2a7ad2e6..f3f4a05e2d 100644 >> --- a/qga/commands-posix.c >> +++ b/qga/commands-posix.c >> @@ -1921,49 +1921,21 @@ static void linux_sys_state_suspend(SuspendMode >> mode, Error **errp) >> Error *local_err = NULL; >> const char *sysfile_strs[3] = {"disk", "mem", NULL}; >> const char *sysfile_str = sysfile_strs[mode]; >> -pid_t pid; >> -int status; >> >> if (!sysfile_str) { >> error_setg(errp, "unknown guest suspend mode"); >> return; >> } >> >> -pid = fork(); >> -if (!pid) { >> -/* child */ >> -int fd; >> - >> -setsid(); >> -reopen_fd_to_null(0); >> -reopen_fd_to_null(1); >> -reopen_fd_to_null(2); >> - >> -fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); >> -if (fd < 0) { >> -_exit(EXIT_FAILURE); >> -} >> - >> -if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) { >> -_exit(EXIT_FAILURE); >> -} >> - >> -_exit(EXIT_SUCCESS); > > > This pre-existing code is strange to me. Why do we need to fork a > new process in order to write to /sys/power/state ? > > Looking at the original commit > > commit 11d0f1255bd5651f628280dc96c4ce9d63ae9236 > Author: Luiz Capitulino > Date: Tue Feb 28 11:03:03 2012 -0300 > > qemu-ga: add guest-suspend-disk > > > The code made a little more sense, as after fork() it first > tried to execve 'pm-utils', and then had the sysfs codepath > as a fallback. IOW having the sysfs code after fork() was a > much easier code structure. > > This was all changed in > > commit 246d76eba1944d7e59affb288ec27d7fcfb5d256 > Author: Daniel Henrique Barboza > Date: Thu Jun 21 07:21:50 2018 -0300 > > qga: guest_suspend: decoupling pm-utils and sys logic > > > so the pm-utils logic runs in a separate forked child > from the sysfs logic. > > AFAICT, that should have made it completely redundant to > fork a process to access /sys/power/state. > > Does anyone know of a reason to keep the fork() here ? Of > not we should just be calling 'g_file_set_contents' without > fork > In the original commit message Luiz Capitulino explained that multiple forks are needed to properly reap child processes needed for execl(). AFAIU since writing to /sys/power/state doesn't require execl(), fork() isn't needed either. I think the 2nd commit you mention simply kept things as they were since it wasn't the original goal of the patch. So we're just looking at legacy code. I agree that in this case my original patch is redundant and we may replace it with smth like g_file_set_contents(). I'll add it in v3. >> -} else if (pid < 0) { >> -error_setg_errno(errp, errno, "failed to create child process"); >> -return; >> -} >> +g_autofree char *echo_cmd = g_strdup_printf( >> +"echo %s > " LINUX_SYS_STATE_FILE, sysfile_str); >> +const char *argv[] = {"sh", "-c", echo_cmd, NULL}; >> >> -ga_wait_child(pid, &status, &local_err); >> +ga_run_command(argv, NULL, "suspend", &local_err); >> if (local_err) { >> error_propagate(errp, local_err); >> return; >> } >> - >> -if (WEXITSTATUS(status)) { >> -error_setg(errp, "child process has failed to suspend"); >> -} >> - >> } >> >> static void guest_suspend(SuspendMode mode, Error **errp) >> -- >> 2.39.3 >> >> > > With regards, > Daniel > -- > |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o-https://fstop138.berrange.com :| > |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| >
Re: [RFC PATCH v3 3/3] migration: Add fd to FileMigrationArgs
Daniel P. Berrangé writes: > On Fri, Mar 15, 2024 at 12:20:40AM -0300, Fabiano Rosas wrote: >> The fd: URI has supported migration to a file or socket since before >> QEMU 8.2. In 8.2 we added the file: URI that supported migration to a >> file. So now we have two ways (three if you count exec:>cat) to >> migrate to a file. Fine. >> >> However, >> >> In 8.2 we also added the new qmp_migrate API that uses a JSON channel >> list instead of the URI. It added two migration transports SOCKET and >> FILE. It was decided that the new API would classify the fd migration >> as a type of socket migration, neglecting the fact that the fd.c code >> also supported file migrations. >> >> In 9.0 we're adding support for fd + multifd + mapped-ram, which is >> tied to the file migration. This was implemented in fd.c, which is >> only reachable when the SOCKET address type is used. >> >> The result of this is that we're asking users of the new API to create (1) >> something called a "socket" to perform migration to a plain file. And >> creating something called a "file" provides no way of passing in a >> file descriptor. This is confusing. > > The 'file:' protocol eventually calls into qemu_open, and this > transparently allows for FD passing using /dev/fdset/NNN syntax > to pass in FDs. > Ok, that's technically correct. But it works differently from fd:fdname. /dev/fdset requires the user to switch from getfd to add-fd and it requires QEMU and libvirt/user to synchronize on the open() flags being used. QEMU cannot just receive any fd, it must be an fd that matches the flags QEMU passed into qio_channel_file_new_path(). Users will have to adapt to the new API anyway, so it might be ok to require these changes around it as well. To keep compatibility, we'd continue to accept the fd that comes from "fd:" or SOCKET_ADDRESS_TYPE_FD. But we'd be making it harder for users of the fd: syntax to move to the new API. I also don't know how we would deal with fdset when (if) we add support for passing in more channels in the new API. It supports multiple fds, but how do we deal with something like: "[ { 'channel-type': 'main'," "'addr': { 'transport': 'file'," " 'filename': '/dev/fdset/1' } }, " { 'channel-type': 'second'," "'addr': { 'transport': 'file'," " 'filename': '/dev/fdset/2' } } ]", Maybe that's too far ahead for this discussion. >> diff --git a/qapi/migration.json b/qapi/migration.json >> index aa1b39bce1..37f4b9c6fb 100644 >> --- a/qapi/migration.json >> +++ b/qapi/migration.json >> @@ -1656,13 +1656,20 @@ >> # >> # @filename: The file to receive the migration stream >> # >> +# @fd: A file descriptor name or number. File descriptors must be >> +# first added with the 'getfd' command. (since 9.0). >> +# >> # @offset: The file offset where the migration stream will start >> # >> +# Since 9.0, all members are optional, but at least one of @filename >> +# or @fd are required. >> +# >> # Since: 8.2 >> ## >> { 'struct': 'FileMigrationArgs', >> - 'data': { 'filename': 'str', >> -'offset': 'uint64' } } >> + 'data': { '*filename': 'str', >> +'*fd': 'str', >> +'*offset': 'uint64' } } > > Adding 'fd' here is not desirable, because 'filename' is > resolved via qemu_open which allows for FD passing without > introducing any new syntax in interfaces which take filenames. > > With regards, > Daniel
Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()
On 3/15/24 12:01, Peter Xu wrote: On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote: migrate_set_state is also unintuitive because it ignores invalid state transitions and we've been using that property to deal with special states such as POSTCOPY_PAUSED and FAILED: - After the migration goes into POSTCOPY_PAUSED, the resumed migration's migrate_init() will try to set the state NONE->SETUP, which is not valid. - After save_setup fails, the migration goes into FAILED, but wait_unplug will try to transition SETUP->ACTIVE, which is also not valid. I am not sure I understand what the plan is. Both solutions are problematic regarding the state transitions. Should we consider that waiting for failover devices to unplug is an internal step of the SETUP phase not transitioning to ACTIVE ? If to unblock this series, IIUC the simplest solution is to do what Fabiano suggested, that we move qemu_savevm_wait_unplug() to be before the check of setup() ret. The simplest is IMHO moving qemu_savevm_wait_unplug() before qemu_savevm_state_setup() and leave patch 10 is unchanged. See below the extra patch. It looks much cleaner than what we have today. In that case, the state change in qemu_savevm_wait_unplug() should be benign and we should see a super small window it became ACTIVE but then it should be FAILED (and IIUC the patch itself will need to use ACTIVE as "old_state", not SETUP anymore). OK. I will give it a try to compare. For the long term, maybe we can remove the WAIT_UNPLUG state? I hope so, it's an internal SETUP state for me. The only Libvirt support seems to be here: commit 8a226ddb3602586a2ba2359afc4448c02f566a0e Author: Laine Stump Date: Wed Jan 15 16:38:57 2020 -0500 qemu: add wait-unplug to qemu migration status enum Considering that qemu_savevm_wait_unplug() can be a noop if the device is already unplugged, I think it means no upper layer app should rely on this state to present. Thanks, C. @@ -3383,11 +3383,10 @@ bool migration_rate_limit(void) * unplugged */ -static void qemu_savevm_wait_unplug(MigrationState *s, int old_state, -int new_state) +static void qemu_savevm_wait_unplug(MigrationState *s, int state) { if (qemu_savevm_state_guest_unplug_pending()) { -migrate_set_state(&s->state, old_state, MIGRATION_STATUS_WAIT_UNPLUG); +migrate_set_state(&s->state, state, MIGRATION_STATUS_WAIT_UNPLUG); while (s->state == MIGRATION_STATUS_WAIT_UNPLUG && qemu_savevm_state_guest_unplug_pending()) { @@ -3410,9 +3409,7 @@ static void qemu_savevm_wait_unplug(Migr } } -migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, new_state); -} else { -migrate_set_state(&s->state, old_state, new_state); +migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, state); } } @@ -3469,17 +3466,19 @@ static void *migration_thread(void *opaq qemu_savevm_send_colo_enable(s->to_dst_file); } +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP); + bql_lock(); qemu_savevm_state_setup(s->to_dst_file); bql_unlock(); -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, - MIGRATION_STATUS_ACTIVE); - s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; trace_migration_thread_setup_complete(); +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_ACTIVE); + while (migration_is_active()) { if (urgent || !migration_rate_exceeded(s->to_dst_file)) { MigIterateState iter_state = migration_iteration_run(s); @@ -3580,18 +3579,20 @@ static void *bg_migration_thread(void *o ram_write_tracking_prepare(); #endif +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP); + bql_lock(); qemu_savevm_state_header(s->to_dst_file); qemu_savevm_state_setup(s->to_dst_file); bql_unlock(); -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, - MIGRATION_STATUS_ACTIVE); - s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; trace_migration_thread_setup_complete(); +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_ACTIVE); + bql_lock(); if (migration_stop_vm(s, RUN_STATE_PAUSED)) {
Re: [PATCH 17/18] target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types
On 13/10/23 06:34, Richard Henderson wrote: On 10/10/23 02:28, Philippe Mathieu-Daudé wrote: "target/foo/cpu-qom.h" can not use any target specific definitions. Currently "target/mips/cpu-qom.h" defines TYPE_MIPS_CPU depending on the mips(32)/mips64 build type. This doesn't scale in a heterogeneous context where we need to access both types concurrently. In order to do that, introduce the new MIPS32_CPU / MIPS64_CPU types, both inheriting a common TYPE_MIPS_CPU base type. Keep the current CPU types registered in mips_register_cpudef_type() as 32 or 64-bit, but instead of depending on the binary built being targeting 32/64-bit, check whether the CPU is 64-bit by looking at the CPU_MIPS64 bit. Signed-off-by: Philippe Mathieu-Daudé --- target/mips/cpu-qom.h | 13 ++--- target/mips/cpu.h | 3 +++ target/mips/cpu.c | 11 ++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h index 9c98ca1956..1a71509b5e 100644 --- a/target/mips/cpu-qom.h +++ b/target/mips/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU MIPS CPU + * QEMU MIPS CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -23,13 +23,12 @@ #include "hw/core/cpu.h" #include "qom/object.h" -#ifdef TARGET_MIPS64 -#define TYPE_MIPS_CPU "mips64-cpu" -#else -#define TYPE_MIPS_CPU "mips-cpu" -#endif +#define TYPE_MIPS_CPU "mips-cpu" +#define TYPE_MIPS32_CPU "mips32-cpu" +#define TYPE_MIPS64_CPU "mips64-cpu" -OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU) +OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU) +OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU) #define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 6b026e6bcf..3b6d0a7a8a 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -10,6 +10,9 @@ #include "hw/clock.h" #include "mips-defs.h" +/* Abstract QOM MIPS CPU, not exposed to other targets */ +OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU) Why is this one moved back to cpu.h? You exposed TYPE_X86_CPU in i386/cpu-qom.h... First thinking was to expose the base TYPE, so we can use QOM methods to enumerate implementations, but not expose QOM state/class getter for the base type (except in target/foo/). HW would use concrete 32 or 64b type state/class getter. I might be wrong, so I'll keep the base type exposed for now. We might restrict later.
Re: Another CXL/MMIO tcg tlb corner case
Jørgen Hansen writes: > Hi, > > While doing some testing using numactl-based interleaving of application > memory > across regular memory and CXL-based memory using QEMU with tcg, I ran into an > issue similar to what we saw a while back - link to old issue: > https://lore.kernel.org/qemu-devel/CAFEAcA_a_AyQ=epz3_+cheat8crsk9mou894wbnw_fywamk...@mail.gmail.com/#t. > > When running: > > numactl --interleave 0,1 ./cachebench … > > I hit the following: > > numactl --interleave 0,1 ./cachebench --json_test_config > ../test_configs/hit_ratio/graph_cache_follower_assocs/config.json > qemu: fatal: cpu_io_recompile: could not find TB for pc=0x7fffc3926dd4 Ok so this will be because we (by design) don't cache TB's for MMIO regions. But as you say: > > Looking at the tb being executed, it looks like it is a single instruction tb, > so with my _very_ limited understanding of tcg, it shouldn’t be necessary to > do the IO recompile: > > (gdb) up 13 > > #13 0x55ca13ac in cpu_loop_exec_tb (tb_exit=0x749ff6d8, > last_tb=, pc=, tb=0x7fffc3926cc0 > , cpu=0x578c19c0) at > ../accel/tcg/cpu-exec.c:904 > 904 tb = cpu_tb_exec(cpu, tb, tb_exit); > (gdb) print *tb > $1 = {pc = 0, cs_base = 0, flags = 415285939, cflags = 4278321152, size = 7, > icount = 1, tc = {ptr = 0x7fffc3926d80 , size = > 176}, page_next = {0, 0}, page_addr = {18446744073709551615, > 18446744073709551615}, jmp_lock = {value = 0}, jmp_reset_offset = > {65535, 65535}, jmp_insn_offset = {65535, 65535}, jmp_target_addr = > {0, 0}, jmp_list_head = 140736474540928, jmp_list_next = {0, 0}, > jmp_dest = {0, 0}} with an icount of 1 we by definition can do io. This is done in the translator_loop: /* * Disassemble one instruction. The translate_insn hook should * update db->pc_next and db->is_jmp to indicate what should be * done next -- either exiting this loop or locate the start of * the next instruction. */ if (db->num_insns == db->max_insns) { /* Accept I/O on the last instruction. */ set_can_do_io(db, true); } and we see later on: tb->icount = db->num_insns; So I guess we must have gone into the translator loop expecting to translate more? (side note having int8_t type for the saved bool value seems weird). Could you confirm by doing something like: if (tb->icount == 1 && db->max_insns > 1) { fprintf(stderr, "ended up doing one insn (%d, %d)", db->max_insns, db->saved_can_do_io); } after we set tb->icount? > If the application is run entirely out of MMIO memory, things work fine (the > previous patches related to this is in Jonathans branch), so one thought is > that > it is related to having the code on a mix of regular and CXL memory. Since we > previously had issues with code crossing page boundaries where only the second > page is MMIO, I tried out the following change to the fix introduced for that > issue thinking that reverting to the slow path in the middle of the > translation > might not correctly update can_do_io: > > diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c > index 38c34009a5..db6ea360e0 100644 > --- a/accel/tcg/translator.c > +++ b/accel/tcg/translator.c > @@ -258,6 +258,7 @@ static void *translator_access(CPUArchState *env, > DisasContextBase *db, > if (unlikely(new_page1 == -1)) { > tb_unlock_pages(tb); > tb_set_page_addr0(tb, -1); > +set_can_do_io(db, true); > return NULL; > } > > With that change, things work fine. Not saying that this is a valid fix for > the > issue, but just trying to provide as much information as possible :) I can see why this works, my worry is if we address all the early exit cases here. > > Thanks, > Jorgen -- Alex Bennée Virtualisation Tech Lead @ Linaro
Re: [PATCH] target/s390x: improve cpu compatibility check error message
Am 14.03.24 um 20:00 schrieb Claudio Fontana: some users were confused by this message showing under TCG: Selected CPU generation is too new. Maximum supported model in the configuration: 'xyz' Try to clarify that the maximum can depend on the accel by adding also the current accelerator to the message as such: Selected CPU generation is too new. Maximum supported model in the accelerator 'tcg' configuration: 'xyz' Signed-off-by: Claudio Fontana Independent on which message we end up with (see comments in this mail thread), I agree that improving the error message is helpful. Acked-by: Christian Borntraeger --- target/s390x/cpu_models.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 1a1c096122..0d6d8fc727 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -508,14 +508,14 @@ static void check_compatibility(const S390CPUModel *max_model, if (model->def->gen > max_model->def->gen) { error_setg(errp, "Selected CPU generation is too new. Maximum " - "supported model in the configuration: \'%s\'", - max_model->def->name); + "supported model in the accelerator \'%s\' configuration: \'%s\'", + current_accel_name(), max_model->def->name); return; } else if (model->def->gen == max_model->def->gen && model->def->ec_ga > max_model->def->ec_ga) { error_setg(errp, "Selected CPU GA level is too new. Maximum " - "supported model in the configuration: \'%s\'", - max_model->def->name); + "supported model in the accelerator \'%s\' configuration: \'%s\'", + current_accel_name(), max_model->def->name); return; } @@ -537,7 +537,8 @@ static void check_compatibility(const S390CPUModel *max_model, error_setg(errp, " "); s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat); error_prepend(errp, "Some features requested in the CPU model are not " - "available in the configuration: "); + "available in the accelerator \'%s\' configuration: ", + current_accel_name()); } S390CPUModel *get_max_cpu_model(Error **errp)
Re: Any interest in the QEMU community attending DVCon Europe October 2024?
> Le 5 mars 2024 à 16:50, Alex Bennée a écrit : > > > Hi, > > Over recent years there has been a push to make QEMU more flexible for > EDA type applications. As long time developers know there are a number > of downstream forks of QEMU which have their own solutions for modelling > heterogeneous systems and integrating with hardware models. The work by > Philippe, Anton and others to build a single binary with composable > hardware is aiming at least to solve the heterogeneous modelling problem > in the upstream project. > > While we do discuss these "TCG" topics during KVM Forum the project may > benefit from doing some outreach at some conferences where simulation > and emulation are the primary focus. > > The Design and Verification Conference & Exhibition Europe (DVCon > Europe) is the premier European technical conference on system, > software, design, verification, validation and integration. This year it > will be on the 15-16 October 2024 in Munich. See: https://dvcon-europe.org/ > > There have been a number of papers and workshops on QEMU/KVM topics over > the years. Unfortunately the website doesn't provide slides or videos of > the talks but topics have included how QEMU can be used as a fast > instruction simulator alongside things such as SystemC models or > virtualisation can be leveraged to accelerate full system emulation. > > The main tracks are fairly academic where engineering and research > papers are submitted and if accepted can then be presented at the > conference. This is probably over the top for QEMU related stuff but > their is a tutorial track (deadline for Abstracts 1st July) which could > be a good target for a introduction to the features and capabilities of > the QEMU upstream. I suspect there would be interest in the wider > modelling community to find out more about how to use the upstream > project directly. > > There is a co-located "SystemC Evolution Day" on the 17th where there > might well be a strong overlap between SystemC users and QEMU. Mark > Burton is involved with that and is keen for proposals talking about > integrating SystemC models with QEMU. Please send a message to > mbur...@quicinc.com if you're interested. > > So is anyone interested? > > Should we do more within the community to network and discuss our plans > for QEMU as a modelling solution? > > Any other thoughts? I would love to hear how Qemu can participate into heterogeneous simulations. One case is where multiple Qemu instances collaborate with limited interactions, One case is where there is with memory aliasing (cortex M/R see a « window » of the main memory with a different address for the same byte) between Qemu. One case Qemu is integrated with other simulators. An interface to handle aliasing, MMIO, SMMU, GIC are required to allow all possible cases of which simulator emulate what. > > -- > Alex Bennée > Virtualisation Tech Lead @ Linaro
[PATCH v3 1/7] qga: guest-get-fsinfo: add optional 'total-bytes-root' field
Since the commit 25b5ff1a86 ("qga: add mountpoint usage info to GuestFilesystemInfo") we have 2 values reported in guest-get-fsinfo: used = (f_blocks - f_bfree), total = (f_blocks - f_bfree + f_bavail) as returned by statvfs(3). While on Windows guests that's all we can get with GetDiskFreeSpaceExA(), on POSIX guests we might also be interested in total file system size, as it's visible for root user. Let's add an optional field 'total-bytes-root' to GuestFilesystemInfo struct, which'd only be reported on POSIX and represent f_blocks value as returned by statvfs(3). While here, let's document better where those values come from in both POSIX and Windows. Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 2 ++ qga/commands-win32.c | 1 + qga/qapi-schema.json | 12 +++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 26008db497..8207c4c47e 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -1569,8 +1569,10 @@ static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount, nonroot_total = used + buf.f_bavail; fs->used_bytes = used * fr_size; fs->total_bytes = nonroot_total * fr_size; +fs->total_bytes_root = buf.f_blocks * fr_size; fs->has_total_bytes = true; +fs->has_total_bytes_root = true; fs->has_used_bytes = true; } diff --git a/qga/commands-win32.c b/qga/commands-win32.c index a1015757d8..9e820aad8d 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1143,6 +1143,7 @@ static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp) fs = g_malloc(sizeof(*fs)); fs->name = g_strdup(guid); fs->has_total_bytes = false; +fs->has_total_bytes_root = false; fs->has_used_bytes = false; if (len == 0) { fs->mountpoint = g_strdup("System Reserved"); diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index b8efe31897..093a5ab602 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1031,8 +1031,18 @@ # @type: file system type string # # @used-bytes: file system used bytes (since 3.0) +# * POSIX: (f_blocks - f_bfree) * f_frsize, as returned by statvfs(3) +# * Windows: (TotalNumberOfBytes - TotalNumberOfFreeBytes), as returned +# by GetDiskFreeSpaceEx() # # @total-bytes: non-root file system total bytes (since 3.0) +# * POSIX: (f_blocks - f_bfree + f_bavail) * f_frsize, as returned by +# statvfs(3) +# * Windows: TotalNumberOfBytes, as returned by GetDiskFreeSpaceEx() +# +# @total-bytes-root: total file system size in bytes (as visible for a +# priviledged user) (since 8.3) +# * POSIX only: (f_blocks * f_frsize), returned by statvfs(3) # # @disk: an array of disk hardware information that the volume lies # on, which may be empty if the disk type is not supported @@ -1042,7 +1052,7 @@ { 'struct': 'GuestFilesystemInfo', 'data': {'name': 'str', 'mountpoint': 'str', 'type': 'str', '*used-bytes': 'uint64', '*total-bytes': 'uint64', - 'disk': ['GuestDiskAddress']} } + '*total-bytes-root': 'uint64', 'disk': ['GuestDiskAddress']} } ## # @guest-get-fsinfo: -- 2.39.3
[PATCH v3 0/7] qga/commands-posix: replace code duplicating commands with a helper
v2 -> v3: * Patch 2/7: - ga_pipe_read_str() helper now returns -errno in case of an error during read from pipe, so that the caller may use it to set error_setg_errno(); - ga_pipe_read_str() allocates +1 additional byte to make the string read from pipe null-terminated on every iteration; * Patch 6/7: patch is rewritten to completely get rid of fork()/exec() when suspending via sysfs, it now simply uses g_file_set_contents() (suggested by Daniel); * Patch 7/7: cosmetic change: removed unneeded brackets in an expression. v2: https://lists.nongnu.org/archive/html/qemu-devel/2024-03/msg00147.html Andrey Drobyshev (7): qga: guest-get-fsinfo: add optional 'total-bytes-root' field qga: introduce ga_run_command() helper for guest cmd execution qga/commands-posix: qmp_guest_shutdown: use ga_run_command helper qga/commands-posix: qmp_guest_set_time: use ga_run_command helper qga/commands-posix: execute_fsfreeze_hook: use ga_run_command helper qga/commands-posix: don't do fork()/exec() when suspending via sysfs qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper qga/commands-posix.c | 404 +++ qga/commands-win32.c | 1 + qga/qapi-schema.json | 12 +- 3 files changed, 193 insertions(+), 224 deletions(-) -- 2.39.3
[PATCH v3 6/7] qga/commands-posix: don't do fork()/exec() when suspending via sysfs
Since commit 246d76eba ("qga: guest_suspend: decoupling pm-utils and sys logic") pm-utils logic is running in a separate child from the sysfs logic. Now when suspending via sysfs we don't really need to do that in a separate process as we only need to perform one write to /sys/power/state. Let's just use g_file_set_contents() to simplify things here. Suggested-by: Daniel P. Berrangé Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 41 + 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 610d225d30..e0ea377f65 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -1928,52 +1928,21 @@ static bool linux_sys_state_supports_mode(SuspendMode mode, Error **errp) static void linux_sys_state_suspend(SuspendMode mode, Error **errp) { -Error *local_err = NULL; +GError *local_gerr = NULL; const char *sysfile_strs[3] = {"disk", "mem", NULL}; const char *sysfile_str = sysfile_strs[mode]; -pid_t pid; -int status; if (!sysfile_str) { error_setg(errp, "unknown guest suspend mode"); return; } -pid = fork(); -if (!pid) { -/* child */ -int fd; - -setsid(); -reopen_fd_to_null(0); -reopen_fd_to_null(1); -reopen_fd_to_null(2); - -fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); -if (fd < 0) { -_exit(EXIT_FAILURE); -} - -if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) { -_exit(EXIT_FAILURE); -} - -_exit(EXIT_SUCCESS); -} else if (pid < 0) { -error_setg_errno(errp, errno, "failed to create child process"); -return; -} - -ga_wait_child(pid, &status, &local_err); -if (local_err) { -error_propagate(errp, local_err); +if (!g_file_set_contents(LINUX_SYS_STATE_FILE, sysfile_str, + -1, &local_gerr)) { +error_setg(errp, "suspend: cannot write to '%s': %s", + LINUX_SYS_STATE_FILE, local_gerr->message); return; } - -if (WEXITSTATUS(status)) { -error_setg(errp, "child process has failed to suspend"); -} - } static void guest_suspend(SuspendMode mode, Error **errp) -- 2.39.3
[PATCH v3 2/7] qga: introduce ga_run_command() helper for guest cmd execution
When executing guest commands in *nix environment, we repeat the same fork/exec pattern multiple times. Let's just separate it into a single helper which would also be able to feed input data into the launched process' stdin. This way we can avoid code duplication. To keep the history more bisectable, let's replace qmp commands implementations one by one. Also add G_GNUC_UNUSED attribute to the helper and remove it in the next commit. Originally-by: Yuri Pudgorodskiy Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 150 +++ 1 file changed, 150 insertions(+) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 8207c4c47e..ad05630086 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -76,6 +76,156 @@ static void ga_wait_child(pid_t pid, int *status, Error **errp) g_assert(rpid == pid); } +static ssize_t ga_pipe_read_str(int fd[2], char **str) +{ +ssize_t n, len = 0; +char buf[1024]; + +close(fd[1]); +fd[1] = -1; +while ((n = read(fd[0], buf, sizeof(buf))) != 0) { +if (n < 0) { +if (errno == EINTR) { +continue; +} else { +len = -errno; +break; +} +} +*str = g_realloc(*str, len + n + 1); +memcpy(*str + len, buf, n); +len += n; +*str[len] = '\0'; +} +close(fd[0]); +fd[0] = -1; + +return len; +} + +/* + * Helper to run command with input/output redirection, + * sending string to stdin and taking error message from + * stdout/err. + */ +G_GNUC_UNUSED +static int ga_run_command(const char *argv[], const char *in_str, + const char *action, Error **errp) +{ +pid_t pid; +int status; +int retcode = -1; +int infd[2] = { -1, -1 }; +int outfd[2] = { -1, -1 }; +char *str = NULL; +ssize_t len = 0; + +if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) || +!g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) { +error_setg(errp, "cannot create pipe FDs"); +goto out; +} + +pid = fork(); +if (pid == 0) { +char *cherr = NULL; + +setsid(); + +if (in_str) { +/* Redirect stdin to infd. */ +close(infd[1]); +dup2(infd[0], 0); +close(infd[0]); +} else { +reopen_fd_to_null(0); +} + +/* Redirect stdout/stderr to outfd. */ +close(outfd[0]); +dup2(outfd[1], 1); +dup2(outfd[1], 2); +close(outfd[1]); + +execvp(argv[0], (char *const *)argv); + +/* Write the cause of failed exec to pipe for the parent to read it. */ +cherr = g_strdup_printf("failed to exec '%s'", argv[0]); +perror(cherr); +g_free(cherr); +_exit(EXIT_FAILURE); +} else if (pid < 0) { +error_setg_errno(errp, errno, "failed to create child process"); +goto out; +} + +if (in_str) { +close(infd[0]); +infd[0] = -1; +if (qemu_write_full(infd[1], in_str, strlen(in_str)) != +strlen(in_str)) { +error_setg_errno(errp, errno, "%s: cannot write to stdin pipe", + action); +goto out; +} +close(infd[1]); +infd[1] = -1; +} + +len = ga_pipe_read_str(outfd, &str); +if (len < 0) { +error_setg_errno(errp, -len, "%s: cannot read from stdout/stderr pipe", + action); +goto out; +} + +ga_wait_child(pid, &status, errp); +if (*errp) { +goto out; +} + +if (!WIFEXITED(status)) { +if (len) { +error_setg(errp, "child process has terminated abnormally: %s", + str); +} else { +error_setg(errp, "child process has terminated abnormally"); +} +goto out; +} + +retcode = WEXITSTATUS(status); + +if (WEXITSTATUS(status)) { +if (len) { +error_setg(errp, "child process has failed to %s: %s", + action, str); +} else { +error_setg(errp, "child process has failed to %s: exit status %d", + action, WEXITSTATUS(status)); +} +goto out; +} + +out: +g_free(str); + +if (infd[0] != -1) { +close(infd[0]); +} +if (infd[1] != -1) { +close(infd[1]); +} +if (outfd[0] != -1) { +close(outfd[0]); +} +if (outfd[1] != -1) { +close(outfd[1]); +} + +return retcode; +} + void qmp_guest_shutdown(const char *mode, Error **errp) { const char *shutdown_flag; -- 2.39.3
[PATCH v3 4/7] qga/commands-posix: qmp_guest_set_time: use ga_run_command helper
There's no need to check for the existence of "/sbin/hwclock", the exec() call will do that for us. Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 43 +++ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index d4025e0c1e..94b652d54e 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -279,21 +279,9 @@ void qmp_guest_shutdown(const char *mode, Error **errp) void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) { int ret; -int status; -pid_t pid; Error *local_err = NULL; struct timeval tv; -static const char hwclock_path[] = "/sbin/hwclock"; -static int hwclock_available = -1; - -if (hwclock_available < 0) { -hwclock_available = (access(hwclock_path, X_OK) == 0); -} - -if (!hwclock_available) { -error_setg(errp, QERR_UNSUPPORTED); -return; -} +const char *argv[] = {"/sbin/hwclock", has_time ? "-w" : "-s", NULL}; /* If user has passed a time, validate and set it. */ if (has_time) { @@ -324,37 +312,12 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) * just need to synchronize the hardware clock. However, if no time was * passed, user is requesting the opposite: set the system time from the * hardware clock (RTC). */ -pid = fork(); -if (pid == 0) { -setsid(); -reopen_fd_to_null(0); -reopen_fd_to_null(1); -reopen_fd_to_null(2); - -/* Use '/sbin/hwclock -w' to set RTC from the system time, - * or '/sbin/hwclock -s' to set the system time from RTC. */ -execl(hwclock_path, "hwclock", has_time ? "-w" : "-s", NULL); -_exit(EXIT_FAILURE); -} else if (pid < 0) { -error_setg_errno(errp, errno, "failed to create child process"); -return; -} - -ga_wait_child(pid, &status, &local_err); +ga_run_command(argv, NULL, "set hardware clock to system time", + &local_err); if (local_err) { error_propagate(errp, local_err); return; } - -if (!WIFEXITED(status)) { -error_setg(errp, "child process has terminated abnormally"); -return; -} - -if (WEXITSTATUS(status)) { -error_setg(errp, "hwclock failed to set hardware clock to system time"); -return; -} } typedef enum { -- 2.39.3
[PATCH v3 3/7] qga/commands-posix: qmp_guest_shutdown: use ga_run_command helper
Also remove the G_GNUC_UNUSED attribute added in the previous commit from the helper. Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 39 ++- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index ad05630086..d4025e0c1e 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -108,7 +108,6 @@ static ssize_t ga_pipe_read_str(int fd[2], char **str) * sending string to stdin and taking error message from * stdout/err. */ -G_GNUC_UNUSED static int ga_run_command(const char *argv[], const char *in_str, const char *action, Error **errp) { @@ -230,8 +229,6 @@ void qmp_guest_shutdown(const char *mode, Error **errp) { const char *shutdown_flag; Error *local_err = NULL; -pid_t pid; -int status; #ifdef CONFIG_SOLARIS const char *powerdown_flag = "-i5"; @@ -260,46 +257,22 @@ void qmp_guest_shutdown(const char *mode, Error **errp) return; } -pid = fork(); -if (pid == 0) { -/* child, start the shutdown */ -setsid(); -reopen_fd_to_null(0); -reopen_fd_to_null(1); -reopen_fd_to_null(2); - +const char *argv[] = {"/sbin/shutdown", #ifdef CONFIG_SOLARIS -execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y", - "hypervisor initiated shutdown", (char *)NULL); + shutdown_flag, "-g0", "-y", #elif defined(CONFIG_BSD) -execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0", - "hypervisor initiated shutdown", (char *)NULL); + shutdown_flag, "+0", #else -execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", - "hypervisor initiated shutdown", (char *)NULL); + "-h", shutdown_flag, "+0", #endif -_exit(EXIT_FAILURE); -} else if (pid < 0) { -error_setg_errno(errp, errno, "failed to create child process"); -return; -} + "hypervisor initiated shutdown", (char *) NULL}; -ga_wait_child(pid, &status, &local_err); +ga_run_command(argv, NULL, "shutdown", &local_err); if (local_err) { error_propagate(errp, local_err); return; } -if (!WIFEXITED(status)) { -error_setg(errp, "child process has terminated abnormally"); -return; -} - -if (WEXITSTATUS(status)) { -error_setg(errp, "child process has failed to shutdown"); -return; -} - /* succeeded */ } -- 2.39.3
[PATCH v3 7/7] qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper
There's no need to check for the existence of the "chpasswd", "pw" executables, as the exec() call will do that for us. Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 96 ++-- 1 file changed, 13 insertions(+), 83 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index e0ea377f65..ffea69c3f0 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2151,14 +2151,8 @@ void qmp_guest_set_user_password(const char *username, Error **errp) { Error *local_err = NULL; -char *passwd_path = NULL; -pid_t pid; -int status; -int datafd[2] = { -1, -1 }; -char *rawpasswddata = NULL; +g_autofree char *rawpasswddata = NULL; size_t rawpasswdlen; -char *chpasswddata = NULL; -size_t chpasswdlen; rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp); if (!rawpasswddata) { @@ -2169,95 +2163,31 @@ void qmp_guest_set_user_password(const char *username, if (strchr(rawpasswddata, '\n')) { error_setg(errp, "forbidden characters in raw password"); -goto out; +return; } if (strchr(username, '\n') || strchr(username, ':')) { error_setg(errp, "forbidden characters in username"); -goto out; +return; } #ifdef __FreeBSD__ -chpasswddata = g_strdup(rawpasswddata); -passwd_path = g_find_program_in_path("pw"); +g_autofree char *chpasswdata = g_strdup(rawpasswddata); +const char *crypt_flag = crypted ? "-H" : "-h"; +const char *argv[] = {"pw", "usermod", "-n", username, + crypt_flag, "0", NULL}; #else -chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata); -passwd_path = g_find_program_in_path("chpasswd"); +g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username, +rawpasswddata); +const char *crypt_flag = crypted ? "-e" : NULL; +const char *argv[] = {"chpasswd", crypt_flag, NULL}; #endif -chpasswdlen = strlen(chpasswddata); - -if (!passwd_path) { -error_setg(errp, "cannot find 'passwd' program in PATH"); -goto out; -} - -if (!g_unix_open_pipe(datafd, FD_CLOEXEC, NULL)) { -error_setg(errp, "cannot create pipe FDs"); -goto out; -} - -pid = fork(); -if (pid == 0) { -close(datafd[1]); -/* child */ -setsid(); -dup2(datafd[0], 0); -reopen_fd_to_null(1); -reopen_fd_to_null(2); - -#ifdef __FreeBSD__ -const char *h_arg; -h_arg = (crypted) ? "-H" : "-h"; -execl(passwd_path, "pw", "usermod", "-n", username, h_arg, "0", NULL); -#else -if (crypted) { -execl(passwd_path, "chpasswd", "-e", NULL); -} else { -execl(passwd_path, "chpasswd", NULL); -} -#endif -_exit(EXIT_FAILURE); -} else if (pid < 0) { -error_setg_errno(errp, errno, "failed to create child process"); -goto out; -} -close(datafd[0]); -datafd[0] = -1; - -if (qemu_write_full(datafd[1], chpasswddata, chpasswdlen) != chpasswdlen) { -error_setg_errno(errp, errno, "cannot write new account password"); -goto out; -} -close(datafd[1]); -datafd[1] = -1; - -ga_wait_child(pid, &status, &local_err); +ga_run_command(argv, chpasswddata, "set user password", &local_err); if (local_err) { error_propagate(errp, local_err); -goto out; -} - -if (!WIFEXITED(status)) { -error_setg(errp, "child process has terminated abnormally"); -goto out; -} - -if (WEXITSTATUS(status)) { -error_setg(errp, "child process has failed to set user password"); -goto out; -} - -out: -g_free(chpasswddata); -g_free(rawpasswddata); -g_free(passwd_path); -if (datafd[0] != -1) { -close(datafd[0]); -} -if (datafd[1] != -1) { -close(datafd[1]); +return; } } #else /* __linux__ || __FreeBSD__ */ -- 2.39.3
[PATCH v3 5/7] qga/commands-posix: execute_fsfreeze_hook: use ga_run_command helper
There's no need to check for the existence of the hook executable, as the exec() call will do that for us. Signed-off-by: Andrey Drobyshev --- qga/commands-posix.c | 35 +++ 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 94b652d54e..610d225d30 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -736,8 +736,6 @@ static const char *fsfreeze_hook_arg_string[] = { static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) { -int status; -pid_t pid; const char *hook; const char *arg_str = fsfreeze_hook_arg_string[arg]; Error *local_err = NULL; @@ -746,42 +744,15 @@ static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) if (!hook) { return; } -if (access(hook, X_OK) != 0) { -error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook); -return; -} -slog("executing fsfreeze hook with arg '%s'", arg_str); -pid = fork(); -if (pid == 0) { -setsid(); -reopen_fd_to_null(0); -reopen_fd_to_null(1); -reopen_fd_to_null(2); - -execl(hook, hook, arg_str, NULL); -_exit(EXIT_FAILURE); -} else if (pid < 0) { -error_setg_errno(errp, errno, "failed to create child process"); -return; -} +const char *argv[] = {hook, arg_str, NULL}; -ga_wait_child(pid, &status, &local_err); +slog("executing fsfreeze hook with arg '%s'", arg_str); +ga_run_command(argv, NULL, "execute fsfreeze hook", &local_err); if (local_err) { error_propagate(errp, local_err); return; } - -if (!WIFEXITED(status)) { -error_setg(errp, "fsfreeze hook has terminated abnormally"); -return; -} - -status = WEXITSTATUS(status); -if (status) { -error_setg(errp, "fsfreeze hook has failed with status %d", status); -return; -} } /* -- 2.39.3
Re: [PATCH v2 3/6] qdev-monitor: add option to report GenericError from find_device_state
Sorry for the late answer. Vladimir Sementsov-Ogievskiy writes: > On 07.03.24 12:46, Markus Armbruster wrote: [...] >> I appreciate the attempt to curb the spread of DeviceNotFound errors. >> Two issues: >> >> * Copy-pasting find_device_state() with a false argument is an easy >> error to make. >> >> * Most uses of find_device_state() are via blk_by_qdev_id() and >> qmp_get_blk(). Any new uses of qemu_get_blk() will still produce >> DeviceNotFound. >> >> Hmm. > > Hmm. Right. Wait a bit, I can make the change stricter. > > Could you still explain (or give a link), why and when we decided to use only > GenericError? I think, having different "error-codes" is a good thing, why we > are trying to get rid of it? We actually got rid of most of them years ago :) But you deserve a more complete answer. QMP initially specified the following error response[1]: 2.4.2 error --- The error response is issued when the command execution could not be completed because of an error condition. The format is: { "error": { "class": json-string, "data": json-value }, "id": json-value } Where, - The "class" member contains the error class name (eg. "ServiceUnavailable") - The "data" member contains specific error data and is defined in a per-command basis, it will be an empty json-object if the error has no data - The "id" member contains the transaction identification associated with the command execution (if issued by the Client) Note the structure of @data depends on @class. We documented a command's possible error classes (well, we tried), but never bothered to document the @data it comes with. Documentation deficits aside, this is looks quite expressive. There are issues, though: 1. Formatting errors in human-readable form is bothersome, and creates a tight coupling between QMP server and client. Consider: {"class": "DeviceNotFound", "data": {"device": "ide1-cd0"}} To format this in human-readable form, you need to know the error. The server does. Fine print: it has a table mapping JSON templates to human-readable error message templates. The client needs to duplicate this somehow. If it receives an error it doesn't know, all it can do is barf (possibly dressed up) JSON at the human. To avoid that, clients need to track the server closely: tight coupling. 2. Errors have notational overhead, which leads to bad errors. To create a new error, you have to edit two source files (not counting clients). Strong incentive to reuse existing errors. Even when they don't quite fit. When a name provided by the user couldn't be resolved, reusing DeviceNotFound is easier than creating a new error that is more precise. 3. The human-readable error message is hidden from the programmer's view, which leads to bad error messages. At the point in the source where the error is created, we see something like QERR_DEVICE_NOT_FOUND, name. To see the human-readable message, we have to look up macro QERR_DEVICE_NOT_FOUND's error message template in the table, or actually test (*gasp*) the error. People generally do neither, and bad error messages proliferate. 4. Too little gain for the pain Clients rarely want to handle different errors differently. More often than not, all they do with @class and @data is log them. Only occasionally do they switch on @class, and basically never on @data. It me took a considerable fight to get the protocol amended to include a human-readable message[2]. This addressed issue 1. Over the next two years or so, issues 2. to 4. slowly sank in. We eventually tired of the complexity, ripped out @data, and dumbed down all error classes to GenericError, except for the few clients actually cared for[3]. We also mandated that new errors avoid the QERR_ macros. Eliminating the existing QERR_ macros has been slow. We're down to 13 in master, with patches deleting 7 on the list. This has served us reasonably well. Questions? [1] Commit f544d174dfc QMP: Introduce specification Dec 2009 [2] Commit 77e595e7c61q QMP: add human-readable description to error response Dec 2009 [3] Commit de253f14912 qmp: switch to the new error format on the wire Aug 2012
Re: [PATCH v7 3/8] tests/qtest/migration: Replace migrate_get_connect_uri inplace of migrate_get_socket_address
Het Gala writes: > Refactor migrate_get_socket_address to internally utilize 'socket-address' > parameter, reducing redundancy in the function definition. > > migrate_get_socket_address implicitly converts SocketAddress into str. > Move migrate_get_socket_address inside migrate_get_connect_uri which > should return the uri string instead. > > Signed-off-by: Het Gala > Suggested-by: Fabiano Rosas > Reviewed-by: Fabiano Rosas > --- > tests/qtest/migration-helpers.c | 29 +++-- > 1 file changed, 19 insertions(+), 10 deletions(-) > > diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c > index 3e8c19c4de..8806dc841e 100644 > --- a/tests/qtest/migration-helpers.c > +++ b/tests/qtest/migration-helpers.c > @@ -48,28 +48,37 @@ static char *SocketAddress_to_str(SocketAddress *addr) > } > } > > -static char * > -migrate_get_socket_address(QTestState *who, const char *parameter) > +static SocketAddress *migrate_get_socket_address(QTestState *who) > { > QDict *rsp; > -char *result; > SocketAddressList *addrs; > +SocketAddress *addr; > Visitor *iv = NULL; > QObject *object; > > rsp = migrate_query(who); > -object = qdict_get(rsp, parameter); > +object = qdict_get(rsp, "socket-address"); Just a heads up, none of what I'm about to say applies to current master. This can return NULL if there is no socket-address, such as with a file migration. Then the visitor code below just barfs. It would be nice if we touched this up eventually. I only noticed this because I was fiddling with the file migration API and this series helped me a lot to test my changes. So thanks for that, Het. Another point is: we really need to encourage people to write tests using the new channels API. I added the FileMigrationArgs with the 'offset' as a required parameter, not even knowing optional parameters were a thing. So it's obviously not enough to write support for the new API if no tests ever touch it. > > iv = qobject_input_visitor_new(object); > visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort); > +addr = addrs->value; > visit_free(iv); > > -/* we are only using a single address */ > -result = SocketAddress_to_str(addrs->value); > - > -qapi_free_SocketAddressList(addrs); > qobject_unref(rsp); > -return result; > +return addr; > +} > + > +static char * > +migrate_get_connect_uri(QTestState *who) > +{ > +SocketAddress *addrs; > +char *connect_uri; > + > +addrs = migrate_get_socket_address(who); > +connect_uri = SocketAddress_to_str(addrs); > + > +qapi_free_SocketAddress(addrs); > +return connect_uri; > } > > bool migrate_watch_for_events(QTestState *who, const char *name, > @@ -129,7 +138,7 @@ void migrate_qmp(QTestState *who, QTestState *to, const > char *uri, > > g_assert(!qdict_haskey(args, "uri")); > if (!uri) { > -connect_uri = migrate_get_socket_address(to, "socket-address"); > +connect_uri = migrate_get_connect_uri(to); > } > qdict_put_str(args, "uri", uri ? uri : connect_uri);
Re: [PATCH v4 0/3] Adjust the output of x-query-virtio-status
On Fri, Mar 15, 2024 at 3:51 PM Markus Armbruster wrote: > "Michael S. Tsirkin" writes: > > > On Wed, Mar 13, 2024 at 10:40:21AM +0100, Markus Armbruster wrote: > >> I could be awkward for the use case described in PATCH 1's commit > >> message: > >> > >> However, we sometimes want to compare features and status bits > without > >> caring for their exact meaning. Say we want to verify the > correctness > >> of the virtio negotiation between guest, QEMU, and OVS-DPDK. We > can use > >> QMP command x-query-virtio-status to retrieve vhost-user net device > >> features, and the "ovs-vsctl list interface" command to retrieve > >> interface features. Without commit f3034ad71fc, we could then > simply > >> compare the numbers. With this commit, we first have to map from > the > >> strings back to the numeric encoding. > > > > So, consider how guest kernel presents features then. Do you happen to > know? > > It's actually a binary string: > > > > static ssize_t features_show(struct device *_d, > > struct device_attribute *attr, char *buf) > > { > > struct virtio_device *dev = dev_to_virtio(_d); > > unsigned int i; > > ssize_t len = 0; > > > > /* We actually represent this as a bitstring, as it could be > > * arbitrary length in future. */ > > for (i = 0; i < sizeof(dev->features)*8; i++) > > len += sysfs_emit_at(buf, len, "%c", > >__virtio_test_bit(dev, i) ? '1' : '0'); > > len += sysfs_emit_at(buf, len, "\n"); > > return len; > > } > > static DEVICE_ATTR_RO(features); > > I'm willing to accept any reasonably compact representation of the bits > that is easy to use for the comparison use case. > > I strongly prefer integers as long as their width suffices. > > Since out integers are limited to 64 bits, and you want us to design for > more, we need something else. > > I'm fine with array of integers, but you don't like it. > > We generally avoid encoding stuff in strings, but using strings for > "overwide" integers isn't as bad as using them for structured data. I > guess I'd be okay with it. > > I'd use decimal simply to keep these "overwide" integers as close as > possible to regular ones. > > If using base 2 enables string compare for the comparison use case, > that's an argument for base 2. > > Hyman Huang, can you show us example output of "ovs-vsctl list > interface"? > > Here is the output of an active interface enable the dpdk feature: # ovs-vsctl list interface port-testvm2pn8 _uuid: admin_state: up name: port-testvm2pn8 .. status: {features="0x00017060a782", mode=client, num_of_vrings="4"..} Yong -- Best regards
[PATCH 02/12] uefi-test-tools/UefiTestToolsPkg: Add RISC-V support
Enable building the test application for RISC-V with appropriate dependencies updated. Signed-off-by: Sunil V L --- tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc index c8511cd732..0902fd3c73 100644 --- a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc +++ b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc @@ -19,7 +19,7 @@ PLATFORM_VERSION= 0.1 PLATFORM_NAME = UefiTestTools SKUID_IDENTIFIER= DEFAULT - SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64 + SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64 BUILD_TARGETS = DEBUG [BuildOptions.IA32] @@ -60,6 +60,10 @@ [LibraryClasses.IA32, LibraryClasses.X64] BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf + RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf + +[LibraryClasses.RISCV64] + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf [PcdsFixedAtBuild] gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F -- 2.40.1
[PATCH 00/12] Add support for RISC-V ACPI tests
Currently, bios-table-test doesn't support RISC-V. This series enables the framework changes required and basic testing. Things like NUMA related test cases will be added later. This needs refactoring/renaming of ARM64 bios table tests. Importantly, the test cases now look for the expected AML files under tests/data/acpi/virt/aarch64 path instead of directly under tests/data/acpi/virt. To keep test cases not to fail because of this movement, they are updated to look for both paths first. As part of this effort, it is found that uefi-test-tools is currently broken to build. So, updated its Makefile as well to use python based edk2 build script. The series depends on Gerd's below series. https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg03855.html The changes are also available at branch https://gitlab.com/vlsunil/qemu/-/tree/riscv_bios_table_test_v1 This branch which is on top of Gerd's series completed CI tests. https://gitlab.com/vlsunil/qemu/-/pipelines/1214784985 Sunil V L (12): roms/edk2-build.py: Add --module support uefi-test-tools/UefiTestToolsPkg: Add RISC-V support uefi-test-tools: Add support for python based build script tests/data/uefi-boot-images: Add RISC-V ISO image qtest: bios-tables-test: Rename aarch64 tests with aarch64 in them tests/qtest/bios-tables-test.c: Add support for arch in path tests/data/acpi/virt: Move ACPI tables under aarch64 meson.build: Add RISC-V to the edk2-target list pc-bios/meson.build: Add support for RISC-V in unpack_edk2_blobs tests/data/acpi/rebuild-expected-aml.sh: Add RISC-V tests/data/acpi/virt/riscv64: Add expected ACPI tables for RISC-V tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V meson.build | 2 +- pc-bios/meson.build | 2 + roms/edk2-build.py| 3 + tests/data/acpi/rebuild-expected-aml.sh | 5 +- tests/data/acpi/virt/{ => aarch64}/APIC | Bin .../acpi/virt/{ => aarch64}/APIC.acpihmatvirt | Bin .../acpi/virt/{ => aarch64}/APIC.topology | Bin tests/data/acpi/virt/{ => aarch64}/DBG2 | Bin tests/data/acpi/virt/{ => aarch64}/DSDT | Bin .../acpi/virt/{ => aarch64}/DSDT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/DSDT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/DSDT.pxb | Bin .../acpi/virt/{ => aarch64}/DSDT.topology | Bin tests/data/acpi/virt/{ => aarch64}/FACP | Bin tests/data/acpi/virt/{ => aarch64}/GTDT | Bin .../acpi/virt/{ => aarch64}/HMAT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/IORT | Bin tests/data/acpi/virt/{ => aarch64}/MCFG | Bin tests/data/acpi/virt/{ => aarch64}/NFIT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/PPTT | Bin .../acpi/virt/{ => aarch64}/PPTT.acpihmatvirt | Bin .../acpi/virt/{ => aarch64}/PPTT.topology | Bin tests/data/acpi/virt/{ => aarch64}/SLIT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/SPCR | Bin .../acpi/virt/{ => aarch64}/SRAT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/SRAT.memhp | Bin .../data/acpi/virt/{ => aarch64}/SRAT.numamem | Bin tests/data/acpi/virt/{ => aarch64}/SSDT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/VIOT | Bin tests/data/acpi/virt/riscv64/APIC | Bin 0 -> 116 bytes tests/data/acpi/virt/riscv64/BGRT | Bin 0 -> 56 bytes tests/data/acpi/virt/riscv64/DSDT | Bin 0 -> 3518 bytes tests/data/acpi/virt/riscv64/FACP | Bin 0 -> 276 bytes tests/data/acpi/virt/riscv64/MCFG | Bin 0 -> 60 bytes tests/data/acpi/virt/riscv64/RHCT | Bin 0 -> 314 bytes tests/data/acpi/virt/riscv64/RSDP | Bin 0 -> 36 bytes tests/data/acpi/virt/riscv64/SPCR | Bin 0 -> 80 bytes tests/data/acpi/virt/riscv64/XSDT | Bin 0 -> 84 bytes .../bios-tables-test.riscv64.iso.qcow2| Bin 0 -> 16896 bytes tests/qtest/bios-tables-test.c| 95 ++ tests/qtest/meson.build | 3 + tests/uefi-test-tools/Makefile| 18 ++-- .../UefiTestToolsPkg/UefiTestToolsPkg.dsc | 6 +- tests/uefi-test-tools/uefi-test-build.config | 57 +++ 44 files changed, 156 insertions(+), 35 deletions(-) rename tests/data/acpi/virt/{ => aarch64}/APIC (100%) rename tests/data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/APIC.topology (100%) rename tests/data/acpi/virt/{ => aarch64}/DBG2 (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.pxb (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.topology (100%) rename tests/data/acpi/virt/{ => aarch64}/FACP (100%) rename tests/data/acpi/virt/{ => aarch64}/GTDT (100%) rename tests/data/acpi/virt/{ => aarch6
[PATCH 01/12] roms/edk2-build.py: Add --module support
UefiTestToolsPkg which should use edk2-build.py needs --module parameter support. Add this optional parameter handling. Signed-off-by: Sunil V L --- roms/edk2-build.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roms/edk2-build.py b/roms/edk2-build.py index e564765aaa..3bfe200929 100755 --- a/roms/edk2-build.py +++ b/roms/edk2-build.py @@ -192,6 +192,9 @@ def build_one(cfg, build, jobs = None, silent = False, nologs = False): cmdline += [ '-n', jobs ] for arch in b['arch'].split(): cmdline += [ '-a', arch ] +if 'module' in b: +for module in b['module'].split(): +cmdline += [ '-m', module ] if 'opts' in b: for name in b['opts'].split(): section = 'opts.' + name -- 2.40.1
Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()
On Fri, Mar 15, 2024 at 01:20:49PM +0100, Cédric Le Goater wrote: > On 3/15/24 12:01, Peter Xu wrote: > > On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote: > > > > migrate_set_state is also unintuitive because it ignores invalid state > > > > transitions and we've been using that property to deal with special > > > > states such as POSTCOPY_PAUSED and FAILED: > > > > > > > > - After the migration goes into POSTCOPY_PAUSED, the resumed migration's > > > > migrate_init() will try to set the state NONE->SETUP, which is not > > > > valid. > > > > > > > > - After save_setup fails, the migration goes into FAILED, but > > > > wait_unplug > > > > will try to transition SETUP->ACTIVE, which is also not valid. > > > > > > > > > > I am not sure I understand what the plan is. Both solutions are > > > problematic > > > regarding the state transitions. > > > > > > Should we consider that waiting for failover devices to unplug is an > > > internal > > > step of the SETUP phase not transitioning to ACTIVE ? > > > > If to unblock this series, IIUC the simplest solution is to do what Fabiano > > suggested, that we move qemu_savevm_wait_unplug() to be before the check of > > setup() ret. > > The simplest is IMHO moving qemu_savevm_wait_unplug() before > qemu_savevm_state_setup() and leave patch 10 is unchanged. See > below the extra patch. It looks much cleaner than what we have > today. Yes it looks cleaner indeed, it's just that then we'll have one more possible state conversions like SETUP->UNPLUG->SETUP. I'd say it's fine, but let's also copy Laruent and Laine if it's going to be posted formally. Thanks, > > > In that case, the state change in qemu_savevm_wait_unplug() > > should be benign and we should see a super small window it became ACTIVE > > but then it should be FAILED (and IIUC the patch itself will need to use > > ACTIVE as "old_state", not SETUP anymore). > > OK. I will give it a try to compare. > > > For the long term, maybe we can remove the WAIT_UNPLUG state? > > I hope so, it's an internal SETUP state for me. > > > The only Libvirt support seems to be here: > > > > commit 8a226ddb3602586a2ba2359afc4448c02f566a0e > > Author: Laine Stump > > Date: Wed Jan 15 16:38:57 2020 -0500 > > > > qemu: add wait-unplug to qemu migration status enum > > > > Considering that qemu_savevm_wait_unplug() can be a noop if the device is > > already unplugged, I think it means no upper layer app should rely on this > > state to present. > > Thanks, > > C. > > > > > @@ -3383,11 +3383,10 @@ bool migration_rate_limit(void) > * unplugged > */ > -static void qemu_savevm_wait_unplug(MigrationState *s, int old_state, > -int new_state) > +static void qemu_savevm_wait_unplug(MigrationState *s, int state) > { > if (qemu_savevm_state_guest_unplug_pending()) { > -migrate_set_state(&s->state, old_state, > MIGRATION_STATUS_WAIT_UNPLUG); > +migrate_set_state(&s->state, state, MIGRATION_STATUS_WAIT_UNPLUG); > while (s->state == MIGRATION_STATUS_WAIT_UNPLUG && > qemu_savevm_state_guest_unplug_pending()) { > @@ -3410,9 +3409,7 @@ static void qemu_savevm_wait_unplug(Migr > } > } > -migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, > new_state); > -} else { > -migrate_set_state(&s->state, old_state, new_state); > +migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, state); > } > } > @@ -3469,17 +3466,19 @@ static void *migration_thread(void *opaq > qemu_savevm_send_colo_enable(s->to_dst_file); > } > +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP); > + > bql_lock(); > qemu_savevm_state_setup(s->to_dst_file); > bql_unlock(); > -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, > - MIGRATION_STATUS_ACTIVE); > - > s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; > trace_migration_thread_setup_complete(); > +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, > + MIGRATION_STATUS_ACTIVE); > + > while (migration_is_active()) { > if (urgent || !migration_rate_exceeded(s->to_dst_file)) { > MigIterateState iter_state = migration_iteration_run(s); > @@ -3580,18 +3579,20 @@ static void *bg_migration_thread(void *o > ram_write_tracking_prepare(); > #endif > +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP); > + > bql_lock(); > qemu_savevm_state_header(s->to_dst_file); > qemu_savevm_state_setup(s->to_dst_file); > bql_unlock(); > -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP, > - MIGRATION_STATUS_ACTIVE); > - > s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; > trace_migration_thread_setup_complete(); > +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, > + MIGRATION_ST
[PATCH-for-9.1 01/21] target/i386: Declare CPU QOM types using DEFINE_TYPES() macro
When multiple QOM types are registered in the same file, it is simpler to use the the DEFINE_TYPES() macro. In particular because type array declared with such macro are easier to review. In few commits we are going to add more types, so replace the type_register_static() to ease further reviews. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Zhao Liu Message-Id: <20231013140116.255-14-phi...@linaro.org> --- target/i386/cpu.c | 50 ++- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 9a210d8d92..ebf555f50f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4991,13 +4991,6 @@ static void max_x86_cpu_initfn(Object *obj) &error_abort); } -static const TypeInfo max_x86_cpu_type_info = { -.name = X86_CPU_TYPE_NAME("max"), -.parent = TYPE_X86_CPU, -.instance_init = max_x86_cpu_initfn, -.class_init = max_x86_cpu_class_init, -}; - static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) { assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD); @@ -8041,19 +8034,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) } } -static const TypeInfo x86_cpu_type_info = { -.name = TYPE_X86_CPU, -.parent = TYPE_CPU, -.instance_size = sizeof(X86CPU), -.instance_align = __alignof(X86CPU), -.instance_init = x86_cpu_initfn, -.instance_post_init = x86_cpu_post_initfn, - -.abstract = true, -.class_size = sizeof(X86CPUClass), -.class_init = x86_cpu_common_class_init, -}; - /* "base" CPU model, used by query-cpu-model-expansion */ static void x86_cpu_base_class_init(ObjectClass *oc, void *data) { @@ -8065,22 +8045,38 @@ static void x86_cpu_base_class_init(ObjectClass *oc, void *data) xcc->ordering = 8; } -static const TypeInfo x86_base_cpu_type_info = { -.name = X86_CPU_TYPE_NAME("base"), -.parent = TYPE_X86_CPU, -.class_init = x86_cpu_base_class_init, +static const TypeInfo x86_cpu_types[] = { +{ +.name = TYPE_X86_CPU, +.parent = TYPE_CPU, +.abstract = true, +.instance_size = sizeof(X86CPU), +.instance_align = __alignof(X86CPU), +.instance_init = x86_cpu_initfn, +.instance_post_init = x86_cpu_post_initfn, +.class_size = sizeof(X86CPUClass), +.class_init = x86_cpu_common_class_init, +}, { +.name = X86_CPU_TYPE_NAME("base"), +.parent = TYPE_X86_CPU, +.class_init = x86_cpu_base_class_init, +}, { +.name = X86_CPU_TYPE_NAME("max"), +.parent = TYPE_X86_CPU, +.instance_init = max_x86_cpu_initfn, +.class_init = max_x86_cpu_class_init, +} }; +DEFINE_TYPES(x86_cpu_types) + static void x86_cpu_register_types(void) { int i; -type_register_static(&x86_cpu_type_info); for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) { x86_register_cpudef_types(&builtin_x86_defs[i]); } -type_register_static(&max_x86_cpu_type_info); -type_register_static(&x86_base_cpu_type_info); } type_init(x86_cpu_register_types) -- 2.41.0
[PATCH 04/12] tests/data/uefi-boot-images: Add RISC-V ISO image
To test ACPI tables, edk2 needs to be booted with a disk image having EFI partition. This image is created using UefiTestToolsPkg. Signed-off-by: Sunil V L --- .../bios-tables-test.riscv64.iso.qcow2 | Bin 0 -> 16896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2 diff --git a/tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2 b/tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2 new file mode 100644 index ..c720bf99a45fab6d1e21963cca563ee0ea059b82 GIT binary patch literal 16896 zcmeIZbyQp5w=Wvpf_t$*DNx*s76?*Gkpjhw1#fW*1ef3~T4-^K6sNdLaVJ>O;85J1 zQtYN*dfvO^_r|&BjPd@sc6P{~`K&p2_F8kzHD!gZF8|^R005vN-~auA^AEuE|F<^$ z`wy6ZG3pwPn*YYNLL{ z@~dP#ETCmdJ*7_kgqm;AKA-YZ)H7i(_@NMQyg)%>KxsGsR-2gBcMs8>CNZu}?giTr zW$PK&8%mMm2N;bN$uC%lqEk?%*o3+>e_ic4JOyZ|QDL}X0t1oRteN9K<8(Pw$37xF z1|I2P6F9n_yPUW{fk&qoW*`a$lHzw{Kz0D&>R{It0_pAL#g%74US}QyK_2E*7!OJR zAOI>3rhJGxFB1wt!!!m0K*PZ#AnIyU>wpil!a2G-TU)W^B7llPn!FEq6{Iy4q~)j} z>{K9cNmkXnrC&tPStW#fh-_pr=`de}dA<-N&D^d}y}pq>O>MJ&j$(%bF!LVvC;g^~ zXE=dk`Gi+tSz8DwS_3uBWFbZj%AzyV%_=l~oF%n-a=AdsJV^C9}F;wuhCstjLCnUP*F48|zU^QfHp zBMJ#O{w?+cY7szMfzGGoxOAWs2Ye9nKr0PthyUvz;D5RZZ20$j`j@}-Kj!00+{+OG zApZywo!w&+yn9UQdymNi?=d<2o>EHQw^NnfV`{`brO~{nv}N~vdis0JU~x}DfBiTU z_#QueeNUO^!GJ#p3peB+${KJ_*~Y>DV0OiO%z=B4IqmK-*N1z`!*k!xn|6=+obNIJ z-|rFdzsG_R_xvXb_gE=9YrM4Ci?)1f@8Iihn0CWpe5WAz@Sgkk! z`gPpBm$H~L9JTE~PC!(x9k^sr57SWaemy2t{-hFrElVz*fv{aT9xicJN6~n1W2%AH zFz7ge3Yn;tW&tB8wW|-F68=c@4o$;g>UMmqbv5_1c)wkvMLraUAyg?f9Xt3O+n84 zxsFBX$^U1H-jvM19JShUm36pu-|w@BOyrj!y)XL!K-(D4iF`Jx?;EZRkq(^%-V;CE zcCCm2TZd0Zyx9J>IzrROgqwwaV4a)5#CQHST8)M~U(xf(CglJ&*7=;~S6QbpX;V)T zw2syD4S@~j;erLP2kkcLLaZLfMRkwS0(o~v2kvzw!X~{MrJ5esl&4GEOJV7d&hn8{ zeXmzCDRM1cZ?;5Rdn$LUpGE2RNlNXtlH|}3`e>#khWUA_OBnq{A4nn&@%q-@rrO#r zxunkjqcl+%<=?T&QPlY8on}hQAT0X`EyB5^YASJg%Nk_nMh*dNzwzGuKByng+~1e4 z(>xQDn?MQP0zxSLe$(8ldOyAz4en>*y!(XjKOM3bU4b#c5Vo*p2u|1JNb!apiEl7F z6oe$t^09h6zbrWyIyW4@vXsP?ApYD`Ds;wbvlic;r&SvoW5h{zAnIo~U0XGI;nY+E^rWKx**=fVr<=(@I zO5qv}aXk5CR8{LkI<~~9xK4fKH@V}TA6(DfZG-1LPdWF)-~zu^aB6Q!#@P^;GI@u; z4tpm`m-41mquxn8e1f?;V%ABiZlX3YrJ~3ltEae`Zce;$8)|WdW*6O}gvLkKGd3_9 zK`!RvNGvcn)8@&>_L<;My9Y^gH$Wy9eAsc z*l+dtwVGq!z*W<*a1;Eh1G*bV8qoDlueCBHZfEf7Q`bwwGQ{VxZ8~GZq<3WpzWh?k zT^6RC1loy@L<6#`Y~N7#q0j_Ql`njd2(+Sh@_)AET3l<&=RUtU`}k1AHlY=2AWFiR zovd$E!^p++iWWXf$oR@TjbdO6BO>4t4(8kFvAP_iAL-p&EUHtW1AuDMT@z$@l<*S619(Zb8 z11;tS2SD(-G3d&nqSq}%+pP^FazC!cZ==@6M{`LtD{*?fm96(&ehVYezoIYJk4S)) zQ@i?t9&_f*Va3bo2_~kAP|b(*l9fU*#m*RR{`>>b<@(Mp5FAI6`bxJvxvJG&>q@ii zg+L}t4!No&{*r%U&TG_aRqAZhC;`bhs?$*wv3TL6Y8Z{_D;vpiNzt+web{los3i}D zk=~Bo$0P=jR8wMzSnp-9$l=K-yPkD#7M)*XV5<^J@Ux1wx3U7f9})pl;@=IKPZese z;0ivjh}nz&5sitdmdK%Rd-?DXy!yTqFG;u`lM~+0!UT^)NS`K1Wr!rt4c$`qVj_-) zONtSn)_5x44j6~gkfT#mgH6(L1vL^s9+gzQ&xoy%{z?)E9PzpMgkLj<)^HeA(e+t; zZ2nJZY*Z3rKz0D&^~+lf4XxuO1hZaiPlHf6rE)Ii(#RkZCY?CQ<;uT0auZ$W*bk0WdiVP6=D`al1d^tu2Ltds|9(CyFZmdEpQ3olTc!W)ow(-WJ(Ev zwi!l6z4{Hr?d$K(pG0wVla<{5y%qX0=B$2JR@RyaLH#_5k@PH40g9?rA|TJG6q(a1 zC>p>j>_f`2cPTO`1%Z0{y)kBl@U`3s2ou*@iRwJrR=)?3|! zzb=BOYGq}bI)_Y74y>ePd|u(&FjaV31ajTwHU^%S`I)=w*t-w4_5w6I{@8s(;o3pc zpx*7E`y7z@g6yD=0_y{AC4=AWCd&|}c{$yc>xfpO7C7^*=huINDC<+poR;LcId^*N zS5G>b&k{)bw2M18?fr&;r?U|~W7K~V3y~(Hi3KlOrjzTf)YYVet_kqIdSw#a)BlA5 zd9S5Pb#T629fsBg)e2=;e!FuJ&VDozOO@zLOD#x9;*vFvdWs|d>NZ`Mn)7}K-2D*S zME*)5h`MK&rBVny2ze4b-Rds`CUae3wFSI=ecVBi37ia{_9X$`wzVfKjeoXPs^+Kc!n;i1!26 zA`<~LJYj@y42SeBtp3-&M_Bm81;_vhutDByM$ixe>1+AxgU^etTRa+&nY8gSK9nFV zvE%m76x250soo4>6YDub{@fXE$$6Js#E-OMJ1x0**F?^e?p6@IM)@uO4w{iu2Cm7Z zCQklkk*1Ea8`kz)sb-It$EnACww!*66Vcb0$!A_jrEzp}L9R;61OyxOxd9b-Y$@I- zAF8h_ZG7UF;fgfVejt~<>InIEyHe52-fM@#)Fjt12qKU-5uJ* z6j-Jy(hHe)^D%cCW{NQ=o0_+-zf;S9l7a>>yR3cackc`@5CZh7RuG8$f+J+V@OH!+K$dW|Xf^n8IhY(28FQjzKhKv?y ze6l{B5)tTJ?F2fh8%aR(uX%Y=Vwmm0|L!t?qb z{rTWLU#p-QVdwifL^>0+dA|Cy0+8l;$K4(H3_+Aofuo9Cz_7a0eC+XS7VMi0hULa{ z`k;fkY?jIg;Ik@R8MsD1R(;QX#l$hH2=v02G=?LJP8APMYjgQqLv!*QYvGgx#F);KHR7v7iorV`*AdN zN%-+a5@19pszp)hFGb=uz$S{&)ezk}-gX9g#<09oveKK$Z%;T2t!WrK0Evv+JX-j~Aj zsW6n@A!HH4nuJ_l=~}bR+CerXU!<=A??#cf7^}%-SOp@SfA-ckPLDhY#Qn-5H2+;# z$6nT{U`BWapW&(_<=C@`07VBXbnwcb1@WX|wwfiUET9Xq!1f)`S9U#S066}Mw6trZnJ;%&bBRIBNS|kMb>&4SDDpb>mFe|)6A@ul913}EBRz{^MT-)L>_a<<8ykGHdKa24#OxJD~jA&`h6*jiA za=)ZuHl1q7_b=#tQeKc*p|*t=7*sJBE7eb-e+yW<6{5#V;yZEr+Q|KqM)#vFAPIj3 zWl(Bp=#bdDnPl4KxpWPyA|aJXt^hCZQwNdO&fYRM*yFB`#D**|V#W@^%mUa)lx&$T z95tgfn8`bFuUT5Fj3mfqzf28}B7?uZklwK>0x}?Fk@65+YkVnigEZw~ng`xG$kG-F zHN1eItXKnq?Y7qSNYgodUxbSIrg{R}rm}_I{t~_{6p{TZE->;Onb7zJBdBx}k@d2) zAxBFgooMPIqHrnX?N0f4-#09D#+sU3*>Nu3V1(E_?P@7Bl)7(F*Uk?VW$R_mILna3 zfDbHleE?#>Hw4VsK&8y|4{t=K}1(|XNK{H@e>m_(=V*BCAA_EYiUOnyB{Ee zX94I~(sEda1_rwznW8A}fTA~i1dkrSikNBK6gTVITA24*JlOCmRrIvE;R$r5T@&Rz zd)I(%RrLZF=gVfYd?qv#%Jad%fH9a#wLVb>KPcw0>Ug;ewqch_QFKw9jZzZ6hoqZY zT%+T5%+e}#+pEt@n{;gjGpzCM7w+kom~=ga>>n&hop5q;URpHLosQK{5$)ugI?f+e zO3uCJl^wu*S+4n^=!33x!(n$Xv-l1#A+GiBswHoJ*VmDpmY@Omm!OUV{@>}{KR-ms zOFtLucFElC4!3wx`~c;gL(n;EnYoNfYigjqHmS?GbulY@GX)Omq~=zGQwd zlPN+Jydg0^MT
[PATCH-for-9.1 02/21] target/mips: Declare CPU QOM types using DEFINE_TYPES() macro
When multiple QOM types are registered in the same file, it is simpler to use the the DEFINE_TYPES() macro. In particular because type array declared with such macro are easier to review. In few commits we are going to add more types, so replace the type_register_static() to ease further reviews. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20231013140116.255-15-phi...@linaro.org> --- target/mips/cpu.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 8d8f690a53..c096d97fe3 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -594,17 +594,21 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) #endif /* CONFIG_TCG */ } -static const TypeInfo mips_cpu_type_info = { -.name = TYPE_MIPS_CPU, -.parent = TYPE_CPU, -.instance_size = sizeof(MIPSCPU), -.instance_align = __alignof(MIPSCPU), -.instance_init = mips_cpu_initfn, -.abstract = true, -.class_size = sizeof(MIPSCPUClass), -.class_init = mips_cpu_class_init, +static const TypeInfo mips_cpu_types[] = { +{ +.name = TYPE_MIPS_CPU, +.parent = TYPE_CPU, +.instance_size = sizeof(MIPSCPU), +.instance_align = __alignof(MIPSCPU), +.instance_init = mips_cpu_initfn, +.abstract = true, +.class_size = sizeof(MIPSCPUClass), +.class_init = mips_cpu_class_init, +} }; +DEFINE_TYPES(mips_cpu_types) + static void mips_cpu_cpudef_class_init(ObjectClass *oc, void *data) { MIPSCPUClass *mcc = MIPS_CPU_CLASS(oc); @@ -629,7 +633,6 @@ static void mips_cpu_register_types(void) { int i; -type_register_static(&mips_cpu_type_info); for (i = 0; i < mips_defs_number; i++) { mips_register_cpudef_type(&mips_defs[i]); } -- 2.41.0
[PATCH 12/12] tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V
Add basic ACPI table testing for RISC-V. Signed-off-by: Sunil V L --- tests/qtest/bios-tables-test.c | 28 1 file changed, 28 insertions(+) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index c492438ced..033acc8958 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1923,6 +1923,30 @@ static void test_acpi_microvm_acpi_erst(void) } #endif /* CONFIG_POSIX */ +static void test_acpi_riscv64_virt_tcg(void) +{ +test_data data = { +.machine = "virt", +.arch = "riscv64", +.tcg_only = true, +.uefi_fl1 = "pc-bios/edk2-riscv-code.fd", +.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd", +.ram_start = 0x8000ULL, +.scan_len = 128ULL * 1024 * 1024, +}; + +/* + * RHCT will have ISA string encoded. To reduce the effort + * of updating expected AML file for any new default ISA extension, + * use the profile rva22s64. Once profile is ratified, there may + * not be new extension possible. + */ +test_acpi_one("-cpu rva22s64 -device virtio-blk-device,drive=hd0 " + "-drive file=tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2,id=hd0", + &data); +free_test_data(&data); +} + static void test_acpi_aarch64_virt_tcg(void) { test_data data = { @@ -2342,6 +2366,10 @@ int main(int argc, char *argv[]) qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot); } } +} else if (strcmp(arch, "riscv64") == 0) { +if (has_tcg && qtest_has_device("virtio-blk-pci")) { +qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg); +} } ret = g_test_run(); boot_sector_cleanup(disk); -- 2.40.1
[RFC PATCH-for-9.1 15/21] target/arm: Use QMP generic_query_cpu_definitions()
Signed-off-by: Philippe Mathieu-Daudé --- target/arm/arm-qmp-cmds.c | 25 ++--- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 3cc8cc738b..c5091e64ec 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -28,6 +28,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-commands-machine-target.h" #include "qapi/qapi-commands-misc-target.h" +#include "qapi/commands-target-compat.h" #include "qapi/qmp/qdict.h" #include "qom/qom-qobject.h" @@ -220,29 +221,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return expansion_info; } -static void arm_cpu_add_definition(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CpuDefinitionInfoList **cpu_list = user_data; -CpuDefinitionInfo *info; -const char *typename; - -typename = object_class_get_name(oc); -info = g_malloc0(sizeof(*info)); -info->name = cpu_model_from_type(typename); -info->q_typename = g_strdup(typename); - -QAPI_LIST_PREPEND(*cpu_list, info); -} - CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list; - -list = object_class_get_list(TYPE_ARM_CPU, false); -g_slist_foreach(list, arm_cpu_add_definition, &cpu_list); -g_slist_free(list); - -return cpu_list; +return generic_query_cpu_definitions(errp); } -- 2.41.0
[PATCH-for-9.1 04/21] target/sparc: Declare CPU QOM types using DEFINE_TYPES() macro
When multiple QOM types are registered in the same file, it is simpler to use the the DEFINE_TYPES() macro. In particular because type array declared with such macro are easier to review. In few commits we are going to add more types, so replace the type_register_static() to ease further reviews. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Mark Cave-Ayland Message-Id: <20231013140116.255-17-phi...@linaro.org> --- target/sparc/cpu.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index dc9ead21fc..42b13ab63f 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -949,17 +949,21 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->tcg_ops = &sparc_tcg_ops; } -static const TypeInfo sparc_cpu_type_info = { -.name = TYPE_SPARC_CPU, -.parent = TYPE_CPU, -.instance_size = sizeof(SPARCCPU), -.instance_align = __alignof(SPARCCPU), -.instance_init = sparc_cpu_initfn, -.abstract = true, -.class_size = sizeof(SPARCCPUClass), -.class_init = sparc_cpu_class_init, +static const TypeInfo sparc_cpu_types[] = { +{ +.name = TYPE_SPARC_CPU, +.parent = TYPE_CPU, +.instance_size = sizeof(SPARCCPU), +.instance_align = __alignof(SPARCCPU), +.instance_init = sparc_cpu_initfn, +.abstract = true, +.class_size = sizeof(SPARCCPUClass), +.class_init = sparc_cpu_class_init, +} }; +DEFINE_TYPES(sparc_cpu_types) + static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data) { SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); @@ -984,7 +988,6 @@ static void sparc_cpu_register_types(void) { int i; -type_register_static(&sparc_cpu_type_info); for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { sparc_register_cpudef_type(&sparc_defs[i]); } -- 2.41.0
[PATCH 03/12] uefi-test-tools: Add support for python based build script
edk2-funcs.sh which is used in this Makefile, was removed in the commit c28a2891f3 ("edk2: update build script"). It is replaced with a python based script. So, update the Makefile and add the configuration file as required to support the python based build script. Signed-off-by: Sunil V L --- tests/uefi-test-tools/Makefile | 18 +++ tests/uefi-test-tools/uefi-test-build.config | 57 2 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 tests/uefi-test-tools/uefi-test-build.config diff --git a/tests/uefi-test-tools/Makefile b/tests/uefi-test-tools/Makefile index 0c003f2877..f94738b645 100644 --- a/tests/uefi-test-tools/Makefile +++ b/tests/uefi-test-tools/Makefile @@ -12,7 +12,7 @@ edk2_dir := ../../roms/edk2 images_dir:= ../data/uefi-boot-images -emulation_targets := arm aarch64 i386 x86_64 +emulation_targets := arm aarch64 i386 x86_64 riscv64 uefi_binaries := bios-tables-test intermediate_suffixes := .efi .fat .iso.raw @@ -56,7 +56,8 @@ Build/%.iso.raw: Build/%.fat # stripped from, the argument. map_arm_to_uefi = $(subst arm,ARM,$(1)) map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1))) -map_i386_to_uefi= $(subst i386,IA32,$(call map_aarch64_to_uefi,$(1))) +map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_aarch64_to_uefi,$(1))) +map_i386_to_uefi= $(subst i386,IA32,$(call map_riscv64_to_uefi,$(1))) map_x86_64_to_uefi = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1))) map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1))) @@ -70,7 +71,7 @@ Build/%.fat: Build/%.efi uefi_bin_b=$$(stat --format=%s -- $<) && \ uefi_fat_kb=$$(( (uefi_bin_b * 11 / 10 + 1023) / 1024 )) && \ uefi_fat_kb=$$(( uefi_fat_kb >= 64 ? uefi_fat_kb : 64 )) && \ - mkdosfs -C $@ -n $(basename $(@F)) -- $$uefi_fat_kb + mkdosfs -C $@ -n "bios-test" -- $$uefi_fat_kb MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI/BOOT MTOOLS_SKIP_CHECK=1 mcopy -i $@ -- $< \ @@ -95,15 +96,8 @@ Build/%.fat: Build/%.efi # we must mark the recipe manually as recursive, by using the "+" indicator. # This way, when the inner "make" starts a parallel build of the target edk2 # module, it can communicate with the outer "make"'s job server. -Build/bios-tables-test.%.efi: build-edk2-tools - +./build.sh $(edk2_dir) BiosTablesTest $* $@ - -build-edk2-tools: - cd $(edk2_dir)/BaseTools && git submodule update --init --force - $(MAKE) -C $(edk2_dir)/BaseTools \ - PYTHON_COMMAND=$${EDK2_PYTHON_COMMAND:-python3} \ - EXTRA_OPTFLAGS='$(EDK2_BASETOOLS_OPTFLAGS)' \ - EXTRA_LDFLAGS='$(EDK2_BASETOOLS_LDFLAGS)' +Build/bios-tables-test.%.efi: + $(PYTHON) ../../roms/edk2-build.py --config uefi-test-build.config clean: rm -rf Build Conf log diff --git a/tests/uefi-test-tools/uefi-test-build.config b/tests/uefi-test-tools/uefi-test-build.config new file mode 100644 index 00..4fb89f7db9 --- /dev/null +++ b/tests/uefi-test-tools/uefi-test-build.config @@ -0,0 +1,57 @@ +[global] +core = ../../roms/edk2 + + +# arm + +[build.arm] +conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc +plat = UefiTestTools +module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf +dest = ./Build +arch = ARM +cpy1 = ARM/BiosTablesTest.efi bios-tables-test.arm.efi + + +# aarch64 + +[build.aarch64] +conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc +plat = UefiTestTools +module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf +dest = ./Build +arch = AARCH64 +cpy1 = AARCH64/BiosTablesTest.efi bios-tables-test.aarch64.efi + + +# riscv64 + +[build.riscv] +conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc +plat = UefiTestTools +module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf +dest = ./Build +arch = RISCV64 +cpy1 = RISCV64/BiosTablesTest.efi bios-tables-test.riscv64.efi + + +# ia32 + +[build.ia32] +conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc +plat = UefiTestTools +module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf +dest = ./Build +arch = IA32 +cpy1 = IA32/BiosTablesTest.efi bios-tables-test.i386.efi + + +# x64 + +[build.x64] +conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc +plat = UefiTestTools +module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf +dest = ./Build +arch = X64 +cpy1 = X64/BiosTablesTest.efi bios-tables-test.x86_64.efi -- 2.40.1
[PATCH 08/12] meson.build: Add RISC-V to the edk2-target list
so that ACPI table test can be supported. Signed-off-by: Sunil V L --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index b8ded80cbe..bf50688593 100644 --- a/meson.build +++ b/meson.build @@ -93,7 +93,7 @@ else iasl = find_program(get_option('iasl'), required: true) endif -edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ] +edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu', 'riscv64-softmmu' ] unpack_edk2_blobs = false foreach target : edk2_targets if target in target_dirs -- 2.40.1
[PATCH-for-9.1 05/21] cpus: Open code OBJECT_DECLARE_TYPE() in OBJECT_DECLARE_CPU_TYPE()
Since the OBJECT_DECLARE_CPU_TYPE() macro uses the abstract ArchCPU type, when declaring multiple CPUs of the same ArchCPU type we get an error related to the indirect G_DEFINE_AUTOPTR_CLEANUP_FUNC() use within OBJECT_DECLARE_TYPE(): target/mips/cpu-qom.h:31:1: error: redefinition of 'glib_autoptr_clear_ArchCPU' OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU) ^ include/hw/core/cpu.h:82:5: note: expanded from macro 'OBJECT_DECLARE_CPU_TYPE' OBJECT_DECLARE_TYPE(ArchCPU, CpuClassType, CPU_MODULE_OBJ_NAME); ^ include/qom/object.h:237:5: note: expanded from macro 'OBJECT_DECLARE_TYPE' G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \ ^ /usr/include/glib-2.0/glib/gmacros.h:1371:3: note: expanded from macro 'G_DEFINE_AUTOPTR_CLEANUP_FUNC' _GLIB_DEFINE_AUTOPTR_CLEANUP_FUNCS(TypeName, TypeName, func) ^ /usr/include/glib-2.0/glib/gmacros.h:1354:36: note: expanded from macro '_GLIB_DEFINE_AUTOPTR_CLEANUP_FUNCS' static G_GNUC_UNUSED inline void _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) (TypeName *_ptr) \ ^ /usr/include/glib-2.0/glib/gmacros.h:1338:49: note: expanded from macro '_GLIB_AUTOPTR_CLEAR_FUNC_NAME' #define _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) glib_autoptr_clear_##TypeName ^ :54:1: note: expanded from here glib_autoptr_clear_ArchCPU ^ target/mips/cpu-qom.h:30:1: note: previous definition is here OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU) ^ Avoid that problem by expanding the OBJECT_DECLARE_TYPE() macro within OBJECT_DECLARE_CPU_TYPE(). Signed-off-by: Philippe Mathieu-Daudé Acked-by: Richard Henderson --- TODO: check rth comment: What about adding an OBJECT_DECLARE_CPU_SUBTYPE that omits half the stuff instead? We don't need another object typedef at all, for instance. --- include/hw/core/cpu.h | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index ec14f74ce5..4c2e5095bf 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -78,7 +78,12 @@ DECLARE_CLASS_CHECKERS(CPUClass, CPU, */ #define OBJECT_DECLARE_CPU_TYPE(CpuInstanceType, CpuClassType, CPU_MODULE_OBJ_NAME) \ typedef struct ArchCPU CpuInstanceType; \ -OBJECT_DECLARE_TYPE(ArchCPU, CpuClassType, CPU_MODULE_OBJ_NAME); +typedef struct CpuClassType CpuClassType; \ +\ +G_DEFINE_AUTOPTR_CLEANUP_FUNC(CpuInstanceType, object_unref) \ +\ +DECLARE_OBJ_CHECKERS(CpuInstanceType, CpuClassType, \ + CPU_MODULE_OBJ_NAME, TYPE_##CPU_MODULE_OBJ_NAME) typedef enum MMUAccessType { MMU_DATA_LOAD = 0, -- 2.41.0
[PATCH 06/12] tests/qtest/bios-tables-test.c: Add support for arch in path
Since virt machine is common for multiple architectures, add "arch" in the path to search expected AML files. Since the AML files are still under old path, support both by searching with and without arch in the path. Signed-off-by: Sunil V L --- tests/qtest/bios-tables-test.c | 32 +--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index ea3ba1992b..c492438ced 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -78,6 +78,7 @@ typedef struct { bool tcg_only; const char *machine; +const char *arch; const char *machine_param; const char *variant; const char *uefi_fl1; @@ -262,8 +263,20 @@ static void dump_aml_files(test_data *data, bool rebuild) g_assert(exp_sdt->aml); if (rebuild) { -aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, +aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, + data->machine, data->arch, sdt->aml, ext); + +/* + * To keep test cases not failing when the DATA files are moved to + * ARCH under virt folder, add this check which can be removed once + * the DATA files are moved. + */ +if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) { +aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, + sdt->aml, ext); +} + if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) && sdt->aml_len == exp_sdt->aml_len && !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) { @@ -398,8 +411,13 @@ static GArray *load_expected_aml(test_data *data) memset(&exp_sdt, 0, sizeof(exp_sdt)); try_again: -aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, - sdt->aml, ext); +aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, data->machine, + data->arch, sdt->aml, ext); +if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) { +aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, + sdt->aml, ext); +} +exp_sdt.aml_file = aml_file; if (verbosity_level >= 2) { fprintf(stderr, "Looking for expected file '%s'\n", aml_file); } @@ -1561,6 +1579,7 @@ static void test_acpi_aarch64_virt_tcg_memhp(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -1654,6 +1673,7 @@ static void test_acpi_aarch64_virt_tcg_numamem(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -1676,6 +1696,7 @@ static void test_acpi_aarch64_virt_tcg_pxb(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -1749,6 +1770,7 @@ static void test_acpi_aarch64_virt_tcg_acpi_hmat(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -1905,6 +1927,7 @@ static void test_acpi_aarch64_virt_tcg(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -1924,6 +1947,7 @@ static void test_acpi_aarch64_virt_tcg_topology(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .variant = ".topology", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", @@ -2007,6 +2031,7 @@ static void test_acpi_aarch64_virt_viot(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", @@ -2139,6 +2164,7 @@ static void test_acpi_aarch64_virt_oem_fields(void) { test_data data = { .machine = "virt", +.arch = "aarch64", .tcg_only = true, .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", -- 2.40.1
[RFC PATCH-for-9.1 21/21] qapi: Make @query-cpu-definitions target-agnostic
All targets use the generic_query_cpu_definitions() method, which is not target-specific. Make the command target agnostic by moving it to machine.json. Rename generic_query_cpu_definitions as qmp_query_cpu_definitions. This is an introspection change for the target that were not implementing qmp_query_cpu_definitions(): now query-cpu-definitions returns an their CPUs list. Example with SH4 before: { "execute": "query-cpu-definitions" } { "error": {"class": "CommandNotFound", "desc": "The command query-cpu-definitions has not been found"} } and after: { "execute": "query-cpu-definitions" } { "return": [ {"name": "sh7751r", "typename": "sh7751r-superh-cpu", "static": false, "deprecated": false}, {"name": "sh7750r", "typename": "sh7750r-superh-cpu", "static": false, "deprecated": false}, {"name": "sh7785", "typename": "sh7785-superh-cpu", "static": false, "deprecated": false} ] } However this allows heterogeneous emulation to return a correct list. Signed-off-by: Philippe Mathieu-Daudé --- Well, not all target got converted, I left the s390x one for later :) --- MAINTAINERS | 1 - qapi/machine-target.json | 18 -- qapi/machine.json | 11 +++ include/qapi/commands-target-compat.h | 14 -- system/cpu-qmp-cmds.c | 4 ++-- target/arm/arm-qmp-cmds.c | 6 -- target/i386/cpu.c | 6 -- target/loongarch/loongarch-qmp-cmds.c | 6 -- target/mips/sysemu/mips-qmp-cmds.c| 9 - target/ppc/ppc-qmp-cmds.c | 7 --- target/riscv/riscv-qmp-cmds.c | 6 -- 11 files changed, 13 insertions(+), 75 deletions(-) delete mode 100644 include/qapi/commands-target-compat.h diff --git a/MAINTAINERS b/MAINTAINERS index 39d7c14d98..71f446311b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1895,7 +1895,6 @@ F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h -F: include/qapi/commands-target-compat.h F: include/sysemu/numa.h F: tests/unit/test-smp-parse.c T: git https://gitlab.com/ehabkost/qemu.git machine-next diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 7480921d33..2065972d8a 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -212,24 +212,6 @@ 'TARGET_LOONGARCH64', 'TARGET_RISCV' ] } } -## -# @query-cpu-definitions: -# -# Return a list of supported virtual CPU definitions -# -# Returns: a list of CpuDefinitionInfo -# -# Since: 1.2 -## -{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'], - 'if': { 'any': [ 'TARGET_PPC', - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', - 'TARGET_MIPS', - 'TARGET_LOONGARCH64', - 'TARGET_RISCV' ] } } - ## # @CpuS390Polarization: # diff --git a/qapi/machine.json b/qapi/machine.json index 9c44b8fa82..987c64f8e7 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -73,6 +73,17 @@ 'deprecated' : 'bool' } } +## +# @query-cpu-definitions: +# +# Return a list of supported virtual CPU definitions +# +# Returns: a list of CpuDefinitionInfo +# +# Since: 1.2 +## +{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] } + ## # @CpuModelInfo: # diff --git a/include/qapi/commands-target-compat.h b/include/qapi/commands-target-compat.h deleted file mode 100644 index 86d45d8fcc..00 --- a/include/qapi/commands-target-compat.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * QAPI helpers for target specific QMP commands - * - * SPDX-FileCopyrightText: 2024 Linaro Ltd. - * SPDX-License-Identifier: GPL-2.0-or-later - */ -#ifndef QAPI_COMPAT_TARGET_H -#define QAPI_COMPAT_TARGET_H - -#include "qapi/qapi-types-machine.h" - -CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp); - -#endif diff --git a/system/cpu-qmp-cmds.c b/system/cpu-qmp-cmds.c index daeb131159..049e8b9d35 100644 --- a/system/cpu-qmp-cmds.c +++ b/system/cpu-qmp-cmds.c @@ -7,7 +7,7 @@ #include "qemu/osdep.h" #include "qom/object.h" -#include "qapi/commands-target-compat.h" +#include "qapi/qapi-commands-machine.h" #include "sysemu/arch_init.h" #include "hw/core/cpu.h" #include "hw/core/sysemu-cpu-ops.h" @@ -53,7 +53,7 @@ static void arch_add_cpu_definitions(CpuDefinitionInfoList **cpu_list, } } -CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp) +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index c5091e64ec..ac8d890bc0 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -28,7 +28,6 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-commands-machine-target.h" #include "qapi/qapi-comm
[PATCH 11/12] tests/data/acpi/virt/riscv64: Add expected ACPI tables for RISC-V
Add expected ACPI tables for RISC-V so that bios-table-test can be enabled for RISC-V. Signed-off-by: Sunil V L --- tests/data/acpi/virt/riscv64/APIC | Bin 0 -> 116 bytes tests/data/acpi/virt/riscv64/BGRT | Bin 0 -> 56 bytes tests/data/acpi/virt/riscv64/DSDT | Bin 0 -> 3518 bytes tests/data/acpi/virt/riscv64/FACP | Bin 0 -> 276 bytes tests/data/acpi/virt/riscv64/MCFG | Bin 0 -> 60 bytes tests/data/acpi/virt/riscv64/RHCT | Bin 0 -> 314 bytes tests/data/acpi/virt/riscv64/RSDP | Bin 0 -> 36 bytes tests/data/acpi/virt/riscv64/SPCR | Bin 0 -> 80 bytes tests/data/acpi/virt/riscv64/XSDT | Bin 0 -> 84 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 tests/data/acpi/virt/riscv64/APIC create mode 100755 tests/data/acpi/virt/riscv64/BGRT create mode 100755 tests/data/acpi/virt/riscv64/DSDT create mode 100755 tests/data/acpi/virt/riscv64/FACP create mode 100755 tests/data/acpi/virt/riscv64/MCFG create mode 100755 tests/data/acpi/virt/riscv64/RHCT create mode 100755 tests/data/acpi/virt/riscv64/RSDP create mode 100755 tests/data/acpi/virt/riscv64/SPCR create mode 100755 tests/data/acpi/virt/riscv64/XSDT diff --git a/tests/data/acpi/virt/riscv64/APIC b/tests/data/acpi/virt/riscv64/APIC new file mode 100755 index ..66a25dfd2d6ea2b607c024722b2eab95873a01e9 GIT binary patch literal 116 zcmZ<^@N_O=U|?X|;^gn_5v<@85#X!<1dKp25F13pfP@Mo12P{Zj?R|`s)2!c7=s}J I#NvT*0o0BN0RR91 literal 0 HcmV?d1 diff --git a/tests/data/acpi/virt/riscv64/BGRT b/tests/data/acpi/virt/riscv64/BGRT new file mode 100755 index ..dccf14cce4063dbfe18cd8a459aaa8b206d3b3f0 GIT binary patch literal 56 zcmZ>A4+^nhU|?XZ_Vf#J^-*wj@itNb0w$msh!zG)F#_2V3gY!3S{^7-3}gTR|5yhB literal 0 HcmV?d1 diff --git a/tests/data/acpi/virt/riscv64/DSDT b/tests/data/acpi/virt/riscv64/DSDT new file mode 100755 index ..0fb2d5e0e389541209b765d5092d0706f40298f6 GIT binary patch literal 3518 zcmZvf%WvaU6vnR;w@IBxlQexl(t(j!ppl%0(ryqeCJ*}oI`D?w!iChKA+$9t$orAn%(bn zN+n)t?0eh6a^of6TgGN7rRbcFh1Tyc_k%{iceZVNuIr}z+pT7)qm0&dr&dmZB`a{a^Ra*0&D5Eo1b;X8Qm}E3gQYkTOF1_DRa)WNl^t#{A^TNmZNji{btZCtt5&QPNDqU;E!+b zecnEQ^xc;~?0jvN=B?69B6sx0n@1-LMChb{iWO(USDtFAW3{YY{55g*p1P}!a8zWX z7lz;IPVBzpJS=7G%wV8y2Q62ba|`EHRm#%1lYm%>L=vK=N;x|_7+?*WxKL3R0`umY z&O>MhKe$y(1g;N2-TU8l!@sOMoiwl`i1tW@cj+o4-cu3BPCB-VhD+4MD9hIDroD&Pl#Oi8OIy2%- zNlr-4iRFXLXr|LTGn$gLp$V}cX!M^n3=p)tt`$vN>NG_kr`M{qil6Owag1ZPHY zW+W#h=gbPutl-Q_PDsv)?-Htwo@Y*Q<|HR1=gbSvyx`1BPDsup=eXpAX~8)yIHx5iBIp+lDoZy_3oRFMzUU1F}&UwiR$vGDU=Yrr|kera5b5U?E3eH8z3CTH^1m}|A zT#}rSoU5@qiM`L8Qmx@>rXnqyVu6bqy3;0 zSfN$e$O$X-aop-gjFlN1TJ2C(VM8aZsGs9rPsDhcG3gaHcG3%d9rt=N#>h-rEXOMpLn!a_)bcQwbVUYCt>d6Z~go(OKwiV=x$e6rJOWm8FJLZ)jL(gSOQ9 z(=101Q%{N90rg{iGreXyIPiUy_PU*2Ro)uw?+2cJexkhQVfAu5b@3W?^1b$-wSOuL z8($pWumAYmuXoN*92)^EIHqx|osu9QI;oM>2efl4w7)DozPM|Bh$~ecUA>%od=bT& z;R0PerC=JrI{7MZ#_1;2tCR9A{Hkc%mp4o`zpVZISFrki`_c5@?b)Ba_T|{c>*}hQ pv@F`;cR<_jYzAT_(hnb+|8pBtRxTSGr9{slF`>K_0A literal 0 HcmV?d1 diff --git a/tests/data/acpi/virt/riscv64/FACP b/tests/data/acpi/virt/riscv64/FACP new file mode 100755 index ..a5276b65ea8ce46cc9b40d96d98f0669c9089ed4 GIT binary patch literal 276 zcmZ>BbPf<`lE(^DK1@Wog4=(iq&1K z7;1J`gewX|OE=3Z>{xM3wM)ljIQKa+635YaZ7jrOeGc+eJEnks*|jl=GEUBVQ8WhX zK@GjINg;u`)Bd);9H literal 0 HcmV?d1 diff --git a/tests/data/acpi/virt/riscv64/RSDP b/tests/data/acpi/virt/riscv64/RSDP new file mode 100755 index ..55054f8730c389d0d7eba90c24a1dae6d1283b90 GIT binary patch literal 36 ncmWFvc2Nij2~zmyE!S15v<@85#X!<1dKp25F12;fdT`FDF9*%FmM4$c8~z`e;@#f G!2kgKJqrN< literal 0 HcmV?d1 diff --git a/tests/data/acpi/virt/riscv64/XSDT b/tests/data/acpi/virt/riscv64/XSDT new file mode 100755 index ..c69474889664d72d075419c0a1dcf1d82ec44268 GIT binary patch literal 84 zcmazDb_oe#U|?VrcJg=j2v%^42yj*a0!E-1h!zG)F&y~+AIN23*Z`#$K
[RFC PATCH-for-9.1 14/21] system: Introduce QMP generic_query_cpu_definitions()
Each target use a common template for qmp_query_cpu_definitions(). Extract it as generic_query_cpu_definitions(), keeping the target-specific implementations as the following SysemuCPUOps handlers: - cpu_list_compare() - add_definition() - add_alias_definitions() Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 2 + include/hw/core/sysemu-cpu-ops.h | 14 ++ include/qapi/commands-target-compat.h | 14 ++ system/cpu-qmp-cmds.c | 71 +++ system/meson.build| 1 + 5 files changed, 102 insertions(+) create mode 100644 include/qapi/commands-target-compat.h create mode 100644 system/cpu-qmp-cmds.c diff --git a/MAINTAINERS b/MAINTAINERS index af27490243..39d7c14d98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -148,6 +148,7 @@ M: Richard Henderson R: Paolo Bonzini S: Maintained F: system/cpus.c +F: system/cpu-qmp-cmds.c F: system/cpu-qom-helpers.c F: system/watchpoint.c F: cpu-common.c @@ -1894,6 +1895,7 @@ F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h +F: include/qapi/commands-target-compat.h F: include/sysemu/numa.h F: tests/unit/test-smp-parse.c T: git https://gitlab.com/ehabkost/qemu.git machine-next diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h index 24d003fe04..2173226e97 100644 --- a/include/hw/core/sysemu-cpu-ops.h +++ b/include/hw/core/sysemu-cpu-ops.h @@ -11,6 +11,7 @@ #define SYSEMU_CPU_OPS_H #include "hw/core/cpu.h" +#include "qapi/qapi-types-machine.h" /* * struct SysemuCPUOps: System operations specific to a CPU class @@ -81,6 +82,19 @@ typedef struct SysemuCPUOps { */ bool (*virtio_is_big_endian)(CPUState *cpu); +/** + * @cpu_list_compare: Sort alphabetically by type name, + *respecting CPUClass::ordering. + */ +gint (*cpu_list_compare)(gconstpointer cpu_class_a, gconstpointer cpu_class_b); +/** + * @add_definition: Add the @cpu_class definition to @cpu_list. + */ +void (*add_definition)(gpointer cpu_class, gpointer cpu_list); +/** + * @add_alias_definitions: Add CPU alias definitions to @cpu_list. + */ +void (*add_alias_definitions)(CpuDefinitionInfoList **cpu_list); /** * @legacy_vmsd: Legacy state for migration. * Do not use in new targets, use #DeviceClass::vmsd instead. diff --git a/include/qapi/commands-target-compat.h b/include/qapi/commands-target-compat.h new file mode 100644 index 00..86d45d8fcc --- /dev/null +++ b/include/qapi/commands-target-compat.h @@ -0,0 +1,14 @@ +/* + * QAPI helpers for target specific QMP commands + * + * SPDX-FileCopyrightText: 2024 Linaro Ltd. + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef QAPI_COMPAT_TARGET_H +#define QAPI_COMPAT_TARGET_H + +#include "qapi/qapi-types-machine.h" + +CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp); + +#endif diff --git a/system/cpu-qmp-cmds.c b/system/cpu-qmp-cmds.c new file mode 100644 index 00..daeb131159 --- /dev/null +++ b/system/cpu-qmp-cmds.c @@ -0,0 +1,71 @@ +/* + * QAPI helpers for target specific QMP commands + * + * SPDX-FileCopyrightText: 2024 Linaro Ltd. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qom/object.h" +#include "qapi/commands-target-compat.h" +#include "sysemu/arch_init.h" +#include "hw/core/cpu.h" +#include "hw/core/sysemu-cpu-ops.h" + +static void cpu_common_add_definition(gpointer data, gpointer user_data) +{ +ObjectClass *oc = data; +CpuDefinitionInfoList **cpu_list = user_data; +CpuDefinitionInfo *info; +const char *typename; + +typename = object_class_get_name(oc); +info = g_malloc0(sizeof(*info)); +info->name = cpu_model_from_type(typename); +info->q_typename = g_strdup(typename); + +QAPI_LIST_PREPEND(*cpu_list, info); +} + +static void arch_add_cpu_definitions(CpuDefinitionInfoList **cpu_list, + const char *cpu_typename) +{ +ObjectClass *oc; +GSList *list; +const struct SysemuCPUOps *ops; + +oc = object_class_by_name(cpu_typename); +if (!oc) { +return; +} +ops = CPU_CLASS(oc)->sysemu_ops; + +list = object_class_get_list(cpu_typename, false); +if (ops->cpu_list_compare) { +list = g_slist_sort(list, ops->cpu_list_compare); +} +g_slist_foreach(list, ops->add_definition ? : cpu_common_add_definition, +cpu_list); +g_slist_free(list); + +if (ops->add_alias_definitions) { +ops->add_alias_definitions(cpu_list); +} +} + +CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp) +{ +CpuDefinitionInfoList *cpu_list = NULL; + +for (unsigned i = 0; i <= QEMU_ARCH_BIT_LAST; i++) { +const char *cpu_typename; + +cpu_typename = cpu_typename_by_arch_bit(i); +if (!cpu_typename
[RFC PATCH-for-9.1 18/21] target/i386: Use QMP generic_query_cpu_definitions()
Register x86_cpu_definition_entry() and x86_cpu_list_compare() as handler so we can use the QMP generic_query_cpu_definitions() method. Signed-off-by: Philippe Mathieu-Daudé --- target/i386/cpu.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 07f64c1ea5..e5dbd307d8 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -38,6 +38,7 @@ #ifndef CONFIG_USER_ONLY #include "sysemu/reset.h" #include "qapi/qapi-commands-machine-target.h" +#include "qapi/commands-target-compat.h" #include "exec/address-spaces.h" #include "hw/boards.h" #include "hw/i386/sgx-epc.h" @@ -5667,11 +5668,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list = get_sorted_cpu_model_list(); -g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list); -g_slist_free(list); -return cpu_list; +return generic_query_cpu_definitions(errp); } #endif /* !CONFIG_USER_ONLY */ @@ -7937,6 +7934,8 @@ static Property x86_cpu_properties[] = { #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps i386_sysemu_ops = { +.add_definition = x86_cpu_definition_entry, +.cpu_list_compare = x86_cpu_list_compare, .get_memory_mapping = x86_cpu_get_memory_mapping, .get_paging_enabled = x86_cpu_get_paging_enabled, .get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug, -- 2.41.0
[PATCH-for-9.1 11/21] qapi: Make CpuDefinitionInfo target agnostic
Generate the CpuDefinitionInfo type once for all targets. In few commits @query-cpu-definitions will become generic and all target will return their CPUs list. Signed-off-by: Philippe Mathieu-Daudé --- qapi/machine-target.json | 69 qapi/machine.json| 63 2 files changed, 63 insertions(+), 69 deletions(-) diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 0412400df3..7480921d33 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -212,75 +212,6 @@ 'TARGET_LOONGARCH64', 'TARGET_RISCV' ] } } -## -# @CpuDefinitionInfo: -# -# Virtual CPU definition. -# -# @name: the name of the CPU definition -# -# @migration-safe: whether a CPU definition can be safely used for -# migration in combination with a QEMU compatibility machine when -# migrating between different QEMU versions and between hosts with -# different sets of (hardware or software) capabilities. If not -# provided, information is not available and callers should not -# assume the CPU definition to be migration-safe. (since 2.8) -# -# @static: whether a CPU definition is static and will not change -# depending on QEMU version, machine type, machine options and -# accelerator options. A static model is always migration-safe. -# (since 2.8) -# -# @unavailable-features: List of properties that prevent the CPU model -# from running in the current host. (since 2.8) -# -# @typename: Type name that can be used as argument to -# @device-list-properties, to introspect properties configurable -# using -cpu or -global. (since 2.9) -# -# @alias-of: Name of CPU model this model is an alias for. The target -# of the CPU model alias may change depending on the machine type. -# Management software is supposed to translate CPU model aliases -# in the VM configuration, because aliases may stop being -# migration-safe in the future (since 4.1) -# -# @deprecated: If true, this CPU model is deprecated and may be -# removed in in some future version of QEMU according to the QEMU -# deprecation policy. (since 5.2) -# -# @unavailable-features is a list of QOM property names that represent -# CPU model attributes that prevent the CPU from running. If the QOM -# property is read-only, that means there's no known way to make the -# CPU model run in the current host. Implementations that choose not -# to provide specific information return the property name "type". If -# the property is read-write, it means that it MAY be possible to run -# the CPU model in the current host if that property is changed. -# Management software can use it as hints to suggest or choose an -# alternative for the user, or just to generate meaningful error -# messages explaining why the CPU model can't be used. If -# @unavailable-features is an empty list, the CPU model is runnable -# using the current host and machine-type. If @unavailable-features -# is not present, runnability information for the CPU is not -# available. -# -# Since: 1.2 -## -{ 'struct': 'CpuDefinitionInfo', - 'data': { 'name': 'str', -'*migration-safe': 'bool', -'static': 'bool', -'*unavailable-features': [ 'str' ], -'typename': 'str', -'*alias-of' : 'str', -'deprecated' : 'bool' }, - 'if': { 'any': [ 'TARGET_PPC', - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', - 'TARGET_MIPS', - 'TARGET_LOONGARCH64', - 'TARGET_RISCV' ] } } - ## # @query-cpu-definitions: # diff --git a/qapi/machine.json b/qapi/machine.json index 65702c2c78..9c44b8fa82 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -10,6 +10,69 @@ { 'include': 'common.json' } +## +# @CpuDefinitionInfo: +# +# Virtual CPU definition. +# +# @name: the name of the CPU definition +# +# @migration-safe: whether a CPU definition can be safely used for +# migration in combination with a QEMU compatibility machine when +# migrating between different QEMU versions and between hosts with +# different sets of (hardware or software) capabilities. If not +# provided, information is not available and callers should not +# assume the CPU definition to be migration-safe. (since 2.8) +# +# @static: whether a CPU definition is static and will not change +# depending on QEMU version, machine type, machine options and +# accelerator options. A static model is always migration-safe. +# (since 2.8) +# +# @unavailable-features: List of properties that prevent the CPU model +# from running in the current host. (since 2.8) +# +# @typename: Type name that can be used as argument to +# @device-list-properties, to introspect properties configurable +# using -cpu or -global. (since 2.9) +# +# @alias-of: Name of CPU model
[RFC PATCH-for-9.1 16/21] target/loongarch: Use QMP generic_query_cpu_definitions()
Signed-off-by: Philippe Mathieu-Daudé --- target/loongarch/loongarch-qmp-cmds.c | 23 ++- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c index 8721a5eb13..ef5aedc1cd 100644 --- a/target/loongarch/loongarch-qmp-cmds.c +++ b/target/loongarch/loongarch-qmp-cmds.c @@ -9,34 +9,15 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-commands-machine-target.h" +#include "qapi/commands-target-compat.h" #include "cpu.h" #include "qapi/qmp/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qom/qom-qobject.h" -static void loongarch_cpu_add_definition(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CpuDefinitionInfoList **cpu_list = user_data; -CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1); -const char *typename = object_class_get_name(oc); - -info->name = cpu_model_from_type(typename); -info->q_typename = g_strdup(typename); - -QAPI_LIST_PREPEND(*cpu_list, info); -} - CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list; - -list = object_class_get_list(TYPE_LOONGARCH_CPU, false); -g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list); -g_slist_free(list); - -return cpu_list; +return generic_query_cpu_definitions(errp); } static const char *cpu_model_advertised_features[] = { -- 2.41.0
[PATCH-for-9.1 09/21] qapi: Merge machine-common.json with qapi/machine.json
machine-common.json declares a single type, which isn't restricted to a particular target. Move this type in machine.json. Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 1 - qapi/machine-common.json | 21 - qapi/machine-target.json | 2 +- qapi/machine.json| 13 - qapi/qapi-schema.json| 1 - target/s390x/cpu.h | 2 +- qapi/meson.build | 1 - 7 files changed, 14 insertions(+), 27 deletions(-) delete mode 100644 qapi/machine-common.json diff --git a/MAINTAINERS b/MAINTAINERS index a3130f64fd..ed98814398 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1889,7 +1889,6 @@ F: hw/core/null-machine.c F: hw/core/numa.c F: hw/cpu/cluster.c F: qapi/machine.json -F: qapi/machine-common.json F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h diff --git a/qapi/machine-common.json b/qapi/machine-common.json deleted file mode 100644 index fa6bd71d12..00 --- a/qapi/machine-common.json +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Mode: Python -*- -# vim: filetype=python -# -# This work is licensed under the terms of the GNU GPL, version 2 or later. -# See the COPYING file in the top-level directory. - -## -# = Machines S390 data types -## - -## -# @CpuS390Entitlement: -# -# An enumeration of CPU entitlements that can be assumed by a virtual -# S390 CPU -# -# Since: 8.2 -## -{ 'enum': 'CpuS390Entitlement', - 'prefix': 'S390_CPU_ENTITLEMENT', - 'data': [ 'auto', 'low', 'medium', 'high' ] } diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 519adf3220..5f17b25d50 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -4,7 +4,7 @@ # This work is licensed under the terms of the GNU GPL, version 2 or later. # See the COPYING file in the top-level directory. -{ 'include': 'machine-common.json' } +{ 'include': 'machine.json' } ## # @CpuModelInfo: diff --git a/qapi/machine.json b/qapi/machine.json index bb5a178909..4bc38e86fd 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -9,7 +9,6 @@ ## { 'include': 'common.json' } -{ 'include': 'machine-common.json' } ## # @SysEmuTarget: @@ -50,6 +49,18 @@ 'prefix': 'S390_CPU_STATE', 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] } +## +# @CpuS390Entitlement: +# +# An enumeration of CPU entitlements that can be assumed by a virtual +# S390 CPU +# +# Since: 8.2 +## +{ 'enum': 'CpuS390Entitlement', + 'prefix': 'S390_CPU_ENTITLEMENT', + 'data': [ 'auto', 'low', 'medium', 'high' ] } + ## # @CpuInfoS390: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 8304d45625..2c82a49bae 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -67,7 +67,6 @@ { 'include': 'introspect.json' } { 'include': 'qom.json' } { 'include': 'qdev.json' } -{ 'include': 'machine-common.json' } { 'include': 'machine.json' } { 'include': 'machine-target.json' } { 'include': 'replay.json' } diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 43a46a5a06..b46339bd7c 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -29,7 +29,7 @@ #include "cpu_models.h" #include "exec/cpu-defs.h" #include "qemu/cpu-float.h" -#include "qapi/qapi-types-machine-common.h" +#include "qapi/qapi-types-machine.h" #define ELF_MACHINE_UNAME "S390X" diff --git a/qapi/meson.build b/qapi/meson.build index 375d564277..90047dae1c 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -37,7 +37,6 @@ qapi_all_modules = [ 'error', 'introspect', 'job', - 'machine-common', 'machine', 'machine-target', 'migration', -- 2.41.0
[PATCH-for-9.1 19/21] target/ppc: Factor ppc_add_alias_definitions() out
Factor ppc_add_alias_definitions() out of qmp_query_cpu_definitions() to clearly see the generic pattern used in all targets. Signed-off-by: Philippe Mathieu-Daudé --- target/ppc/cpu-models.h | 4 target/ppc/ppc-qmp-cmds.c | 26 +++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h index 0229ef3a9a..89a5e232b7 100644 --- a/target/ppc/cpu-models.h +++ b/target/ppc/cpu-models.h @@ -21,6 +21,8 @@ #ifndef TARGET_PPC_CPU_MODELS_H #define TARGET_PPC_CPU_MODELS_H +#include "qapi/qapi-types-machine.h" + /** * PowerPCCPUAlias: * @alias: The alias name. @@ -480,4 +482,6 @@ enum { POWERPC_SVR_8641D = 0x80900121, }; +void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list); + #endif diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c index a25d86a8d1..528cc3e4af 100644 --- a/target/ppc/ppc-qmp-cmds.c +++ b/target/ppc/ppc-qmp-cmds.c @@ -189,17 +189,9 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*first, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list; -int i; - -list = object_class_get_list(TYPE_POWERPC_CPU, false); -g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list); -g_slist_free(list); - -for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { +for (unsigned i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; ObjectClass *oc; CpuDefinitionInfo *info; @@ -213,8 +205,20 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) info->name = g_strdup(alias->alias); info->q_typename = g_strdup(object_class_get_name(oc)); -QAPI_LIST_PREPEND(cpu_list, info); +QAPI_LIST_PREPEND(*cpu_list, info); } +} + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ +CpuDefinitionInfoList *cpu_list = NULL; +GSList *list; + +list = object_class_get_list(TYPE_POWERPC_CPU, false); +g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list); +g_slist_free(list); + +ppc_add_alias_definitions(&cpu_list); return cpu_list; } -- 2.41.0
[PATCH-for-9.1 13/21] system: Introduce cpu_typename_by_arch_bit()
Introduce a helper to return the CPU type name given a QemuArchBit. The TYPE_PPC_CPU target have different 32/64-bit definitions so we can not include it yet. Signed-off-by: Philippe Mathieu-Daudé --- --- MAINTAINERS| 1 + include/sysemu/arch_init.h | 2 ++ system/cpu-qom-helpers.c | 58 ++ system/meson.build | 1 + 4 files changed, 62 insertions(+) create mode 100644 system/cpu-qom-helpers.c diff --git a/MAINTAINERS b/MAINTAINERS index ed98814398..af27490243 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -148,6 +148,7 @@ M: Richard Henderson R: Paolo Bonzini S: Maintained F: system/cpus.c +F: system/cpu-qom-helpers.c F: system/watchpoint.c F: cpu-common.c F: cpu-target.c diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index cf597c40a3..1874f18e67 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -27,6 +27,8 @@ typedef enum QemuArchBit { QEMU_ARCH_BIT_LAST = QEMU_ARCH_BIT_LOONGARCH } QemuArchBit; +const char *cpu_typename_by_arch_bit(QemuArchBit arch_bit); + enum QemuArchMask { QEMU_ARCH_ALL = -1, QEMU_ARCH_ALPHA = (1 << QEMU_ARCH_BIT_ALPHA), diff --git a/system/cpu-qom-helpers.c b/system/cpu-qom-helpers.c new file mode 100644 index 00..0d402ee3a0 --- /dev/null +++ b/system/cpu-qom-helpers.c @@ -0,0 +1,58 @@ +/* + * Helpers for CPU QOM types + * + * SPDX-FileCopyrightText: 2024 Linaro Ltd. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "sysemu/arch_init.h" + +#include "target/alpha/cpu-qom.h" +#include "target/arm/cpu-qom.h" +#include "target/avr/cpu-qom.h" +#include "target/cris/cpu-qom.h" +#include "target/hexagon/cpu-qom.h" +#include "target/hppa/cpu-qom.h" +#include "target/i386/cpu-qom.h" +#include "target/loongarch/cpu-qom.h" +#include "target/m68k/cpu-qom.h" +#include "target/microblaze/cpu-qom.h" +#include "target/mips/cpu-qom.h" +#include "target/nios2/cpu-qom.h" +#include "target/openrisc/cpu-qom.h" +#include "target/riscv/cpu-qom.h" +#include "target/rx/cpu-qom.h" +#include "target/s390x/cpu-qom.h" +#include "target/sparc/cpu-qom.h" +#include "target/sh4/cpu-qom.h" +#include "target/tricore/cpu-qom.h" +#include "target/xtensa/cpu-qom.h" + +const char *cpu_typename_by_arch_bit(QemuArchBit arch_bit) +{ +static const char *cpu_bit_to_typename[QEMU_ARCH_BIT_LAST + 1] = { +[QEMU_ARCH_BIT_ALPHA] = TYPE_ALPHA_CPU, +[QEMU_ARCH_BIT_ARM] = TYPE_ARM_CPU, +[QEMU_ARCH_BIT_CRIS]= TYPE_CRIS_CPU, +[QEMU_ARCH_BIT_I386]= TYPE_I386_CPU, +[QEMU_ARCH_BIT_M68K]= TYPE_M68K_CPU, +[QEMU_ARCH_BIT_MICROBLAZE] = TYPE_MICROBLAZE_CPU, +[QEMU_ARCH_BIT_MIPS]= TYPE_MIPS_CPU, +/* TODO: TYPE_PPC_CPU */ +[QEMU_ARCH_BIT_S390X] = TYPE_S390_CPU, +[QEMU_ARCH_BIT_SH4] = TYPE_SUPERH_CPU, +[QEMU_ARCH_BIT_SPARC] = TYPE_SPARC_CPU, +[QEMU_ARCH_BIT_XTENSA] = TYPE_XTENSA_CPU, +[QEMU_ARCH_BIT_OPENRISC]= TYPE_OPENRISC_CPU, +[QEMU_ARCH_BIT_TRICORE] = TYPE_TRICORE_CPU, +[QEMU_ARCH_BIT_NIOS2] = TYPE_NIOS2_CPU, +[QEMU_ARCH_BIT_HPPA]= TYPE_HPPA_CPU, +[QEMU_ARCH_BIT_RISCV] = TYPE_RISCV_CPU, +[QEMU_ARCH_BIT_RX] = TYPE_RX_CPU, +[QEMU_ARCH_BIT_AVR] = TYPE_AVR_CPU, +[QEMU_ARCH_BIT_HEXAGON] = TYPE_HEXAGON_CPU, +[QEMU_ARCH_BIT_LOONGARCH] = TYPE_LOONGARCH_CPU, +}; +return cpu_bit_to_typename[arch_bit]; +} diff --git a/system/meson.build b/system/meson.build index 25e2117250..c6ee97e3b2 100644 --- a/system/meson.build +++ b/system/meson.build @@ -10,6 +10,7 @@ system_ss.add(files( 'balloon.c', 'bootdevice.c', 'cpus.c', + 'cpu-qom-helpers.c', 'cpu-throttle.c', 'cpu-timers.c', 'datadir.c', -- 2.41.0
[PATCH 09/12] pc-bios/meson.build: Add support for RISC-V in unpack_edk2_blobs
Update list of images supported in unpack_edk2_blobs to enable RISC-V ACPI table testing. Signed-off-by: Sunil V L --- pc-bios/meson.build | 2 ++ tests/qtest/meson.build | 3 +++ 2 files changed, 5 insertions(+) diff --git a/pc-bios/meson.build b/pc-bios/meson.build index 0760612bea..8602b45b9b 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -4,6 +4,8 @@ if unpack_edk2_blobs 'edk2-aarch64-code.fd', 'edk2-arm-code.fd', 'edk2-arm-vars.fd', +'edk2-riscv-code.fd', +'edk2-riscv-vars.fd', 'edk2-i386-code.fd', 'edk2-i386-secure-code.fd', 'edk2-i386-vars.fd', diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 36c5c13a7b..dd19711d9f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -252,6 +252,9 @@ qtests_s390x = \ qtests_riscv32 = \ (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? ['sifive-e-aon-watchdog-test'] : []) +qtests_riscv64 = \ + (unpack_edk2_blobs ? ['bios-tables-test'] : []) + qos_test_ss = ss.source_set() qos_test_ss.add( 'ac97-test.c', -- 2.40.1
[PATCH 10/12] tests/data/acpi/rebuild-expected-aml.sh: Add RISC-V
Update the list of supported architectures to include RISC-V. Signed-off-by: Sunil V L --- tests/data/acpi/rebuild-expected-aml.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/data/acpi/rebuild-expected-aml.sh b/tests/data/acpi/rebuild-expected-aml.sh index dcf2e2f221..c1092fb8ba 100755 --- a/tests/data/acpi/rebuild-expected-aml.sh +++ b/tests/data/acpi/rebuild-expected-aml.sh @@ -12,7 +12,7 @@ # This work is licensed under the terms of the GNU GPLv2. # See the COPYING.LIB file in the top-level directory. -qemu_arches="x86_64 aarch64" +qemu_arches="x86_64 aarch64 riscv64" if [ ! -e "tests/qtest/bios-tables-test" ]; then echo "Test: bios-tables-test is required! Run make check before this script." @@ -36,7 +36,8 @@ fi if [ -z "$qemu_bins" ]; then echo "Only the following architectures are currently supported: $qemu_arches" echo "None of these configured!" -echo "To fix, run configure --target-list=x86_64-softmmu,aarch64-softmmu" +echo "To fix, run configure \ + --target-list=x86_64-softmmu,aarch64-softmmu,riscv64-softmmu" exit 1; fi -- 2.40.1
[PATCH-for-9.1 10/21] qapi: Make CpuModel* definitions target agnostic
CpuModelInfo, CpuModelExpansionType and CpuModelCompareResult are not restricted to any particular target. Define them in machine.json to generate them once. Signed-off-by: Philippe Mathieu-Daudé --- qapi/machine-target.json | 78 --- qapi/machine.json| 79 2 files changed, 79 insertions(+), 78 deletions(-) diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 5f17b25d50..0412400df3 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -6,84 +6,6 @@ { 'include': 'machine.json' } -## -# @CpuModelInfo: -# -# Virtual CPU model. -# -# A CPU model consists of the name of a CPU definition, to which delta -# changes are applied (e.g. features added/removed). Most magic values -# that an architecture might require should be hidden behind the name. -# However, if required, architectures can expose relevant properties. -# -# @name: the name of the CPU definition the model is based on -# -# @props: a dictionary of QOM properties to be applied -# -# Since: 2.8 -## -{ 'struct': 'CpuModelInfo', - 'data': { 'name': 'str', -'*props': 'any' } } - -## -# @CpuModelExpansionType: -# -# An enumeration of CPU model expansion types. -# -# @static: Expand to a static CPU model, a combination of a static -# base model name and property delta changes. As the static base -# model will never change, the expanded CPU model will be the -# same, independent of QEMU version, machine type, machine -# options, and accelerator options. Therefore, the resulting -# model can be used by tooling without having to specify a -# compatibility machine - e.g. when displaying the "host" model. -# The @static CPU models are migration-safe. -# -# @full: Expand all properties. The produced model is not guaranteed -# to be migration-safe, but allows tooling to get an insight and -# work with model details. -# -# Note: When a non-migration-safe CPU model is expanded in static -# mode, some features enabled by the CPU model may be omitted, -# because they can't be implemented by a static CPU model -# definition (e.g. cache info passthrough and PMU passthrough in -# x86). If you need an accurate representation of the features -# enabled by a non-migration-safe CPU model, use @full. If you -# need a static representation that will keep ABI compatibility -# even when changing QEMU version or machine-type, use @static -# (but keep in mind that some features may be omitted). -# -# Since: 2.8 -## -{ 'enum': 'CpuModelExpansionType', - 'data': [ 'static', 'full' ] } - -## -# @CpuModelCompareResult: -# -# An enumeration of CPU model comparison results. The result is -# usually calculated using e.g. CPU features or CPU generations. -# -# @incompatible: If model A is incompatible to model B, model A is not -# guaranteed to run where model B runs and the other way around. -# -# @identical: If model A is identical to model B, model A is -# guaranteed to run where model B runs and the other way around. -# -# @superset: If model A is a superset of model B, model B is -# guaranteed to run where model A runs. There are no guarantees -# about the other way. -# -# @subset: If model A is a subset of model B, model A is guaranteed to -# run where model B runs. There are no guarantees about the other -# way. -# -# Since: 2.8 -## -{ 'enum': 'CpuModelCompareResult', - 'data': [ 'incompatible', 'identical', 'superset', 'subset' ] } - ## # @CpuModelBaselineInfo: # diff --git a/qapi/machine.json b/qapi/machine.json index 4bc38e86fd..65702c2c78 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -10,6 +10,85 @@ { 'include': 'common.json' } +## +# @CpuModelInfo: +# +# Virtual CPU model. +# +# A CPU model consists of the name of a CPU definition, to which delta +# changes are applied (e.g. features added/removed). Most magic values +# that an architecture might require should be hidden behind the name. +# However, if required, architectures can expose relevant properties. +# +# @name: the name of the CPU definition the model is based on +# +# @props: a dictionary of QOM properties to be applied +# +# Since: 2.8 +## +{ 'struct': 'CpuModelInfo', + 'data': { 'name': 'str', +'*props': 'any' } +} + +## +# @CpuModelExpansionType: +# +# An enumeration of CPU model expansion types. +# +# @static: Expand to a static CPU model, a combination of a static +# base model name and property delta changes. As the static base +# model will never change, the expanded CPU model will be the +# same, independent of QEMU version, machine type, machine +# options, and accelerator options. Therefore, the resulting +# model can be used by tooling without having to specify a +# compatibility machine - e.g. when displaying the "host" model. +# The @static CPU models are migration-safe. +# +# @full: Expand all propertie
[PATCH 05/12] qtest: bios-tables-test: Rename aarch64 tests with aarch64 in them
Existing AARCH64 virt test functions do not have AARCH64 in their name. To add RISC-V virt related test cases, better to rename existing functions to indicate they are ARM only. Signed-off-by: Sunil V L --- tests/qtest/bios-tables-test.c | 35 ++ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index 21811a1ab5..ea3ba1992b 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1557,7 +1557,7 @@ static void test_acpi_piix4_tcg_dimm_pxm(void) test_acpi_tcg_dimm_pxm(MACHINE_PC); } -static void test_acpi_virt_tcg_memhp(void) +static void test_acpi_aarch64_virt_tcg_memhp(void) { test_data data = { .machine = "virt", @@ -1650,7 +1650,7 @@ static void test_acpi_microvm_ioapic2_tcg(void) free_test_data(&data); } -static void test_acpi_virt_tcg_numamem(void) +static void test_acpi_aarch64_virt_tcg_numamem(void) { test_data data = { .machine = "virt", @@ -1672,7 +1672,7 @@ static void test_acpi_virt_tcg_numamem(void) } -static void test_acpi_virt_tcg_pxb(void) +static void test_acpi_aarch64_virt_tcg_pxb(void) { test_data data = { .machine = "virt", @@ -1745,7 +1745,7 @@ static void test_acpi_piix4_tcg_acpi_hmat(void) test_acpi_tcg_acpi_hmat(MACHINE_PC); } -static void test_acpi_virt_tcg_acpi_hmat(void) +static void test_acpi_aarch64_virt_tcg_acpi_hmat(void) { test_data data = { .machine = "virt", @@ -1901,7 +1901,7 @@ static void test_acpi_microvm_acpi_erst(void) } #endif /* CONFIG_POSIX */ -static void test_acpi_virt_tcg(void) +static void test_acpi_aarch64_virt_tcg(void) { test_data data = { .machine = "virt", @@ -1920,7 +1920,7 @@ static void test_acpi_virt_tcg(void) free_test_data(&data); } -static void test_acpi_virt_tcg_topology(void) +static void test_acpi_aarch64_virt_tcg_topology(void) { test_data data = { .machine = "virt", @@ -2003,7 +2003,7 @@ static void test_acpi_q35_cxl(void) } #endif /* CONFIG_POSIX */ -static void test_acpi_virt_viot(void) +static void test_acpi_aarch64_virt_viot(void) { test_data data = { .machine = "virt", @@ -2135,7 +2135,7 @@ static void test_acpi_microvm_oem_fields(void) g_free(args); } -static void test_acpi_virt_oem_fields(void) +static void test_acpi_aarch64_virt_oem_fields(void) { test_data data = { .machine = "virt", @@ -2301,16 +2301,19 @@ int main(int argc, char *argv[]) } } else if (strcmp(arch, "aarch64") == 0) { if (has_tcg && qtest_has_device("virtio-blk-pci")) { -qtest_add_func("acpi/virt", test_acpi_virt_tcg); +qtest_add_func("acpi/virt", test_acpi_aarch64_virt_tcg); qtest_add_func("acpi/virt/acpihmatvirt", -test_acpi_virt_tcg_acpi_hmat); -qtest_add_func("acpi/virt/topology", test_acpi_virt_tcg_topology); -qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); -qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp); -qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb); -qtest_add_func("acpi/virt/oem-fields", test_acpi_virt_oem_fields); + test_acpi_aarch64_virt_tcg_acpi_hmat); +qtest_add_func("acpi/virt/topology", + test_acpi_aarch64_virt_tcg_topology); +qtest_add_func("acpi/virt/numamem", + test_acpi_aarch64_virt_tcg_numamem); +qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp); +qtest_add_func("acpi/virt/pxb", test_acpi_aarch64_virt_tcg_pxb); +qtest_add_func("acpi/virt/oem-fields", + test_acpi_aarch64_virt_oem_fields); if (qtest_has_device("virtio-iommu-pci")) { -qtest_add_func("acpi/virt/viot", test_acpi_virt_viot); +qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot); } } } -- 2.40.1
[RFC PATCH-for-9.1 20/21] target/ppc: Use QMP generic_query_cpu_definitions()
Register ppc_add_alias_definitions() as handler so we can use the QMP generic_query_cpu_definitions() method. Signed-off-by: Philippe Mathieu-Daudé --- target/ppc/cpu_init.c | 1 + target/ppc/ppc-qmp-cmds.c | 26 ++ 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index d5e227a6fb..3b500c95a4 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7348,6 +7348,7 @@ static Property ppc_cpu_properties[] = { #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps ppc_sysemu_ops = { +.add_alias_definitions = ppc_add_alias_definitions, .get_phys_page_debug = ppc_cpu_get_phys_page_debug, .write_elf32_note = ppc32_cpu_write_elf32_note, .write_elf64_note = ppc64_cpu_write_elf64_note, diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c index 528cc3e4af..267dd84718 100644 --- a/target/ppc/ppc-qmp-cmds.c +++ b/target/ppc/ppc-qmp-cmds.c @@ -29,6 +29,7 @@ #include "monitor/hmp-target.h" #include "monitor/hmp.h" #include "qapi/qapi-commands-machine-target.h" +#include "qapi/commands-target-compat.h" #include "cpu-models.h" #include "cpu-qom.h" @@ -175,20 +176,6 @@ int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval) return -EINVAL; } -static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CpuDefinitionInfoList **first = user_data; -const char *typename; -CpuDefinitionInfo *info; - -typename = object_class_get_name(oc); -info = g_malloc0(sizeof(*info)); -info->name = cpu_model_from_type(typename); - -QAPI_LIST_PREPEND(*first, info); -} - void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list) { for (unsigned i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { @@ -211,14 +198,5 @@ void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list) CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list; - -list = object_class_get_list(TYPE_POWERPC_CPU, false); -g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list); -g_slist_free(list); - -ppc_add_alias_definitions(&cpu_list); - -return cpu_list; +return generic_query_cpu_definitions(errp); } -- 2.41.0
[PATCH-for-9.1 12/21] system: Introduce QemuArchBit enum
Current QEMU_ARCH_foo definitions are used as masks. Extract the bit values, so we can easily iterate over. Signed-off-by: Philippe Mathieu-Daudé --- include/sysemu/arch_init.h | 69 ++ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 8850cb1a14..cf597c40a3 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -1,30 +1,55 @@ #ifndef QEMU_ARCH_INIT_H #define QEMU_ARCH_INIT_H +typedef enum QemuArchBit { +QEMU_ARCH_BIT_ALPHA = 0, +QEMU_ARCH_BIT_ARM = 1, +QEMU_ARCH_BIT_CRIS = 2, +QEMU_ARCH_BIT_I386 = 3, +QEMU_ARCH_BIT_M68K = 4, +QEMU_ARCH_BIT_MICROBLAZE= 6, +QEMU_ARCH_BIT_MIPS = 7, +QEMU_ARCH_BIT_PPC = 8, +QEMU_ARCH_BIT_S390X = 9, +QEMU_ARCH_BIT_SH4 = 10, +QEMU_ARCH_BIT_SPARC = 11, +QEMU_ARCH_BIT_XTENSA= 12, +QEMU_ARCH_BIT_OPENRISC = 13, +QEMU_ARCH_BIT_TRICORE = 16, +QEMU_ARCH_BIT_NIOS2 = 17, +QEMU_ARCH_BIT_HPPA = 18, +QEMU_ARCH_BIT_RISCV = 19, +QEMU_ARCH_BIT_RX= 20, +QEMU_ARCH_BIT_AVR = 21, +QEMU_ARCH_BIT_HEXAGON = 22, +QEMU_ARCH_BIT_LOONGARCH = 23, -enum { +QEMU_ARCH_BIT_LAST = QEMU_ARCH_BIT_LOONGARCH +} QemuArchBit; + +enum QemuArchMask { QEMU_ARCH_ALL = -1, -QEMU_ARCH_ALPHA = (1 << 0), -QEMU_ARCH_ARM = (1 << 1), -QEMU_ARCH_CRIS = (1 << 2), -QEMU_ARCH_I386 = (1 << 3), -QEMU_ARCH_M68K = (1 << 4), -QEMU_ARCH_MICROBLAZE = (1 << 6), -QEMU_ARCH_MIPS = (1 << 7), -QEMU_ARCH_PPC = (1 << 8), -QEMU_ARCH_S390X = (1 << 9), -QEMU_ARCH_SH4 = (1 << 10), -QEMU_ARCH_SPARC = (1 << 11), -QEMU_ARCH_XTENSA = (1 << 12), -QEMU_ARCH_OPENRISC = (1 << 13), -QEMU_ARCH_TRICORE = (1 << 16), -QEMU_ARCH_NIOS2 = (1 << 17), -QEMU_ARCH_HPPA = (1 << 18), -QEMU_ARCH_RISCV = (1 << 19), -QEMU_ARCH_RX = (1 << 20), -QEMU_ARCH_AVR = (1 << 21), -QEMU_ARCH_HEXAGON = (1 << 22), -QEMU_ARCH_LOONGARCH = (1 << 23), +QEMU_ARCH_ALPHA = (1 << QEMU_ARCH_BIT_ALPHA), +QEMU_ARCH_ARM = (1 << QEMU_ARCH_BIT_ARM), +QEMU_ARCH_CRIS = (1 << QEMU_ARCH_BIT_CRIS), +QEMU_ARCH_I386 = (1 << QEMU_ARCH_BIT_I386), +QEMU_ARCH_M68K = (1 << QEMU_ARCH_BIT_M68K), +QEMU_ARCH_MICROBLAZE= (1 << QEMU_ARCH_BIT_MICROBLAZE), +QEMU_ARCH_MIPS = (1 << QEMU_ARCH_BIT_MIPS), +QEMU_ARCH_PPC = (1 << QEMU_ARCH_BIT_PPC), +QEMU_ARCH_S390X = (1 << QEMU_ARCH_BIT_S390X), +QEMU_ARCH_SH4 = (1 << QEMU_ARCH_BIT_SH4), +QEMU_ARCH_SPARC = (1 << QEMU_ARCH_BIT_SPARC), +QEMU_ARCH_XTENSA= (1 << QEMU_ARCH_BIT_XTENSA), +QEMU_ARCH_OPENRISC = (1 << QEMU_ARCH_BIT_OPENRISC), +QEMU_ARCH_TRICORE = (1 << QEMU_ARCH_BIT_TRICORE), +QEMU_ARCH_NIOS2 = (1 << QEMU_ARCH_BIT_NIOS2), +QEMU_ARCH_HPPA = (1 << QEMU_ARCH_BIT_HPPA), +QEMU_ARCH_RISCV = (1 << QEMU_ARCH_BIT_RISCV), +QEMU_ARCH_RX= (1 << QEMU_ARCH_BIT_RX), +QEMU_ARCH_AVR = (1 << QEMU_ARCH_BIT_AVR), +QEMU_ARCH_HEXAGON = (1 << QEMU_ARCH_BIT_HEXAGON), +QEMU_ARCH_LOONGARCH = (1 << QEMU_ARCH_BIT_LOONGARCH), }; extern const uint32_t arch_type; -- 2.41.0
[RFC PATCH-for-9.1 00/21] qapi: Make @query-cpu-definitions command target-agnostic
Hi Alex, Markus, Markus mentioned QAPI problems with the heterogeneous emulation binary. My understanding is, while QAPI can use host-specific conditional (OS, library available, configure option), it shouldn't use target-specific ones. This series is an example on how to remove target specific bits from the @query-cpu-definitions command. Target specific code is registered as CPUClass handlers, then a generic method is used, iterating over all targets built in. The first set of patches were already posted / reviewed last year. The PPC and S390X targets still need work (help welcomed), however the code is useful enough to be tested and see if this is a good approach. The only drawback is a change in QAPI introspection, because targets not implementing @query-cpu-definitions were returning "CommandNotFound". My view is this was an incomplete implementation, rather than a feature. Regards, Phil. Philippe Mathieu-Daudé (21): target/i386: Declare CPU QOM types using DEFINE_TYPES() macro target/mips: Declare CPU QOM types using DEFINE_TYPES() macro target/ppc: Declare CPU QOM types using DEFINE_TYPES() macro target/sparc: Declare CPU QOM types using DEFINE_TYPES() macro cpus: Open code OBJECT_DECLARE_TYPE() in OBJECT_DECLARE_CPU_TYPE() target/i386: Make X86_CPU common to new I386_CPU / X86_64_CPU types target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types target/sparc: Make SPARC_CPU common to new SPARC32_CPU/SPARC64_CPU types qapi: Merge machine-common.json with qapi/machine.json qapi: Make CpuModel* definitions target agnostic qapi: Make CpuDefinitionInfo target agnostic system: Introduce QemuArchBit enum system: Introduce cpu_typename_by_arch_bit() system: Introduce QMP generic_query_cpu_definitions() target/arm: Use QMP generic_query_cpu_definitions() target/loongarch: Use QMP generic_query_cpu_definitions() target/riscv: Use QMP generic_query_cpu_definitions() target/i386: Use QMP generic_query_cpu_definitions() target/ppc: Factor ppc_add_alias_definitions() out target/ppc: Use QMP generic_query_cpu_definitions() qapi: Make @query-cpu-definitions target-agnostic MAINTAINERS | 3 +- qapi/machine-common.json | 21 qapi/machine-target.json | 167 +- qapi/machine.json | 166 - qapi/qapi-schema.json | 1 - include/hw/core/cpu.h | 7 +- include/hw/core/sysemu-cpu-ops.h | 14 +++ include/sysemu/arch_init.h| 71 +++ target/i386/cpu-qom.h | 16 ++- target/mips/cpu-qom.h | 13 +- target/ppc/cpu-models.h | 4 + target/riscv/cpu.h| 2 + target/s390x/cpu.h| 2 +- target/sparc/cpu-qom.h| 9 +- system/cpu-qmp-cmds.c | 71 +++ system/cpu-qom-helpers.c | 58 + target/arm/arm-qmp-cmds.c | 27 - target/i386/cpu.c | 77 ++-- target/loongarch/loongarch-qmp-cmds.c | 25 target/mips/cpu.c | 34 -- target/mips/sysemu/mips-qmp-cmds.c| 31 - target/ppc/cpu_init.c | 53 target/ppc/ppc-qmp-cmds.c | 31 + target/riscv/cpu.c| 1 + target/riscv/riscv-qmp-cmds.c | 13 +- target/sparc/cpu.c| 35 -- tests/qtest/cpu-plug-test.c | 2 +- qapi/meson.build | 1 - system/meson.build| 2 + 29 files changed, 515 insertions(+), 442 deletions(-) delete mode 100644 qapi/machine-common.json create mode 100644 system/cpu-qmp-cmds.c create mode 100644 system/cpu-qom-helpers.c -- 2.41.0
Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()
On Fri, Mar 15, 2024 at 01:20:49PM +0100, Cédric Le Goater wrote: > +static void qemu_savevm_wait_unplug(MigrationState *s, int state) One more trivial comment: I'd even consider dropping "state" altogether, as this should be the only state this function should be invoked. So we can perhaps assert it instead of passing it over? -- Peter Xu
[PATCH 07/12] tests/data/acpi/virt: Move ACPI tables under aarch64
Since virt is a common machine name across architectures like ARM64 and RISC-V, move existing ARM64 ACPI tables under aarch64 folder so that RISC-V tables can be added under riscv64 folder in future. Signed-off-by: Sunil V L --- tests/data/acpi/virt/{ => aarch64}/APIC | Bin .../data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/APIC.topology| Bin tests/data/acpi/virt/{ => aarch64}/DBG2 | Bin tests/data/acpi/virt/{ => aarch64}/DSDT | Bin .../data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/DSDT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/DSDT.pxb | Bin tests/data/acpi/virt/{ => aarch64}/DSDT.topology| Bin tests/data/acpi/virt/{ => aarch64}/FACP | Bin tests/data/acpi/virt/{ => aarch64}/GTDT | Bin .../data/acpi/virt/{ => aarch64}/HMAT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/IORT | Bin tests/data/acpi/virt/{ => aarch64}/MCFG | Bin tests/data/acpi/virt/{ => aarch64}/NFIT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/PPTT | Bin .../data/acpi/virt/{ => aarch64}/PPTT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/PPTT.topology| Bin tests/data/acpi/virt/{ => aarch64}/SLIT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/SPCR | Bin .../data/acpi/virt/{ => aarch64}/SRAT.acpihmatvirt | Bin tests/data/acpi/virt/{ => aarch64}/SRAT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/SRAT.numamem | Bin tests/data/acpi/virt/{ => aarch64}/SSDT.memhp | Bin tests/data/acpi/virt/{ => aarch64}/VIOT | Bin 25 files changed, 0 insertions(+), 0 deletions(-) rename tests/data/acpi/virt/{ => aarch64}/APIC (100%) rename tests/data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/APIC.topology (100%) rename tests/data/acpi/virt/{ => aarch64}/DBG2 (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.pxb (100%) rename tests/data/acpi/virt/{ => aarch64}/DSDT.topology (100%) rename tests/data/acpi/virt/{ => aarch64}/FACP (100%) rename tests/data/acpi/virt/{ => aarch64}/GTDT (100%) rename tests/data/acpi/virt/{ => aarch64}/HMAT.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/IORT (100%) rename tests/data/acpi/virt/{ => aarch64}/MCFG (100%) rename tests/data/acpi/virt/{ => aarch64}/NFIT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/PPTT (100%) rename tests/data/acpi/virt/{ => aarch64}/PPTT.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/PPTT.topology (100%) rename tests/data/acpi/virt/{ => aarch64}/SLIT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/SPCR (100%) rename tests/data/acpi/virt/{ => aarch64}/SRAT.acpihmatvirt (100%) rename tests/data/acpi/virt/{ => aarch64}/SRAT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/SRAT.numamem (100%) rename tests/data/acpi/virt/{ => aarch64}/SSDT.memhp (100%) rename tests/data/acpi/virt/{ => aarch64}/VIOT (100%) diff --git a/tests/data/acpi/virt/APIC b/tests/data/acpi/virt/aarch64/APIC similarity index 100% rename from tests/data/acpi/virt/APIC rename to tests/data/acpi/virt/aarch64/APIC diff --git a/tests/data/acpi/virt/APIC.acpihmatvirt b/tests/data/acpi/virt/aarch64/APIC.acpihmatvirt similarity index 100% rename from tests/data/acpi/virt/APIC.acpihmatvirt rename to tests/data/acpi/virt/aarch64/APIC.acpihmatvirt diff --git a/tests/data/acpi/virt/APIC.topology b/tests/data/acpi/virt/aarch64/APIC.topology similarity index 100% rename from tests/data/acpi/virt/APIC.topology rename to tests/data/acpi/virt/aarch64/APIC.topology diff --git a/tests/data/acpi/virt/DBG2 b/tests/data/acpi/virt/aarch64/DBG2 similarity index 100% rename from tests/data/acpi/virt/DBG2 rename to tests/data/acpi/virt/aarch64/DBG2 diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/aarch64/DSDT similarity index 100% rename from tests/data/acpi/virt/DSDT rename to tests/data/acpi/virt/aarch64/DSDT diff --git a/tests/data/acpi/virt/DSDT.acpihmatvirt b/tests/data/acpi/virt/aarch64/DSDT.acpihmatvirt similarity index 100% rename from tests/data/acpi/virt/DSDT.acpihmatvirt rename to tests/data/acpi/virt/aarch64/DSDT.acpihmatvirt diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/aarch64/DSDT.memhp similarity index 100% rename from tests/data/acpi/virt/DSDT.memhp rename to tests/data/acpi/virt/aarch64/DSDT.memhp diff --git a/tests/data/acpi/virt/DSDT.pxb b/tests/data/acpi/virt/aarch64/DSDT.pxb similarity index 100% rename from tests/data/acpi/virt/DSDT.pxb rename to tests/data/acpi/virt/aarch64/DSDT.pxb diff --git a/tests/data/acpi/virt/DSDT.topology b/tests/data/acpi/virt/aarch64/DSDT.topology similarity index 100%
[PATCH-for-9.1 08/21] target/sparc: Make SPARC_CPU common to new SPARC32_CPU/SPARC64_CPU types
"target/foo/cpu-qom.h" can not use any target specific definitions. Currently "target/sparc/cpu-qom.h" defines TYPE_SPARC_CPU depending on the sparc(32)/sparc64 build type. This doesn't scale in a heterogeneous context where we need to access both types concurrently. In order to do that, introduce the new SPARC32_CPU / SPARC64_CPU types, both inheriting a common TYPE_SPARC_CPU base type. Keep the current CPU types registered in sparc_register_cpudef_type() as 32 or 64-bit, depending on the binary built. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland --- target/sparc/cpu-qom.h | 9 + target/sparc/cpu.c | 12 +++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/target/sparc/cpu-qom.h b/target/sparc/cpu-qom.h index a86331bd58..6ad283506e 100644 --- a/target/sparc/cpu-qom.h +++ b/target/sparc/cpu-qom.h @@ -22,14 +22,15 @@ #include "hw/core/cpu.h" -#ifdef TARGET_SPARC64 -#define TYPE_SPARC_CPU "sparc64-cpu" -#else #define TYPE_SPARC_CPU "sparc-cpu" -#endif +#define TYPE_SPARC32_CPU "sparc32-cpu" +#define TYPE_SPARC64_CPU "sparc64-cpu" OBJECT_DECLARE_CPU_TYPE(SPARCCPU, SPARCCPUClass, SPARC_CPU) +OBJECT_DECLARE_CPU_TYPE(SPARC32CPU, SPARCCPUClass, SPARC32_CPU) +OBJECT_DECLARE_CPU_TYPE(SPARC64CPU, SPARCCPUClass, SPARC64_CPU) + #define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU #define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 42b13ab63f..9e27e16b75 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -959,6 +959,12 @@ static const TypeInfo sparc_cpu_types[] = { .abstract = true, .class_size = sizeof(SPARCCPUClass), .class_init = sparc_cpu_class_init, +}, { +.name = TYPE_SPARC32_CPU, +.parent = TYPE_SPARC_CPU, +}, { +.name = TYPE_SPARC64_CPU, +.parent = TYPE_SPARC_CPU, } }; @@ -975,7 +981,11 @@ static void sparc_register_cpudef_type(const struct sparc_def_t *def) char *typename = sparc_cpu_type_name(def->name); TypeInfo ti = { .name = typename, -.parent = TYPE_SPARC_CPU, +#ifdef TARGET_SPARC64 +.parent = TYPE_SPARC64_CPU, +#else +.parent = TYPE_SPARC32_CPU, +#endif .class_init = sparc_cpu_cpudef_class_init, .class_data = (void *)def, }; -- 2.41.0
[RFC PATCH-for-9.1 17/21] target/riscv: Use QMP generic_query_cpu_definitions()
Expose riscv_cpu_add_definition() and use it as add_definition() handler, then use the QMP generic_query_cpu_definitions() method. Signed-off-by: Philippe Mathieu-Daudé --- target/riscv/cpu.h| 2 ++ target/riscv/cpu.c| 1 + target/riscv/riscv-qmp-cmds.c | 11 +++ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3b1a02b944..15fc287680 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -824,4 +824,6 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); uint8_t satp_mode_max_from_map(uint32_t map); const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit); +void riscv_cpu_add_definition(gpointer data, gpointer user_data); + #endif /* RISCV_CPU_H */ diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c160b9216b..2da9364335 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -2341,6 +2341,7 @@ static int64_t riscv_get_arch_id(CPUState *cs) #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps riscv_sysemu_ops = { +.add_definition = riscv_cpu_add_definition, .get_phys_page_debug = riscv_cpu_get_phys_page_debug, .write_elf64_note = riscv_cpu_write_elf64_note, .write_elf32_note = riscv_cpu_write_elf32_note, diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index d363dc318d..45adc90d3b 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-machine-target.h" +#include "qapi/commands-target-compat.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" #include "qapi/qobject-input-visitor.h" @@ -36,7 +37,7 @@ #include "cpu-qom.h" #include "cpu.h" -static void riscv_cpu_add_definition(gpointer data, gpointer user_data) +void riscv_cpu_add_definition(gpointer data, gpointer user_data) { ObjectClass *oc = data; CpuDefinitionInfoList **cpu_list = user_data; @@ -55,13 +56,7 @@ static void riscv_cpu_add_definition(gpointer data, gpointer user_data) CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list = object_class_get_list(TYPE_RISCV_CPU, false); - -g_slist_foreach(list, riscv_cpu_add_definition, &cpu_list); -g_slist_free(list); - -return cpu_list; +return generic_query_cpu_definitions(errp); } static void riscv_check_if_cpu_available(RISCVCPU *cpu, Error **errp) -- 2.41.0
[PATCH-for-9.1 06/21] target/i386: Make X86_CPU common to new I386_CPU / X86_64_CPU types
"target/foo/cpu-qom.h" can not use any target specific definitions. Currently "target/i386/cpu-qom.h" defines TYPE_X86_CPU depending on the i386/x86_64 build type. This doesn't scale in a heterogeneous context where we need to access both types concurrently. In order to do that, introduce the new I386_CPU / X86_64_CPU types, both inheriting a common TYPE_X86_CPU base type. Keep the current "base" and "max" CPU types as 32 or 64-bit, depending on the binary built. Adapt the cpu-plug-test, since the 'base' architecture is now common to both 32/64-bit x86 targets. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Richard Henderson --- target/i386/cpu-qom.h | 16 ++-- target/i386/cpu.c | 20 ++-- tests/qtest/cpu-plug-test.c | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index d4e216d000..de28d7ea20 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU x86 CPU + * QEMU x86 CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -22,14 +22,18 @@ #include "hw/core/cpu.h" -#ifdef TARGET_X86_64 -#define TYPE_X86_CPU "x86_64-cpu" -#else -#define TYPE_X86_CPU "i386-cpu" -#endif +#define TYPE_X86_CPU"x86-cpu" +#define TYPE_I386_CPU "i386-cpu" +#define TYPE_X86_64_CPU "x86_64-cpu" OBJECT_DECLARE_CPU_TYPE(X86CPU, X86CPUClass, X86_CPU) +OBJECT_DECLARE_CPU_TYPE(I386CPU, X86CPUClass, I386_CPU) +OBJECT_DECLARE_CPU_TYPE(X86_64CPU, X86CPUClass, X86_64_CPU) + +#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU +#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX) + #define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU #define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ebf555f50f..07f64c1ea5 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -8057,12 +8057,28 @@ static const TypeInfo x86_cpu_types[] = { .class_size = sizeof(X86CPUClass), .class_init = x86_cpu_common_class_init, }, { -.name = X86_CPU_TYPE_NAME("base"), +.name = TYPE_I386_CPU, .parent = TYPE_X86_CPU, +.abstract = true, +}, { +.name = TYPE_X86_64_CPU, +.parent = TYPE_X86_CPU, +.abstract = true, +}, { +.name = X86_CPU_TYPE_NAME("base"), +#ifdef TARGET_X86_64 +.parent = TYPE_X86_64_CPU, +#else +.parent = TYPE_I386_CPU, +#endif .class_init = x86_cpu_base_class_init, }, { .name = X86_CPU_TYPE_NAME("max"), -.parent = TYPE_X86_CPU, +#ifdef TARGET_X86_64 +.parent = TYPE_X86_64_CPU, +#else +.parent = TYPE_I386_CPU, +#endif .instance_init = max_x86_cpu_initfn, .class_init = max_x86_cpu_class_init, } diff --git a/tests/qtest/cpu-plug-test.c b/tests/qtest/cpu-plug-test.c index 7f5dd5f85a..97316d131f 100644 --- a/tests/qtest/cpu-plug-test.c +++ b/tests/qtest/cpu-plug-test.c @@ -90,7 +90,7 @@ static void add_pc_test_case(const char *mname) data->machine = g_strdup(mname); data->cpu_model = "Haswell"; /* 1.3+ theoretically */ data->device_model = g_strdup_printf("%s-%s-cpu", data->cpu_model, - qtest_get_arch()); + qtest_get_base_arch()); data->sockets = 1; data->cores = 3; data->threads = 2; -- 2.41.0
[PATCH-for-9.1 07/21] target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types
"target/foo/cpu-qom.h" can not use any target specific definitions. Currently "target/mips/cpu-qom.h" defines TYPE_MIPS_CPU depending on the mips(32)/mips64 build type. This doesn't scale in a heterogeneous context where we need to access both types concurrently. In order to do that, introduce the new MIPS32_CPU / MIPS64_CPU types, both inheriting a common TYPE_MIPS_CPU base type. Keep the current CPU types registered in mips_register_cpudef_type() as 32 or 64-bit, but instead of depending on the binary built being targeting 32/64-bit, check whether the CPU is 64-bit by looking at the CPU_MIPS64 bit. Signed-off-by: Philippe Mathieu-Daudé --- target/mips/cpu-qom.h | 13 +++-- target/mips/cpu.c | 11 ++- target/mips/sysemu/mips-qmp-cmds.c | 26 ++ 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h index 0eea2a2598..bf464f16b6 100644 --- a/target/mips/cpu-qom.h +++ b/target/mips/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU MIPS CPU + * QEMU MIPS CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -22,14 +22,15 @@ #include "hw/core/cpu.h" -#ifdef TARGET_MIPS64 -#define TYPE_MIPS_CPU "mips64-cpu" -#else -#define TYPE_MIPS_CPU "mips-cpu" -#endif +#define TYPE_MIPS_CPU "mips-cpu" +#define TYPE_MIPS32_CPU "mips32-cpu" +#define TYPE_MIPS64_CPU "mips64-cpu" OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU) +OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU) +OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU) + #define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX diff --git a/target/mips/cpu.c b/target/mips/cpu.c index c096d97fe3..f3ea6175f2 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -604,6 +604,14 @@ static const TypeInfo mips_cpu_types[] = { .abstract = true, .class_size = sizeof(MIPSCPUClass), .class_init = mips_cpu_class_init, +}, { +.name = TYPE_MIPS32_CPU, +.parent = TYPE_MIPS_CPU, +.abstract = true, +}, { +.name = TYPE_MIPS64_CPU, +.parent = TYPE_MIPS_CPU, +.abstract = true, } }; @@ -620,7 +628,8 @@ static void mips_register_cpudef_type(const struct mips_def_t *def) char *typename = mips_cpu_type_name(def->name); TypeInfo ti = { .name = typename, -.parent = TYPE_MIPS_CPU, +.parent = def->insn_flags & CPU_MIPS64 + ? TYPE_MIPS64_CPU : TYPE_MIPS32_CPU, .class_init = mips_cpu_cpudef_class_init, .class_data = (void *)def, }; diff --git a/target/mips/sysemu/mips-qmp-cmds.c b/target/mips/sysemu/mips-qmp-cmds.c index 7340ac70ba..329db3a028 100644 --- a/target/mips/sysemu/mips-qmp-cmds.c +++ b/target/mips/sysemu/mips-qmp-cmds.c @@ -8,31 +8,9 @@ #include "qemu/osdep.h" #include "qapi/qapi-commands-machine-target.h" -#include "cpu.h" - -static void mips_cpu_add_definition(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CpuDefinitionInfoList **cpu_list = user_data; -CpuDefinitionInfo *info; -const char *typename; - -typename = object_class_get_name(oc); -info = g_malloc0(sizeof(*info)); -info->name = cpu_model_from_type(typename); -info->q_typename = g_strdup(typename); - -QAPI_LIST_PREPEND(*cpu_list, info); -} +#include "qapi/commands-target-compat.h" CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { -CpuDefinitionInfoList *cpu_list = NULL; -GSList *list; - -list = object_class_get_list(TYPE_MIPS_CPU, false); -g_slist_foreach(list, mips_cpu_add_definition, &cpu_list); -g_slist_free(list); - -return cpu_list; +return generic_query_cpu_definitions(errp); } -- 2.41.0
[PATCH-for-9.1 03/21] target/ppc: Declare CPU QOM types using DEFINE_TYPES() macro
When multiple QOM types are registered in the same file, it is simpler to use the the DEFINE_TYPES() macro. In particular because type array declared with such macro are easier to review. In few commits we are going to add more types, so replace the type_register_static() to ease further reviews. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20231013140116.255-16-phi...@linaro.org> --- target/ppc/cpu_init.c | 52 +++ 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 7e65f08147..d5e227a6fb 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7432,39 +7432,34 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) #endif /* CONFIG_TCG */ } -static const TypeInfo ppc_cpu_type_info = { -.name = TYPE_POWERPC_CPU, -.parent = TYPE_CPU, -.instance_size = sizeof(PowerPCCPU), -.instance_align = __alignof__(PowerPCCPU), -.instance_init = ppc_cpu_instance_init, -.instance_finalize = ppc_cpu_instance_finalize, -.abstract = true, -.class_size = sizeof(PowerPCCPUClass), -.class_init = ppc_cpu_class_init, +static const TypeInfo ppc_cpu_types[] = { +{ +.name = TYPE_POWERPC_CPU, +.parent = TYPE_CPU, +.abstract = true, +.instance_size = sizeof(PowerPCCPU), +.instance_align = __alignof__(PowerPCCPU), +.instance_init = ppc_cpu_instance_init, +.instance_finalize = ppc_cpu_instance_finalize, +.class_size = sizeof(PowerPCCPUClass), +.class_init = ppc_cpu_class_init, #ifndef CONFIG_USER_ONLY -.interfaces = (InterfaceInfo[]) { - { TYPE_INTERRUPT_STATS_PROVIDER }, - { } +.interfaces = (InterfaceInfo[]) { + { TYPE_INTERRUPT_STATS_PROVIDER }, + { } +}, +#endif +}, +#ifndef CONFIG_USER_ONLY +{ +.name = TYPE_PPC_VIRTUAL_HYPERVISOR, +.parent = TYPE_INTERFACE, +.class_size = sizeof(PPCVirtualHypervisorClass), }, #endif }; -#ifndef CONFIG_USER_ONLY -static const TypeInfo ppc_vhyp_type_info = { -.name = TYPE_PPC_VIRTUAL_HYPERVISOR, -.parent = TYPE_INTERFACE, -.class_size = sizeof(PPCVirtualHypervisorClass), -}; -#endif - -static void ppc_cpu_register_types(void) -{ -type_register_static(&ppc_cpu_type_info); -#ifndef CONFIG_USER_ONLY -type_register_static(&ppc_vhyp_type_info); -#endif -} +DEFINE_TYPES(ppc_cpu_types) void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) { @@ -7658,4 +7653,3 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) #undef RGPL #undef RFPL } -type_init(ppc_cpu_register_types) -- 2.41.0