From 44d9fab1f8a1d376741ff4505ec39f7f0a729ab2 Mon Sep 17 00:00:00 2001 From: Dorjoy Chowdhury Date: Sat, 9 Nov 2024 18:28:44 +0600 Subject: [PATCH 01/20] docs/nitro-enclave: Fix terminal commands formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dorjoy Chowdhury Reviewed-by: Alexander Graf Message-ID: <20241109122844.24057-1-dorjoychy111@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- docs/system/i386/nitro-enclave.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/system/i386/nitro-enclave.rst b/docs/system/i386/nitro-enclave.rst index 73e3edefe5..48eda5bd9e 100644 --- a/docs/system/i386/nitro-enclave.rst +++ b/docs/system/i386/nitro-enclave.rst @@ -48,13 +48,13 @@ Running a nitro-enclave VM First, run `vhost-device-vsock`__ (or a similar tool that supports vhost-user-vsock). The forward-cid option below with value 1 forwards all connections from the enclave VM to the host machine and the forward-listen (port numbers separated by '+') is used -for forwarding connections from the host machine to the enclave VM. - -__ https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock#using-the-vsock-backend +for forwarding connections from the host machine to the enclave VM:: $ vhost-device-vsock \ --vm guest-cid=4,forward-cid=1,forward-listen=9001+9002,socket=/tmp/vhost4.socket +__ https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock#using-the-vsock-backend + Now run the necessary applications on the host machine so that the nitro-enclave VM applications' vsock communication works. For example, the nitro-enclave VM's init process connects to CID 3 and sends a single byte hello heartbeat (0xB7) to let the @@ -65,7 +65,7 @@ the applications on the host machine that would typically be running in the pare VM for successful communication with the enclave VM. Then run the nitro-enclave VM using the following command where ``hello.eif`` is -an EIF file you would use to spawn a real AWS nitro enclave virtual machine: +an EIF file you would use to spawn a real AWS nitro enclave virtual machine:: $ qemu-system-x86_64 -M nitro-enclave,vsock=c,id=hello-world \ -kernel hello-world.eif -nographic -m 4G --enable-kvm -cpu host \ From 5b86ddd83d81add60a177804a0e5f2c373f61f82 Mon Sep 17 00:00:00 2001 From: Dorjoy Chowdhury Date: Sat, 9 Nov 2024 18:30:39 +0600 Subject: [PATCH 02/20] hw/core/eif: Use stateful qcrypto apis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were storing the pointers to buffers in a GList due to lack of stateful crypto apis and instead doing the final hash computation at the end after we had all the necessary buffers. Now that we have the stateful qcrypto apis available, we can instead update the hashes inline in the read_eif_* functions which makes the code much simpler. Signed-off-by: Dorjoy Chowdhury Reviewed-by: Alexander Graf Message-ID: <20241109123039.24180-1-dorjoychy111@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/eif.c | 202 ++++++++++++-------------------- hw/i386/nitro_enclave.c | 12 +- include/hw/i386/nitro_enclave.h | 16 +-- 3 files changed, 91 insertions(+), 139 deletions(-) diff --git a/hw/core/eif.c b/hw/core/eif.c index a7128b71ce..513caec6b4 100644 --- a/hw/core/eif.c +++ b/hw/core/eif.c @@ -187,10 +187,16 @@ static void safe_unlink(char *f) * Upon success, the caller is reponsible for unlinking and freeing *kernel_path */ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path, - uint8_t *kernel, uint32_t *crc, Error **errp) + QCryptoHash *hash0, QCryptoHash *hash1, + uint32_t *crc, Error **errp) { size_t got; FILE *tmp_file = NULL; + uint8_t *kernel = g_try_malloc(size); + if (!kernel) { + error_setg(errp, "Out of memory reading kernel section"); + goto cleanup; + } *kernel_path = NULL; if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) { @@ -218,6 +224,11 @@ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path, } *crc = crc32(*crc, kernel, size); + if (qcrypto_hash_update(hash0, (char *)kernel, size, errp) != 0 || + qcrypto_hash_update(hash1, (char *)kernel, size, errp) != 0) { + goto cleanup; + } + g_free(kernel); fclose(tmp_file); return true; @@ -229,10 +240,12 @@ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path, g_free(*kernel_path); *kernel_path = NULL; + g_free(kernel); return false; } static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline, + QCryptoHash *hash0, QCryptoHash *hash1, uint32_t *crc, Error **errp) { size_t got = fread(cmdline, 1, size, f); @@ -242,28 +255,47 @@ static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline, } *crc = crc32(*crc, (uint8_t *)cmdline, size); + if (qcrypto_hash_update(hash0, cmdline, size, errp) != 0 || + qcrypto_hash_update(hash1, cmdline, size, errp) != 0) { + return false; + } return true; } static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size, - uint8_t *ramdisk, uint32_t *crc, Error **errp) + QCryptoHash *hash0, QCryptoHash *h, uint32_t *crc, + Error **errp) { size_t got; + bool ret = false; + uint8_t *ramdisk = g_try_malloc(size); + if (!ramdisk) { + error_setg(errp, "Out of memory reading initrd section"); + goto cleanup; + } got = fread(ramdisk, 1, size, eif); if ((uint64_t) got != size) { error_setg(errp, "Failed to read EIF ramdisk section data"); - return false; + goto cleanup; } got = fwrite(ramdisk, 1, size, initrd); if ((uint64_t) got != size) { error_setg(errp, "Failed to write EIF ramdisk data to temporary file"); - return false; + goto cleanup; } *crc = crc32(*crc, ramdisk, size); - return true; + if (qcrypto_hash_update(hash0, (char *)ramdisk, size, errp) != 0 || + qcrypto_hash_update(h, (char *)ramdisk, size, errp) != 0) { + goto cleanup; + } + ret = true; + + cleanup: + g_free(ramdisk); + return ret; } static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size, @@ -391,34 +423,10 @@ static long get_file_size(FILE *f, Error **errp) return size; } -static bool get_SHA384_digest(GList *list, uint8_t *digest, Error **errp) +static bool get_SHA384_hash(QCryptoHash *h, uint8_t *hash, Error **errp) { - size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384; - size_t list_len = g_list_length(list); - struct iovec *iovec_list = g_new0(struct iovec, list_len); - bool ret = true; - GList *l; - int i; - - for (i = 0, l = list; l != NULL; l = l->next, i++) { - iovec_list[i] = *(struct iovec *) l->data; - } - - if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iovec_list, list_len, - &digest, &digest_len, errp) < 0) { - ret = false; - } - - g_free(iovec_list); - return ret; -} - -static void free_iovec(struct iovec *iov) -{ - if (iov) { - g_free(iov->iov_base); - g_free(iov); - } + size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384; + return qcrypto_hash_finalize_bytes(h, &hash, &hash_len, errp) == 0; } /* @@ -427,8 +435,8 @@ static void free_iovec(struct iovec *iov) */ bool read_eif_file(const char *eif_path, const char *machine_initrd, char **kernel_path, char **initrd_path, char **cmdline, - uint8_t *image_sha384, uint8_t *bootstrap_sha384, - uint8_t *app_sha384, uint8_t *fingerprint_sha384, + uint8_t *image_hash, uint8_t *bootstrap_hash, + uint8_t *app_hash, uint8_t *fingerprint_hash, bool *signature_found, Error **errp) { FILE *f = NULL; @@ -438,18 +446,29 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, uint32_t crc = 0; EifHeader eif_header; bool seen_sections[EIF_SECTION_MAX] = {false}; - /* kernel + ramdisks + cmdline sha384 hash */ - GList *iov_PCR0 = NULL; - /* kernel + boot ramdisk + cmdline sha384 hash */ - GList *iov_PCR1 = NULL; - /* application ramdisk(s) hash */ - GList *iov_PCR2 = NULL; - uint8_t *ptr = NULL; - struct iovec *iov_ptr = NULL; + /* kernel + ramdisks + cmdline SHA384 hash */ + g_autoptr(QCryptoHash) hash0 = NULL; + /* kernel + boot ramdisk + cmdline SHA384 hash */ + g_autoptr(QCryptoHash) hash1 = NULL; + /* application ramdisk(s) SHA384 hash */ + g_autoptr(QCryptoHash) hash2 = NULL; *signature_found = false; *kernel_path = *initrd_path = *cmdline = NULL; + hash0 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp); + if (!hash0) { + goto cleanup; + } + hash1 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp); + if (!hash1) { + goto cleanup; + } + hash2 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp); + if (!hash2) { + goto cleanup; + } + f = fopen(eif_path, "rb"); if (f == NULL) { error_setg_errno(errp, errno, "Failed to open %s", eif_path); @@ -517,21 +536,8 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, goto cleanup; } - ptr = g_try_malloc(hdr.section_size); - if (!ptr) { - error_setg(errp, "Out of memory reading kernel section"); - goto cleanup; - } - - iov_ptr = g_malloc(sizeof(struct iovec)); - iov_ptr->iov_base = ptr; - iov_ptr->iov_len = hdr.section_size; - - iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); - iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); - - if (!read_eif_kernel(f, hdr.section_size, kernel_path, ptr, &crc, - errp)) { + if (!read_eif_kernel(f, hdr.section_size, kernel_path, hash0, + hash1, &crc, errp)) { goto cleanup; } @@ -539,7 +545,6 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, case EIF_SECTION_CMDLINE: { uint64_t size; - uint8_t *cmdline_copy; if (seen_sections[EIF_SECTION_CMDLINE]) { error_setg(errp, "Invalid EIF image. More than 1 cmdline " "section"); @@ -551,33 +556,26 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, error_setg(errp, "Out of memory reading command line section"); goto cleanup; } - if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) { + if (!read_eif_cmdline(f, size, *cmdline, hash0, hash1, &crc, + errp)) { goto cleanup; } (*cmdline)[size] = '\0'; - /* - * We make a copy of '*cmdline' for putting it in iovecs so that - * we can easily free all the iovec entries later as we cannot - * free '*cmdline' which is used by the caller. - */ - cmdline_copy = g_memdup2(*cmdline, size); - - iov_ptr = g_malloc(sizeof(struct iovec)); - iov_ptr->iov_base = cmdline_copy; - iov_ptr->iov_len = size; - - iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); - iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); break; } case EIF_SECTION_RAMDISK: { + QCryptoHash *h = hash2; if (!seen_sections[EIF_SECTION_RAMDISK]) { /* * If this is the first time we are seeing a ramdisk section, - * we need to create the initrd temporary file. + * we need to: + * 1) hash it into bootstrap (hash1) instead of app (hash2) + * along with image (hash0) + * 2) create the initrd temporary file. */ + h = hash1; if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) { goto cleanup; } @@ -589,29 +587,7 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, } } - ptr = g_try_malloc(hdr.section_size); - if (!ptr) { - error_setg(errp, "Out of memory reading initrd section"); - goto cleanup; - } - - iov_ptr = g_malloc(sizeof(struct iovec)); - iov_ptr->iov_base = ptr; - iov_ptr->iov_len = hdr.section_size; - - iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); - /* - * If it's the first ramdisk, we need to hash it into bootstrap - * i.e., iov_PCR1, otherwise we need to hash it into app i.e., - * iov_PCR2. - */ - if (!seen_sections[EIF_SECTION_RAMDISK]) { - iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); - } else { - iov_PCR2 = g_list_append(iov_PCR2, iov_ptr); - } - - if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, ptr, + if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, hash0, h, &crc, errp)) { goto cleanup; } @@ -621,7 +597,7 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, case EIF_SECTION_SIGNATURE: *signature_found = true; if (!get_signature_fingerprint_sha384(f, hdr.section_size, - fingerprint_sha384, &crc, + fingerprint_hash, &crc, errp)) { goto cleanup; } @@ -692,52 +668,28 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, goto cleanup; } - ptr = g_try_malloc(machine_initrd_size); - if (!ptr) { - error_setg(errp, "Out of memory reading initrd file"); - goto cleanup; - } - - iov_ptr = g_malloc(sizeof(struct iovec)); - iov_ptr->iov_base = ptr; - iov_ptr->iov_len = machine_initrd_size; - - iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); - iov_PCR2 = g_list_append(iov_PCR2, iov_ptr); - if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f, - machine_initrd_size, ptr, &crc, errp)) { + machine_initrd_size, hash0, hash2, &crc, errp)) { goto cleanup; } } - if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) { + if (!get_SHA384_hash(hash0, image_hash, errp)) { goto cleanup; } - if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) { + if (!get_SHA384_hash(hash1, bootstrap_hash, errp)) { goto cleanup; } - if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) { + if (!get_SHA384_hash(hash2, app_hash, errp)) { goto cleanup; } - /* - * We only need to free iov_PCR0 entries because iov_PCR1 and - * iov_PCR2 iovec entries are subsets of iov_PCR0 iovec entries. - */ - g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec); - g_list_free(iov_PCR1); - g_list_free(iov_PCR2); fclose(f); fclose(initrd_path_f); safe_fclose(machine_initrd_f); return true; cleanup: - g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec); - g_list_free(iov_PCR1); - g_list_free(iov_PCR2); - safe_fclose(f); safe_fclose(initrd_path_f); safe_fclose(machine_initrd_f); diff --git a/hw/i386/nitro_enclave.c b/hw/i386/nitro_enclave.c index b6263ae127..acbbc06b71 100644 --- a/hw/i386/nitro_enclave.c +++ b/hw/i386/nitro_enclave.c @@ -117,13 +117,13 @@ static void nitro_enclave_machine_reset(MachineState *machine, ResetType type) memset(ne_state->vnsm->pcrs, 0, sizeof(ne_state->vnsm->pcrs)); /* PCR0 */ - ne_state->vnsm->extend_pcr(ne_state->vnsm, 0, ne_state->image_sha384, + ne_state->vnsm->extend_pcr(ne_state->vnsm, 0, ne_state->image_hash, QCRYPTO_HASH_DIGEST_LEN_SHA384); /* PCR1 */ - ne_state->vnsm->extend_pcr(ne_state->vnsm, 1, ne_state->bootstrap_sha384, + ne_state->vnsm->extend_pcr(ne_state->vnsm, 1, ne_state->bootstrap_hash, QCRYPTO_HASH_DIGEST_LEN_SHA384); /* PCR2 */ - ne_state->vnsm->extend_pcr(ne_state->vnsm, 2, ne_state->app_sha384, + ne_state->vnsm->extend_pcr(ne_state->vnsm, 2, ne_state->app_hash, QCRYPTO_HASH_DIGEST_LEN_SHA384); /* PCR3 */ if (ne_state->parent_role) { @@ -140,7 +140,7 @@ static void nitro_enclave_machine_reset(MachineState *machine, ResetType type) /* PCR8 */ if (ne_state->signature_found) { ne_state->vnsm->extend_pcr(ne_state->vnsm, 8, - ne_state->fingerprint_sha384, + ne_state->fingerprint_hash, QCRYPTO_HASH_DIGEST_LEN_SHA384); } @@ -173,8 +173,8 @@ static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg, if (!read_eif_file(machine->kernel_filename, machine->initrd_filename, &eif_kernel, &eif_initrd, &eif_cmdline, - nems->image_sha384, nems->bootstrap_sha384, - nems->app_sha384, nems->fingerprint_sha384, + nems->image_hash, nems->bootstrap_hash, + nems->app_hash, nems->fingerprint_hash, &(nems->signature_found), &err)) { error_report_err(err); exit(1); diff --git a/include/hw/i386/nitro_enclave.h b/include/hw/i386/nitro_enclave.h index b65875033c..885163ff64 100644 --- a/include/hw/i386/nitro_enclave.h +++ b/include/hw/i386/nitro_enclave.h @@ -44,14 +44,14 @@ struct NitroEnclaveMachineState { /* Machine state */ VirtIONSM *vnsm; - /* kernel + ramdisks + cmdline sha384 hash */ - uint8_t image_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384]; - /* kernel + boot ramdisk + cmdline sha384 hash */ - uint8_t bootstrap_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384]; - /* application ramdisk(s) hash */ - uint8_t app_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384]; - /* certificate fingerprint hash */ - uint8_t fingerprint_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* kernel + ramdisks + cmdline SHA384 hash */ + uint8_t image_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* kernel + boot ramdisk + cmdline SHA384 hash */ + uint8_t bootstrap_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* application ramdisk(s) SHA384 hash */ + uint8_t app_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* certificate fingerprint SHA384 hash */ + uint8_t fingerprint_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; bool signature_found; }; From d4ee9a113e36e90f76cfec892cb9aacd3cd11c17 Mon Sep 17 00:00:00 2001 From: Dorjoy Chowdhury Date: Sat, 9 Nov 2024 18:32:08 +0600 Subject: [PATCH 03/20] hw/virtio/virtio-nsm: Support string data for extendPCR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NSM device in AWS Nitro Enclaves supports extending with both bytestring and string data. Signed-off-by: Dorjoy Chowdhury Reviewed-by: Alexander Graf Message-ID: <20241109123208.24281-1-dorjoychy111@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/virtio/virtio-nsm.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/virtio/virtio-nsm.c b/hw/virtio/virtio-nsm.c index a3db8eef3e..6830fcfe17 100644 --- a/hw/virtio/virtio-nsm.c +++ b/hw/virtio/virtio-nsm.c @@ -444,7 +444,7 @@ static bool handle_describe_pcr(VirtIONSM *vnsm, struct iovec *request, * key = String("index"), * value = Uint8(pcr), * key = String("data"), - * value = Byte_String(data), + * value = Byte_String(data) || String(data), * } * } * } @@ -504,14 +504,21 @@ static enum NSMResponseTypes get_nsm_extend_pcr_req(uint8_t *req, size_t len, if (cbor_string_length(pair[i].key) == 4 && memcmp(str, "data", 4) == 0) { - if (!cbor_isa_bytestring(pair[i].value)) { + if (cbor_isa_bytestring(pair[i].value)) { + str = cbor_bytestring_handle(pair[i].value); + if (!str) { + goto cleanup; + } + nsm_req->data_len = cbor_bytestring_length(pair[i].value); + } else if (cbor_isa_string(pair[i].value)) { + str = cbor_string_handle(pair[i].value); + if (!str) { + goto cleanup; + } + nsm_req->data_len = cbor_string_length(pair[i].value); + } else { goto cleanup; } - str = cbor_bytestring_handle(pair[i].value); - if (!str) { - goto cleanup; - } - nsm_req->data_len = cbor_bytestring_length(pair[i].value); /* * nsm_req->data_len will be smaller than NSM_REQUEST_MAX_SIZE as * we already check for the max request size before processing From 37bae93ce54cfa1eeb8c51c9fa883ad781e0853b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 25 Nov 2024 14:07:25 +0100 Subject: [PATCH 04/20] hw/riscv/virt: Remove pointless GPEX_HOST() cast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to QOM-cast twice, since the intermediate value is not used. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Message-Id: <20241125140535.4526-7-philmd@linaro.org> --- hw/riscv/virt.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 45a8c4f819..2feb851f15 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1140,23 +1140,21 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, dev = qdev_new(TYPE_GPEX_HOST); /* Set GPEX object properties for the virt machine */ - object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_BASE, + object_property_set_uint(OBJECT(dev), PCI_HOST_ECAM_BASE, ecam_base, NULL); - object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_SIZE, + object_property_set_int(OBJECT(dev), PCI_HOST_ECAM_SIZE, ecam_size, NULL); - object_property_set_uint(OBJECT(GPEX_HOST(dev)), - PCI_HOST_BELOW_4G_MMIO_BASE, + object_property_set_uint(OBJECT(dev), PCI_HOST_BELOW_4G_MMIO_BASE, mmio_base, NULL); - object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_BELOW_4G_MMIO_SIZE, + object_property_set_int(OBJECT(dev), PCI_HOST_BELOW_4G_MMIO_SIZE, mmio_size, NULL); - object_property_set_uint(OBJECT(GPEX_HOST(dev)), - PCI_HOST_ABOVE_4G_MMIO_BASE, + object_property_set_uint(OBJECT(dev), PCI_HOST_ABOVE_4G_MMIO_BASE, high_mmio_base, NULL); - object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ABOVE_4G_MMIO_SIZE, + object_property_set_int(OBJECT(dev), PCI_HOST_ABOVE_4G_MMIO_SIZE, high_mmio_size, NULL); - object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_BASE, + object_property_set_uint(OBJECT(dev), PCI_HOST_PIO_BASE, pio_base, NULL); - object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_SIZE, + object_property_set_int(OBJECT(dev), PCI_HOST_PIO_SIZE, pio_size, NULL); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -1189,7 +1187,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i); } - GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(GPEX_HOST(dev))->bus; + GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(dev)->bus; return dev; } From e20a4425ca360b473182ef60e00319c07e3a8799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 18:48:21 +0100 Subject: [PATCH 05/20] hw/nvram/fw_cfg: Rename fw_cfg_add_[file]_from_generator() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fw_cfg_add_from_generator() is adding a 'file' entry, so rename as fw_cfg_add_file_from_generator() for clarity. Besides, we might introduce generators for other entry types. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241206181352.6836-2-philmd@linaro.org> --- hw/nvram/fw_cfg.c | 4 ++-- include/hw/nvram/fw_cfg.h | 6 +++--- system/vl.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index b644577734..fe3b86135a 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -1027,8 +1027,8 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, return NULL; } -bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename, - const char *gen_id, Error **errp) +bool fw_cfg_add_file_from_generator(FWCfgState *s, const char *filename, + const char *gen_id, Error **errp) { FWCfgDataGeneratorClass *klass; GByteArray *array; diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index fa42677619..14e68966c5 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -291,7 +291,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, size_t len); /** - * fw_cfg_add_from_generator: + * fw_cfg_add_file_from_generator: * @s: fw_cfg device being modified * @filename: name of new fw_cfg file item * @gen_id: name of object implementing FW_CFG_DATA_GENERATOR interface @@ -307,8 +307,8 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, * * Returns: %true on success, %false on error. */ -bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename, - const char *gen_id, Error **errp); +bool fw_cfg_add_file_from_generator(FWCfgState *s, const char *filename, + const char *gen_id, Error **errp); /** * fw_cfg_add_extra_pci_roots: diff --git a/system/vl.c b/system/vl.c index 2f855d83fb..f103532a9a 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1184,7 +1184,7 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */ buf = g_memdup(str, size); } else if (nonempty_str(gen_id)) { - if (!fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp)) { + if (!fw_cfg_add_file_from_generator(fw_cfg, name, gen_id, errp)) { return -1; } return 0; From 51680269fe08a739ac95dd651a11430b318b5bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 17:04:09 +0100 Subject: [PATCH 06/20] hw/nvram/fw_cfg: Pass QOM parent to fw_cfg_add_file_from_generator() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently fw_cfg_add_file_from_generator() is restricted to command line created objects which reside in the '/objects' QOM container. In order to extend to other types of containers, pass the QOM parent by argument. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241206181352.6836-3-philmd@linaro.org> --- hw/nvram/fw_cfg.c | 11 ++++++----- include/hw/nvram/fw_cfg.h | 10 ++++++---- system/vl.c | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index fe3b86135a..b94cd27bd8 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -1027,22 +1027,23 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, return NULL; } -bool fw_cfg_add_file_from_generator(FWCfgState *s, const char *filename, - const char *gen_id, Error **errp) +bool fw_cfg_add_file_from_generator(FWCfgState *s, + Object *parent, const char *part, + const char *filename, Error **errp) { FWCfgDataGeneratorClass *klass; GByteArray *array; Object *obj; gsize size; - obj = object_resolve_path_component(object_get_objects_root(), gen_id); + obj = object_resolve_path_component(parent, part); if (!obj) { - error_setg(errp, "Cannot find object ID '%s'", gen_id); + error_setg(errp, "Cannot find object ID '%s'", part); return false; } if (!object_dynamic_cast(obj, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE)) { error_setg(errp, "Object ID '%s' is not a '%s' subclass", - gen_id, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE); + part, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE); return false; } klass = FW_CFG_DATA_GENERATOR_GET_CLASS(obj); diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 14e68966c5..fcb06f18cc 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -294,11 +294,12 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, * fw_cfg_add_file_from_generator: * @s: fw_cfg device being modified * @filename: name of new fw_cfg file item - * @gen_id: name of object implementing FW_CFG_DATA_GENERATOR interface + * @part: name of object implementing FW_CFG_DATA_GENERATOR interface + * @parent: the object in which to resolve the @part * @errp: pointer to a NULL initialized error object * * Add a new NAMED fw_cfg item with the content generated from the - * @gen_id object. The data generated by the @gen_id object is copied + * @part object. The data generated by the @part object is copied * into the data structure of the fw_cfg device. * The next available (unused) selector key starting at FW_CFG_FILE_FIRST * will be used; also, a new entry will be added to the file directory @@ -307,8 +308,9 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, * * Returns: %true on success, %false on error. */ -bool fw_cfg_add_file_from_generator(FWCfgState *s, const char *filename, - const char *gen_id, Error **errp); +bool fw_cfg_add_file_from_generator(FWCfgState *s, + Object *parent, const char *part, + const char *filename, Error **errp); /** * fw_cfg_add_extra_pci_roots: diff --git a/system/vl.c b/system/vl.c index f103532a9a..4a370da624 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1184,7 +1184,8 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */ buf = g_memdup(str, size); } else if (nonempty_str(gen_id)) { - if (!fw_cfg_add_file_from_generator(fw_cfg, name, gen_id, errp)) { + if (!fw_cfg_add_file_from_generator(fw_cfg, object_get_objects_root(), + gen_id, name, errp)) { return -1; } return 0; From 4016adc74aee696bca025e546edfd2ae8f57863b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Dec 2024 14:22:02 +0100 Subject: [PATCH 07/20] hw/nvram/fw_cfg: Skip FW_CFG_DATA_GENERATOR when no data to generate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow the FW_CFG_DATA_GENERATOR interface get_data() handler to return NULL when there is nothing to generate. In that case fw_cfg_add_file_from_generator() will not add any item and return %true. Reported-by: Daniel P. Berrangé Reviewed-by: Daniel P. Berrangé Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241213133352.10915-4-philmd@linaro.org> --- hw/nvram/fw_cfg.c | 3 ++- include/hw/nvram/fw_cfg.h | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index b94cd27bd8..46c62c8f09 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -1031,6 +1031,7 @@ bool fw_cfg_add_file_from_generator(FWCfgState *s, Object *parent, const char *part, const char *filename, Error **errp) { + ERRP_GUARD(); FWCfgDataGeneratorClass *klass; GByteArray *array; Object *obj; @@ -1048,7 +1049,7 @@ bool fw_cfg_add_file_from_generator(FWCfgState *s, } klass = FW_CFG_DATA_GENERATOR_GET_CLASS(obj); array = klass->get_data(obj, errp); - if (!array) { + if (*errp || !array) { return false; } size = array->len; diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index fcb06f18cc..6089681f42 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -30,8 +30,9 @@ struct FWCfgDataGeneratorClass { * @obj: the object implementing this interface * @errp: pointer to a NULL-initialized error object * - * Returns: reference to a byte array containing the data on success, - * or NULL on error. + * Returns: A byte array containing data to add, or NULL without + * @errp set if no data is required, or NULL with @errp + * set on failure. * * The caller should release the reference when no longer * required. @@ -298,14 +299,16 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, * @parent: the object in which to resolve the @part * @errp: pointer to a NULL initialized error object * - * Add a new NAMED fw_cfg item with the content generated from the - * @part object. The data generated by the @part object is copied - * into the data structure of the fw_cfg device. + * If the @part object generates content, add a new NAMED fw_cfg item with it. + * The data generated by the @part object is copied into the data structure of + * the fw_cfg device. * The next available (unused) selector key starting at FW_CFG_FILE_FIRST * will be used; also, a new entry will be added to the file directory * structure residing at key value FW_CFG_FILE_DIR, containing the item name, * data size, and assigned selector key value. * + * If the @part object does not generate content, no fw_cfg item is added. + * * Returns: %true on success, %false on error. */ bool fw_cfg_add_file_from_generator(FWCfgState *s, From 59c5eea5c794ff3867504d2fba63bb535802027b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 17:41:40 +0100 Subject: [PATCH 08/20] hw/pci: Have PCI_BUS implement TYPE_FW_CFG_DATA_GENERATOR_INTERFACE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FW_CFG_DATA_GENERATOR interface allows any object to produce a blob of data consumable by the fw_cfg device. Implement that for PCI bus objects. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241213133352.10915-5-philmd@linaro.org> --- hw/pci/pci.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 1416ae202c..8844251ece 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -46,6 +46,7 @@ #include "hw/pci/msix.h" #include "hw/hotplug.h" #include "hw/boards.h" +#include "hw/nvram/fw_cfg.h" #include "qapi/error.h" #include "qemu/cutils.h" #include "pci-internal.h" @@ -216,11 +217,41 @@ static uint16_t pcibus_numa_node(PCIBus *bus) return NUMA_NODE_UNASSIGNED; } +static GByteArray *pci_bus_fw_cfg_gen_data(Object *obj, Error **errp) +{ + PCIBus *bus = PCI_BUS(obj); + GByteArray *byte_array; + uint64_t extra_hosts = 0; + + if (!bus) { + return NULL; + } + + QLIST_FOREACH(bus, &bus->child, sibling) { + /* look for expander root buses */ + if (pci_bus_is_root(bus)) { + extra_hosts++; + } + } + + if (!extra_hosts) { + return NULL; + } + extra_hosts = cpu_to_le64(extra_hosts); + + byte_array = g_byte_array_new(); + g_byte_array_append(byte_array, + (const void *)&extra_hosts, sizeof(extra_hosts)); + + return byte_array; +} + static void pci_bus_class_init(ObjectClass *klass, void *data) { BusClass *k = BUS_CLASS(klass); PCIBusClass *pbc = PCI_BUS_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); + FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(klass); k->print_dev = pcibus_dev_print; k->get_dev_path = pcibus_get_dev_path; @@ -232,6 +263,8 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) pbc->bus_num = pcibus_num; pbc->numa_node = pcibus_numa_node; + + fwgc->get_data = pci_bus_fw_cfg_gen_data; } static const TypeInfo pci_bus_info = { @@ -240,6 +273,10 @@ static const TypeInfo pci_bus_info = { .instance_size = sizeof(PCIBus), .class_size = sizeof(PCIBusClass), .class_init = pci_bus_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE }, + { } + } }; static const TypeInfo cxl_interface_info = { From 14f1f86d5111ed2dae19ae15da81a98ea048017d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 17:50:47 +0100 Subject: [PATCH 09/20] hw/pci: Add pci_bus_add_fw_cfg_extra_pci_roots() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_bus_add_fw_cfg_extra_pci_roots() calls the fw_cfg API with PCI bus specific arguments. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241206181352.6836-5-philmd@linaro.org> --- hw/pci/pci.c | 16 ++++++++++++++++ include/hw/pci/pci.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 8844251ece..bf0a1840db 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -217,6 +217,22 @@ static uint16_t pcibus_numa_node(PCIBus *bus) return NUMA_NODE_UNASSIGNED; } +bool pci_bus_add_fw_cfg_extra_pci_roots(FWCfgState *fw_cfg, + PCIBus *bus, + Error **errp) +{ + Object *obj; + + if (!bus) { + return true; + } + obj = OBJECT(bus); + + return fw_cfg_add_file_from_generator(fw_cfg, obj->parent, + object_get_canonical_path_component(obj), + "etc/extra-pci-roots", errp); +} + static GByteArray *pci_bus_fw_cfg_gen_data(Object *obj, Error **errp) { PCIBus *bus = PCI_BUS(obj); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index c0717e3121..603c456c3a 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -297,6 +297,9 @@ int pci_bus_get_irq_level(PCIBus *bus, int irq_num); uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus); void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask); void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask); +bool pci_bus_add_fw_cfg_extra_pci_roots(FWCfgState *fw_cfg, + PCIBus *bus, + Error **errp); /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */ static inline int pci_swizzle(int slot, int pin) { From e5fd678a0d2489baa9af0c91408b93474836afcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 17:14:19 +0100 Subject: [PATCH 10/20] hw: Use pci_bus_add_fw_cfg_extra_pci_roots() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to remove fw_cfg_add_extra_pci_roots() which introduced PCI bus knowledge within the generic hw/nvram/fw_cfg.c file. Replace the calls by the pci_bus_add_fw_cfg_extra_pci_roots() which is a 1:1 equivalent, but using correct API. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241206181352.6836-6-philmd@linaro.org> --- hw/arm/virt.c | 3 ++- hw/hppa/machine.c | 2 +- hw/i386/pc.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3bd9dd0f86..333eaf67ea 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1750,7 +1750,8 @@ void virt_machine_done(Notifier *notifier, void *data) exit(1); } - fw_cfg_add_extra_pci_roots(vms->bus, vms->fw_cfg); + pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus, + &error_abort); virt_acpi_setup(vms); virt_build_smbios(vms); diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index a31dc32a9f..4e67335322 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -240,7 +240,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus, g_memdup2(qemu_version, sizeof(qemu_version)), sizeof(qemu_version)); - fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); + pci_bus_add_fw_cfg_extra_pci_roots(fw_cfg, pci_bus, &error_abort); return fw_cfg; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 99b9b105e2..92047ce8c9 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -631,7 +631,8 @@ void pc_machine_done(Notifier *notifier, void *data) /* set the number of CPUs */ x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); - fw_cfg_add_extra_pci_roots(pcms->pcibus, x86ms->fw_cfg); + pci_bus_add_fw_cfg_extra_pci_roots(x86ms->fw_cfg, pcms->pcibus, + &error_abort); acpi_setup(); if (x86ms->fw_cfg) { From 3a25075ecef85adca5ab5b4e2486955b9d7a23ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Dec 2024 18:10:20 +0100 Subject: [PATCH 11/20] hw/nvram/fw_cfg: Remove fw_cfg_add_extra_pci_roots() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that all uses of fw_cfg_add_extra_pci_roots() have been converted to the newer pci_bus_add_fw_cfg_extra_pci_roots(), we can remove that bogus method. hw/nvram/fw_cfg must stay generic. Device specific entries have to be implemented using TYPE_FW_CFG_DATA_GENERATOR_INTERFACE. This mostly reverts commit 0abd38885ac0fcdb08653922f339849cad387961 ("fw_cfg: Refactor extra pci roots addition"). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241206181352.6836-7-philmd@linaro.org> --- hw/nvram/fw_cfg.c | 23 ----------------------- include/hw/nvram/fw_cfg.h | 9 --------- 2 files changed, 32 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 46c62c8f09..97def3a88b 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -41,7 +41,6 @@ #include "qemu/cutils.h" #include "qapi/error.h" #include "hw/acpi/aml-build.h" -#include "hw/pci/pci_bus.h" #include "hw/loader.h" #define FW_CFG_FILE_SLOTS_DFLT 0x20 @@ -1058,28 +1057,6 @@ bool fw_cfg_add_file_from_generator(FWCfgState *s, return true; } -void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s) -{ - int extra_hosts = 0; - - if (!bus) { - return; - } - - QLIST_FOREACH(bus, &bus->child, sibling) { - /* look for expander root buses */ - if (pci_bus_is_root(bus)) { - extra_hosts++; - } - } - - if (extra_hosts && s) { - uint64_t *val = g_malloc(sizeof(*val)); - *val = cpu_to_le64(extra_hosts); - fw_cfg_add_file(s, "etc/extra-pci-roots", val, sizeof(*val)); - } -} - static void fw_cfg_machine_reset(void *opaque) { MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 6089681f42..c60361dc9e 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -315,15 +315,6 @@ bool fw_cfg_add_file_from_generator(FWCfgState *s, Object *parent, const char *part, const char *filename, Error **errp); -/** - * fw_cfg_add_extra_pci_roots: - * @bus: main pci root bus to be scanned from - * @s: fw_cfg device being modified - * - * Add a new fw_cfg item... - */ -void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s); - FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase, AddressSpace *dma_as); FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr); From b7bd67fb31d0c97f7b9a6f83d6c786cbee5c09b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 9 Dec 2024 10:06:35 +0000 Subject: [PATCH 12/20] hw/net/can: clean-up unnecessary includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The event_notifier, thread and socket includes look like copy and paste of standard headers. None of the canbus devices use chardev although some relied on chardev to bring in bitops and byte swapping headers. In this case include them directly. Signed-off-by: Alex Bennée Acked-by: Pavel Pisa Reviewed-by: Pierrick Bouvier Message-ID: <20241209100635.93243-1-alex.bennee@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- hw/net/can/can_kvaser_pci.c | 4 ---- hw/net/can/can_mioe3680_pci.c | 4 ---- hw/net/can/can_pcm3680_pci.c | 4 ---- hw/net/can/can_sja1000.c | 2 +- hw/net/can/ctucan_core.c | 3 ++- hw/net/can/ctucan_pci.c | 4 ---- 6 files changed, 3 insertions(+), 18 deletions(-) diff --git a/hw/net/can/can_kvaser_pci.c b/hw/net/can/can_kvaser_pci.c index 38434d3a04..9e363d532f 100644 --- a/hw/net/can/can_kvaser_pci.c +++ b/hw/net/can/can_kvaser_pci.c @@ -30,12 +30,8 @@ */ #include "qemu/osdep.h" -#include "qemu/event_notifier.h" #include "qemu/module.h" -#include "qemu/thread.h" -#include "qemu/sockets.h" #include "qapi/error.h" -#include "chardev/char.h" #include "hw/irq.h" #include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" diff --git a/hw/net/can/can_mioe3680_pci.c b/hw/net/can/can_mioe3680_pci.c index 21659b7afb..580f099e00 100644 --- a/hw/net/can/can_mioe3680_pci.c +++ b/hw/net/can/can_mioe3680_pci.c @@ -26,12 +26,8 @@ */ #include "qemu/osdep.h" -#include "qemu/event_notifier.h" #include "qemu/module.h" -#include "qemu/thread.h" -#include "qemu/sockets.h" #include "qapi/error.h" -#include "chardev/char.h" #include "hw/irq.h" #include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" diff --git a/hw/net/can/can_pcm3680_pci.c b/hw/net/can/can_pcm3680_pci.c index af21dc6855..3195b79954 100644 --- a/hw/net/can/can_pcm3680_pci.c +++ b/hw/net/can/can_pcm3680_pci.c @@ -26,12 +26,8 @@ */ #include "qemu/osdep.h" -#include "qemu/event_notifier.h" #include "qemu/module.h" -#include "qemu/thread.h" -#include "qemu/sockets.h" #include "qapi/error.h" -#include "chardev/char.h" #include "hw/irq.h" #include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c index 6694d7bfd8..5b6ba9df6c 100644 --- a/hw/net/can/can_sja1000.c +++ b/hw/net/can/can_sja1000.c @@ -27,7 +27,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" -#include "chardev/char.h" +#include "qemu/bitops.h" #include "hw/irq.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/can/ctucan_core.c b/hw/net/can/ctucan_core.c index 812b83e93e..4402d4cb1f 100644 --- a/hw/net/can/ctucan_core.c +++ b/hw/net/can/ctucan_core.c @@ -28,7 +28,8 @@ #include "qemu/osdep.h" #include "qemu/log.h" -#include "chardev/char.h" +#include "qemu/bswap.h" +#include "qemu/bitops.h" #include "hw/irq.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/can/ctucan_pci.c b/hw/net/can/ctucan_pci.c index 65f1f82303..a8c77b9194 100644 --- a/hw/net/can/ctucan_pci.c +++ b/hw/net/can/ctucan_pci.c @@ -27,12 +27,8 @@ */ #include "qemu/osdep.h" -#include "qemu/event_notifier.h" #include "qemu/module.h" -#include "qemu/thread.h" -#include "qemu/sockets.h" #include "qapi/error.h" -#include "chardev/char.h" #include "hw/irq.h" #include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" From bd8760dcfddc8337ba1ad57c72a04e19e803d03b Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sun, 10 Nov 2024 13:39:59 +1000 Subject: [PATCH 13/20] hw/usb/msd: Add status to usb_msd_packet_complete() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a convenience change that accepts a status when completing a packet. Signed-off-by: Nicholas Piggin Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20241110034000.379463-2-npiggin@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/dev-storage.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 341e505bd0..4f1e8b7f6c 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -177,7 +177,7 @@ static const USBDesc desc = { .str = desc_strings, }; -static void usb_msd_packet_complete(MSDState *s) +static void usb_msd_packet_complete(MSDState *s, int status) { USBPacket *p = s->packet; @@ -187,6 +187,7 @@ static void usb_msd_packet_complete(MSDState *s) * usb_packet_complete returns. */ trace_usb_msd_packet_complete(); + p->status = status; s->packet = NULL; usb_packet_complete(&s->dev, p); } @@ -196,8 +197,7 @@ static void usb_msd_fatal_error(MSDState *s) trace_usb_msd_fatal_error(); if (s->packet) { - s->packet->status = USB_RET_STALL; - usb_msd_packet_complete(s); + usb_msd_packet_complete(s, USB_RET_STALL); } /* @@ -255,8 +255,8 @@ void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) usb_msd_copy_data(s, p); p = s->packet; if (p && p->actual_length == p->iov.size) { - p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */ - usb_msd_packet_complete(s); + /* USB_RET_SUCCESS status clears previous ASYNC status */ + usb_msd_packet_complete(s, USB_RET_SUCCESS); } } } @@ -295,8 +295,8 @@ void usb_msd_command_complete(SCSIRequest *req, size_t resid) s->mode = USB_MSDM_CSW; } } - p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */ - usb_msd_packet_complete(s); + /* USB_RET_SUCCESS status clears previous ASYNC status */ + usb_msd_packet_complete(s, USB_RET_SUCCESS); } else if (s->data_len == 0) { s->mode = USB_MSDM_CSW; } @@ -332,8 +332,7 @@ void usb_msd_handle_reset(USBDevice *dev) assert(s->req == NULL); if (s->packet) { - s->packet->status = USB_RET_STALL; - usb_msd_packet_complete(s); + usb_msd_packet_complete(s, USB_RET_STALL); } memset(&s->csw, 0, sizeof(s->csw)); From 2a8c16e423818f35058eba65255af011e7b96031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 27 Nov 2024 10:51:34 +0100 Subject: [PATCH 14/20] hw/usb/hcd-xhci-nec: Remove unused XHCINecState::flags field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit b9599519a01 ("hw/usb/hcd-xhci: Remove XHCI_FLAG_SS_FIRST flag") remove the last use of XHCINecState::flags but neglected to remove it; do that now. Reported-by: Nicholas Piggin Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Message-Id: <20241127122812.89487-1-philmd@linaro.org> --- hw/usb/hcd-xhci-nec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/usb/hcd-xhci-nec.c b/hw/usb/hcd-xhci-nec.c index 0c063b3697..1a191fc737 100644 --- a/hw/usb/hcd-xhci-nec.c +++ b/hw/usb/hcd-xhci-nec.c @@ -30,10 +30,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XHCINecState, NEC_XHCI) struct XHCINecState { - /*< private >*/ XHCIPciState parent_obj; - /*< public >*/ - uint32_t flags; + uint32_t intrs; uint32_t slots; }; @@ -51,7 +49,6 @@ static void nec_xhci_instance_init(Object *obj) XHCIPciState *pci = XHCI_PCI(obj); XHCINecState *nec = NEC_XHCI(obj); - pci->xhci.flags = nec->flags; pci->xhci.numintrs = nec->intrs; pci->xhci.numslots = nec->slots; } From c0179ead952b80ccf0d9d741fc4f66b57ab1250d Mon Sep 17 00:00:00 2001 From: Phil Dennis-Jordan Date: Sun, 8 Dec 2024 20:16:45 +0100 Subject: [PATCH 15/20] hw/usb/hcd-xhci-pci: Indentation fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes number of spaces used for indentation on one line. Signed-off-by: Phil Dennis-Jordan Message-ID: <20241208191646.64857-6-phil@philjordan.eu> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/hcd-xhci-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c index a039f5778a..e110840c7a 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -94,7 +94,7 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id) PCIDevice *pci_dev = PCI_DEVICE(s); int intr; - for (intr = 0; intr < s->xhci.numintrs; intr++) { + for (intr = 0; intr < s->xhci.numintrs; intr++) { if (s->xhci.intr[intr].msix_used) { msix_vector_use(pci_dev, intr); } else { From 8a4989f526cae238d1cf044c62c847ed708c92c6 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 5 Dec 2024 12:44:53 +0100 Subject: [PATCH 16/20] hw/ide/ahci: Decouple from PCI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some adhoc profiling booting Linux VMs, it's observed that ahci_irq_lower() can be a hot path (10000+ triggers until login prompt appears). Even though the parent device never changes, this method re-determines whether the parent device is a PCI device or not using the rather expensive object_dynamic_cast() function. Avoid this overhead by pushing the interrupt handling to the parent device, essentially turning AHCIState into an "IP block". Note that this change also frees AHCIState from the PCI dependency which wasn't reflected in Kconfig. Reported-by: Peter Xu Inspired-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20241212110926.23548-2-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/ide/ahci-internal.h | 1 - hw/ide/ahci.c | 39 ++++----------------------------------- hw/ide/ich.c | 19 +++++++++++++++---- include/hw/ide/ahci-pci.h | 2 ++ include/hw/ide/ahci.h | 2 -- 5 files changed, 21 insertions(+), 42 deletions(-) diff --git a/hw/ide/ahci-internal.h b/hw/ide/ahci-internal.h index 7e63ea2310..a318f36811 100644 --- a/hw/ide/ahci-internal.h +++ b/hw/ide/ahci-internal.h @@ -25,7 +25,6 @@ #define HW_IDE_AHCI_INTERNAL_H #include "hw/ide/ahci.h" -#include "hw/pci/pci_device.h" #include "ide-internal.h" #define AHCI_MEM_BAR_SIZE 0x1000 diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 0eb24304ee..5836aa924b 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -23,8 +23,6 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/pci/msi.h" -#include "hw/pci/pci.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" @@ -34,8 +32,6 @@ #include "qemu/module.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" -#include "hw/ide/pci.h" -#include "hw/ide/ahci-pci.h" #include "hw/ide/ahci-sysbus.h" #include "ahci-internal.h" #include "ide-internal.h" @@ -179,34 +175,6 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset) return val; } -static void ahci_irq_raise(AHCIState *s) -{ - DeviceState *dev_state = s->container; - PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state), - TYPE_PCI_DEVICE); - - trace_ahci_irq_raise(s); - - if (pci_dev && msi_enabled(pci_dev)) { - msi_notify(pci_dev, 0); - } else { - qemu_irq_raise(s->irq); - } -} - -static void ahci_irq_lower(AHCIState *s) -{ - DeviceState *dev_state = s->container; - PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state), - TYPE_PCI_DEVICE); - - trace_ahci_irq_lower(s); - - if (!pci_dev || !msi_enabled(pci_dev)) { - qemu_irq_lower(s->irq); - } -} - static void ahci_check_irq(AHCIState *s) { int i; @@ -222,9 +190,11 @@ static void ahci_check_irq(AHCIState *s) trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus); if (s->control_regs.irqstatus && (s->control_regs.ghc & HOST_CTL_IRQ_EN)) { - ahci_irq_raise(s); + trace_ahci_irq_raise(s); + qemu_irq_raise(s->irq); } else { - ahci_irq_lower(s); + trace_ahci_irq_lower(s); + qemu_irq_lower(s->irq); } } @@ -1608,7 +1578,6 @@ static const IDEDMAOps ahci_dma_ops = { void ahci_init(AHCIState *s, DeviceState *qdev) { - s->container = qdev; /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s, "ahci", AHCI_MEM_BAR_SIZE); diff --git a/hw/ide/ich.c b/hw/ide/ich.c index b311450c12..c99a44df8e 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -61,7 +61,6 @@ */ #include "qemu/osdep.h" -#include "hw/irq.h" #include "hw/pci/msi.h" #include "hw/pci/pci.h" #include "migration/vmstate.h" @@ -91,6 +90,19 @@ static const VMStateDescription vmstate_ich9_ahci = { }, }; +static void pci_ich9_ahci_update_irq(void *opaque, int irq_num, int level) +{ + PCIDevice *pci_dev = opaque; + + if (msi_enabled(pci_dev)) { + if (level) { + msi_notify(pci_dev, 0); + } + } else { + pci_set_irq(pci_dev, level); + } +} + static void pci_ich9_reset(DeviceState *dev) { AHCIPCIState *d = ICH9_AHCI(dev); @@ -102,7 +114,9 @@ static void pci_ich9_ahci_init(Object *obj) { AHCIPCIState *d = ICH9_AHCI(obj); + qemu_init_irq(&d->irq, pci_ich9_ahci_update_irq, d, 0); ahci_init(&d->ahci, DEVICE(obj)); + d->ahci.irq = &d->irq; } static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp) @@ -125,8 +139,6 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp) /* XXX Software should program this register */ dev->config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */ - d->ahci.irq = pci_allocate_irq(dev); - pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO, &d->ahci.idp); pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY, @@ -161,7 +173,6 @@ static void pci_ich9_uninit(PCIDevice *dev) msi_uninit(dev); ahci_uninit(&d->ahci); - qemu_free_irq(d->ahci.irq); } static void ich_ahci_class_init(ObjectClass *klass, void *data) diff --git a/include/hw/ide/ahci-pci.h b/include/hw/ide/ahci-pci.h index c2ee616962..face1a9a4a 100644 --- a/include/hw/ide/ahci-pci.h +++ b/include/hw/ide/ahci-pci.h @@ -9,6 +9,7 @@ #include "qom/object.h" #include "hw/ide/ahci.h" #include "hw/pci/pci_device.h" +#include "hw/irq.h" #define TYPE_ICH9_AHCI "ich9-ahci" OBJECT_DECLARE_SIMPLE_TYPE(AHCIPCIState, ICH9_AHCI) @@ -17,6 +18,7 @@ struct AHCIPCIState { PCIDevice parent_obj; AHCIState ahci; + IRQState irq; }; #endif diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h index ba31e75ff9..ac0292c634 100644 --- a/include/hw/ide/ahci.h +++ b/include/hw/ide/ahci.h @@ -37,8 +37,6 @@ typedef struct AHCIControlRegs { } AHCIControlRegs; typedef struct AHCIState { - DeviceState *container; - AHCIDevice *dev; AHCIControlRegs control_regs; MemoryRegion mem; From 1b26146e898086cd85be22170e7988017b481bb0 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 5 Dec 2024 14:19:37 +0100 Subject: [PATCH 17/20] hw/ide/ahci: Extract TYPE_SYSBUS_AHCI into dedicated file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement in dedicated file, just like TYPE_ICH9_AHCI. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20241212110926.23548-3-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/Kconfig | 10 ++--- hw/ide/Kconfig | 4 ++ hw/ide/ahci-sysbus.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ hw/ide/ahci.c | 67 -------------------------------- hw/ide/meson.build | 1 + 5 files changed, 101 insertions(+), 72 deletions(-) create mode 100644 hw/ide/ahci-sysbus.c diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 1b25e73578..e779b5af95 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -71,7 +71,7 @@ config HIGHBANK depends on TCG && ARM select A9MPCORE select A15MPCORE - select AHCI + select AHCI_SYSBUS select ARM_TIMER # sp804 select ARM_V7M select PL011 if !HAVE_RUST # UART @@ -192,7 +192,7 @@ config SBSA_REF depends on TCG && AARCH64 imply PCI_DEVICES select DEVICE_TREE - select AHCI + select AHCI_SYSBUS select ARM_SMMUV3 select GPIO_KEY select PCI_EXPRESS @@ -319,7 +319,7 @@ config ARM_V7M config ALLWINNER_A10 bool - select AHCI + select AHCI_SYSBUS select ALLWINNER_A10_PIT select ALLWINNER_A10_PIC select ALLWINNER_A10_CCM @@ -352,7 +352,7 @@ config ALLWINNER_H3 config ALLWINNER_R40 bool default y if TCG && ARM - select AHCI + select AHCI_SYSBUS select ALLWINNER_SRAMC select ALLWINNER_A10_PIT select ALLWINNER_WDT @@ -422,7 +422,7 @@ config XLNX_ZYNQMP_ARM bool default y if PIXMAN depends on TCG && AARCH64 - select AHCI + select AHCI_SYSBUS select ARM_GIC select CADENCE select CPU_CLUSTER diff --git a/hw/ide/Kconfig b/hw/ide/Kconfig index 2e22b677da..b55507b836 100644 --- a/hw/ide/Kconfig +++ b/hw/ide/Kconfig @@ -54,6 +54,10 @@ config AHCI_ICH9 depends on PCI select AHCI +config AHCI_SYSBUS + bool + select AHCI + config IDE_SII3112 bool select IDE_PCI diff --git a/hw/ide/ahci-sysbus.c b/hw/ide/ahci-sysbus.c new file mode 100644 index 0000000000..d43db0923f --- /dev/null +++ b/hw/ide/ahci-sysbus.c @@ -0,0 +1,91 @@ +/* + * QEMU AHCI Emulation (MMIO-mapped devices) + * + * Copyright (c) 2010 qiaochong@loongson.cn + * Copyright (c) 2010 Roland Elek + * Copyright (c) 2010 Sebastian Herbszt + * Copyright (c) 2010 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "exec/address-spaces.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" + +#include "hw/ide/ahci-sysbus.h" +#include "ahci-internal.h" + +static const VMStateDescription vmstate_sysbus_ahci = { + .name = "sysbus-ahci", + .fields = (const VMStateField[]) { + VMSTATE_AHCI(ahci, SysbusAHCIState), + VMSTATE_END_OF_LIST() + }, +}; + +static void sysbus_ahci_reset(DeviceState *dev) +{ + SysbusAHCIState *s = SYSBUS_AHCI(dev); + + ahci_reset(&s->ahci); +} + +static void sysbus_ahci_init(Object *obj) +{ + SysbusAHCIState *s = SYSBUS_AHCI(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + ahci_init(&s->ahci, DEVICE(obj)); + + sysbus_init_mmio(sbd, &s->ahci.mem); + sysbus_init_irq(sbd, &s->ahci.irq); +} + +static void sysbus_ahci_realize(DeviceState *dev, Error **errp) +{ + SysbusAHCIState *s = SYSBUS_AHCI(dev); + + ahci_realize(&s->ahci, dev, &address_space_memory); +} + +static Property sysbus_ahci_properties[] = { + DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1), + DEFINE_PROP_END_OF_LIST(), +}; + +static void sysbus_ahci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = sysbus_ahci_realize; + dc->vmsd = &vmstate_sysbus_ahci; + device_class_set_props(dc, sysbus_ahci_properties); + device_class_set_legacy_reset(dc, sysbus_ahci_reset); + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo sysbus_ahci_types[] = { + { + .name = TYPE_SYSBUS_AHCI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SysbusAHCIState), + .instance_init = sysbus_ahci_init, + .class_init = sysbus_ahci_class_init, + }, +}; + +DEFINE_TYPES(sysbus_ahci_types) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 5836aa924b..c02357735e 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -23,16 +23,13 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/main-loop.h" -#include "qemu/module.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" -#include "hw/ide/ahci-sysbus.h" #include "ahci-internal.h" #include "ide-internal.h" @@ -1803,70 +1800,6 @@ const VMStateDescription vmstate_ahci = { }, }; -static const VMStateDescription vmstate_sysbus_ahci = { - .name = "sysbus-ahci", - .fields = (const VMStateField[]) { - VMSTATE_AHCI(ahci, SysbusAHCIState), - VMSTATE_END_OF_LIST() - }, -}; - -static void sysbus_ahci_reset(DeviceState *dev) -{ - SysbusAHCIState *s = SYSBUS_AHCI(dev); - - ahci_reset(&s->ahci); -} - -static void sysbus_ahci_init(Object *obj) -{ - SysbusAHCIState *s = SYSBUS_AHCI(obj); - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - - ahci_init(&s->ahci, DEVICE(obj)); - - sysbus_init_mmio(sbd, &s->ahci.mem); - sysbus_init_irq(sbd, &s->ahci.irq); -} - -static void sysbus_ahci_realize(DeviceState *dev, Error **errp) -{ - SysbusAHCIState *s = SYSBUS_AHCI(dev); - - ahci_realize(&s->ahci, dev, &address_space_memory); -} - -static Property sysbus_ahci_properties[] = { - DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1), - DEFINE_PROP_END_OF_LIST(), -}; - -static void sysbus_ahci_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = sysbus_ahci_realize; - dc->vmsd = &vmstate_sysbus_ahci; - device_class_set_props(dc, sysbus_ahci_properties); - device_class_set_legacy_reset(dc, sysbus_ahci_reset); - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo sysbus_ahci_info = { - .name = TYPE_SYSBUS_AHCI, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SysbusAHCIState), - .instance_init = sysbus_ahci_init, - .class_init = sysbus_ahci_class_init, -}; - -static void sysbus_ahci_register_types(void) -{ - type_register_static(&sysbus_ahci_info); -} - -type_init(sysbus_ahci_register_types) - void ahci_ide_create_devs(AHCIState *ahci, DriveInfo **hd) { int i; diff --git a/hw/ide/meson.build b/hw/ide/meson.build index 90ea861423..ddd7066040 100644 --- a/hw/ide/meson.build +++ b/hw/ide/meson.build @@ -1,5 +1,6 @@ system_ss.add(when: 'CONFIG_AHCI', if_true: files('ahci.c')) system_ss.add(when: 'CONFIG_AHCI_ICH9', if_true: files('ich.c')) +system_ss.add(when: 'CONFIG_AHCI_SYSBUS', if_true: files('ahci-sysbus.c')) system_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('ahci-allwinner.c')) system_ss.add(when: 'CONFIG_IDE_BUS', if_true: files('ide-bus.c')) system_ss.add(when: 'CONFIG_IDE_CF', if_true: files('cf.c')) From 50e2b701876c087e14b1e7cabb2ffaa51008e174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Dec 2024 23:48:36 +0100 Subject: [PATCH 18/20] hw/mips: Include missing 'exec/tswap.h' header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some files indirectly get "exec/tswap.h" declarations via "exec/cpu-all.h". Include it directly to be able to remove the former from the latter, otherwise we get: hw/mips/malta.c:674:22: error: call to undeclared function 'tswap32'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 674 | tswap32((1 << 31) /* ConfigEn */ | ^ hw/mips/fuloong2e.c:89:23: error: call to undeclared function 'tswap32'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 89 | prom_buf[index] = tswap32(ENVP_VADDR + table_addr); | ^ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20241211230357.97036-7-philmd@linaro.org> --- hw/mips/fuloong2e.c | 1 + hw/mips/malta.c | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 7fd8296ccb..904c10b90e 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -40,6 +40,7 @@ #include "sysemu/reset.h" #include "sysemu/sysemu.h" #include "qemu/error-report.h" +#include "exec/tswap.h" #define ENVP_PADDR 0x2000 #define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 198da5ba3d..834636dae5 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -28,6 +28,7 @@ #include "qemu/datadir.h" #include "qemu/cutils.h" #include "qemu/guest-random.h" +#include "exec/tswap.h" #include "hw/clock.h" #include "hw/southbridge/piix.h" #include "hw/isa/superio.h" From ccc76731aee7d3efb16a679fa5bf3cc3f57e9f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Dec 2024 23:42:49 +0100 Subject: [PATCH 19/20] hw/sh4/r2d: Include missing 'exec/tswap.h' header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit r2d.c indirectly get "exec/tswap.h" declarations via "exec/cpu-all.h". Include it directly to be able to remove the former from the latter, otherwise we get: hw/sh4/r2d.c:357:35: error: call to undeclared function 'tswap32'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 357 | boot_params.loader_type = tswap32(1); | ^ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20241211230357.97036-8-philmd@linaro.org> --- hw/sh4/r2d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 7eecd79fcc..e6cc156c23 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -43,6 +43,7 @@ #include "hw/loader.h" #include "hw/usb.h" #include "hw/block/flash.h" +#include "exec/tswap.h" #define FLASH_BASE 0x00000000 #define FLASH_SIZE (16 * MiB) From 456b247eeab067095b680fa4b0fec48137969593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Dec 2024 23:41:58 +0100 Subject: [PATCH 20/20] hw/xtensa: Include missing 'exec/tswap.h' header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some files indirectly get "exec/tswap.h" declarations via "exec/cpu-all.h". Include it directly to be able to remove the former from the latter, otherwise we get: hw/xtensa/bootparam.h:40:16: error: call to undeclared function 'tswap16'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 40 | .tag = tswap16(tag), | ^ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20241211230357.97036-9-philmd@linaro.org> --- hw/xtensa/bootparam.h | 1 + hw/xtensa/xtfpga.c | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/xtensa/bootparam.h b/hw/xtensa/bootparam.h index f57ff850bc..4418c78d5b 100644 --- a/hw/xtensa/bootparam.h +++ b/hw/xtensa/bootparam.h @@ -2,6 +2,7 @@ #define HW_XTENSA_BOOTPARAM_H #include "exec/cpu-common.h" +#include "exec/tswap.h" #define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/ #define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */ diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 398e6256e1..2e264c6198 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -35,6 +35,7 @@ #include "hw/qdev-properties.h" #include "elf.h" #include "exec/memory.h" +#include "exec/tswap.h" #include "hw/char/serial-mm.h" #include "net/net.h" #include "hw/sysbus.h"