From 7f7c8d0ce3630849a4df3d627b11de354fcb3bb0 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 4 Oct 2021 16:04:45 +0200 Subject: [PATCH 01/12] i386: docs: Briefly describe KVM PV features KVM PV features don't seem to be documented anywhere, in particular, the fact that some of the features are enabled by default and some are not can only be figured out from the code. Signed-off-by: Vitaly Kuznetsov Message-Id: <20211004140445.624875-1-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini --- docs/system/i386/kvm-pv.rst | 100 ++++++++++++++++++++++++++++++++++++ docs/system/target-i386.rst | 1 + 2 files changed, 101 insertions(+) create mode 100644 docs/system/i386/kvm-pv.rst diff --git a/docs/system/i386/kvm-pv.rst b/docs/system/i386/kvm-pv.rst new file mode 100644 index 0000000000..1e5a9923ef --- /dev/null +++ b/docs/system/i386/kvm-pv.rst @@ -0,0 +1,100 @@ +Paravirtualized KVM features +============================ + +Description +----------- + +In some cases when implementing hardware interfaces in software is slow, ``KVM`` +implements its own paravirtualized interfaces. + +Setup +----- + +Paravirtualized ``KVM`` features are represented as CPU flags. The following +features are enabled by default for any CPU model when ``KVM`` acceleration is +enabled: + +- ``kvmclock`` +- ``kvm-nopiodelay`` +- ``kvm-asyncpf`` +- ``kvm-steal-time`` +- ``kvm-pv-eoi`` +- ``kvmclock-stable-bit`` + +``kvm-msi-ext-dest-id`` feature is enabled by default in x2apic mode with split +irqchip (e.g. "-machine ...,kernel-irqchip=split -cpu ...,x2apic"). + +Note: when CPU model ``host`` is used, QEMU passes through all supported +paravirtualized ``KVM`` features to the guest. + +Existing features +----------------- + +``kvmclock`` + Expose a ``KVM`` specific paravirtualized clocksource to the guest. Supported + since Linux v2.6.26. + +``kvm-nopiodelay`` + The guest doesn't need to perform delays on PIO operations. Supported since + Linux v2.6.26. + +``kvm-mmu`` + This feature is deprecated. + +``kvm-asyncpf`` + Enable asynchronous page fault mechanism. Supported since Linux v2.6.38. + Note: since Linux v5.10 the feature is deprecated and not enabled by ``KVM``. + Use ``kvm-asyncpf-int`` instead. + +``kvm-steal-time`` + Enable stolen (when guest vCPU is not running) time accounting. Supported + since Linux v3.1. + +``kvm-pv-eoi`` + Enable paravirtualized end-of-interrupt signaling. Supported since Linux + v3.10. + +``kvm-pv-unhalt`` + Enable paravirtualized spinlocks support. Supported since Linux v3.12. + +``kvm-pv-tlb-flush`` + Enable paravirtualized TLB flush mechanism. Supported since Linux v4.16. + +``kvm-pv-ipi`` + Enable paravirtualized IPI mechanism. Supported since Linux v4.19. + +``kvm-poll-control`` + Enable host-side polling on HLT control from the guest. Supported since Linux + v5.10. + +``kvm-pv-sched-yield`` + Enable paravirtualized sched yield feature. Supported since Linux v5.10. + +``kvm-asyncpf-int`` + Enable interrupt based asynchronous page fault mechanism. Supported since Linux + v5.10. + +``kvm-msi-ext-dest-id`` + Support 'Extended Destination ID' for external interrupts. The feature allows + to use up to 32768 CPUs without IRQ remapping (but other limits may apply making + the number of supported vCPUs for a given configuration lower). Supported since + Linux v5.10. + +``kvmclock-stable-bit`` + Tell the guest that guest visible TSC value can be fully trusted for kvmclock + computations and no warps are expected. Supported since Linux v2.6.35. + +Supplementary features +---------------------- + +``kvm-pv-enforce-cpuid`` + Limit the supported paravirtualized feature set to the exposed features only. + Note, by default, ``KVM`` allows the guest to use all currently supported + paravirtualized features even when they were not announced in guest visible + CPUIDs. Supported since Linux v5.10. + + +Useful links +------------ + +Please refer to Documentation/virt/kvm in Linux for additional details. diff --git a/docs/system/target-i386.rst b/docs/system/target-i386.rst index 6a86d63863..4daa53c35d 100644 --- a/docs/system/target-i386.rst +++ b/docs/system/target-i386.rst @@ -26,6 +26,7 @@ Architectural features :maxdepth: 1 i386/cpu + i386/kvm-pv i386/sgx .. _pcsys_005freq: From cff03145ed3cec5c7bd542ea2e6b4458439e0bb0 Mon Sep 17 00:00:00 2001 From: Dov Murik Date: Thu, 30 Sep 2021 08:49:14 +0300 Subject: [PATCH 02/12] sev/i386: Introduce sev_add_kernel_loader_hashes for measured linux boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the sev_add_kernel_loader_hashes function to calculate the hashes of the kernel/initrd/cmdline and fill a designated OVMF encrypted hash table area. For this to work, OVMF must support an encrypted area to place the data which is advertised via a special GUID in the OVMF reset table. The hashes of each of the files is calculated (or the string in the case of the cmdline with trailing '\0' included). Each entry in the hashes table is GUID identified and since they're passed through the sev_encrypt_flash interface, the hashes will be accumulated by the AMD PSP measurement (SEV_LAUNCH_MEASURE). Co-developed-by: James Bottomley Signed-off-by: James Bottomley Signed-off-by: Dov Murik Reviewed-by: Daniel P. Berrangé Message-Id: <20210930054915.13252-2-dovmurik@linux.ibm.com> Signed-off-by: Paolo Bonzini --- target/i386/sev-stub.c | 5 ++ target/i386/sev.c | 137 +++++++++++++++++++++++++++++++++++++++++ target/i386/sev_i386.h | 12 ++++ 3 files changed, 154 insertions(+) diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c index 0227cb5177..d8e6583171 100644 --- a/target/i386/sev-stub.c +++ b/target/i386/sev-stub.c @@ -81,3 +81,8 @@ sev_get_attestation_report(const char *mnonce, Error **errp) error_setg(errp, "SEV is not available in this QEMU"); return NULL; } + +bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) +{ + g_assert_not_reached(); +} diff --git a/target/i386/sev.c b/target/i386/sev.c index fa7210473a..bcd9260fa4 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -23,6 +23,7 @@ #include "qemu/base64.h" #include "qemu/module.h" #include "qemu/uuid.h" +#include "crypto/hash.h" #include "sysemu/kvm.h" #include "sev_i386.h" #include "sysemu/sysemu.h" @@ -83,6 +84,32 @@ typedef struct __attribute__((__packed__)) SevInfoBlock { uint32_t reset_addr; } SevInfoBlock; +#define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454" +typedef struct QEMU_PACKED SevHashTableDescriptor { + /* SEV hash table area guest address */ + uint32_t base; + /* SEV hash table area size (in bytes) */ + uint32_t size; +} SevHashTableDescriptor; + +/* hard code sha256 digest size */ +#define HASH_SIZE 32 + +typedef struct QEMU_PACKED SevHashTableEntry { + QemuUUID guid; + uint16_t len; + uint8_t hash[HASH_SIZE]; +} SevHashTableEntry; + +typedef struct QEMU_PACKED SevHashTable { + QemuUUID guid; + uint16_t len; + SevHashTableEntry cmdline; + SevHashTableEntry initrd; + SevHashTableEntry kernel; + uint8_t padding[]; +} SevHashTable; + static SevGuestState *sev_guest; static Error *sev_mig_blocker; @@ -1071,6 +1098,116 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) return 0; } +static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +}; + +static const QemuUUID sev_kernel_entry_guid = { + .data = UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1, + 0x72, 0xd2, 0x04, 0x5b) +}; +static const QemuUUID sev_initrd_entry_guid = { + .data = UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2, + 0x91, 0x69, 0x78, 0x1d) +}; +static const QemuUUID sev_cmdline_entry_guid = { + .data = UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71, + 0x4d, 0x36, 0xab, 0x2a) +}; + +/* + * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page + * which is included in SEV's initial memory measurement. + */ +bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) +{ + uint8_t *data; + SevHashTableDescriptor *area; + SevHashTable *ht; + uint8_t cmdline_hash[HASH_SIZE]; + uint8_t initrd_hash[HASH_SIZE]; + uint8_t kernel_hash[HASH_SIZE]; + uint8_t *hashp; + size_t hash_len = HASH_SIZE; + int aligned_len; + + if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) { + error_setg(errp, "SEV: kernel specified but OVMF has no hash table guid"); + return false; + } + area = (SevHashTableDescriptor *)data; + + /* + * Calculate hash of kernel command-line with the terminating null byte. If + * the user doesn't supply a command-line via -append, the 1-byte "\0" will + * be used. + */ + hashp = cmdline_hash; + if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->cmdline_data, + ctx->cmdline_size, &hashp, &hash_len, errp) < 0) { + return false; + } + assert(hash_len == HASH_SIZE); + + /* + * Calculate hash of initrd. If the user doesn't supply an initrd via + * -initrd, an empty buffer will be used (ctx->initrd_size == 0). + */ + hashp = initrd_hash; + if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->initrd_data, + ctx->initrd_size, &hashp, &hash_len, errp) < 0) { + return false; + } + assert(hash_len == HASH_SIZE); + + /* Calculate hash of the kernel */ + hashp = kernel_hash; + struct iovec iov[2] = { + { .iov_base = ctx->setup_data, .iov_len = ctx->setup_size }, + { .iov_base = ctx->kernel_data, .iov_len = ctx->kernel_size } + }; + if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256, iov, ARRAY_SIZE(iov), + &hashp, &hash_len, errp) < 0) { + return false; + } + assert(hash_len == HASH_SIZE); + + /* + * Populate the hashes table in the guest's memory at the OVMF-designated + * area for the SEV hashes table + */ + ht = qemu_map_ram_ptr(NULL, area->base); + + ht->guid = sev_hash_table_header_guid; + ht->len = sizeof(*ht); + + ht->cmdline.guid = sev_cmdline_entry_guid; + ht->cmdline.len = sizeof(ht->cmdline); + memcpy(ht->cmdline.hash, cmdline_hash, sizeof(ht->cmdline.hash)); + + ht->initrd.guid = sev_initrd_entry_guid; + ht->initrd.len = sizeof(ht->initrd); + memcpy(ht->initrd.hash, initrd_hash, sizeof(ht->initrd.hash)); + + ht->kernel.guid = sev_kernel_entry_guid; + ht->kernel.len = sizeof(ht->kernel); + memcpy(ht->kernel.hash, kernel_hash, sizeof(ht->kernel.hash)); + + /* When calling sev_encrypt_flash, the length has to be 16 byte aligned */ + aligned_len = ROUND_UP(ht->len, 16); + if (aligned_len != ht->len) { + /* zero the excess data so the measurement can be reliably calculated */ + memset(ht->padding, 0, aligned_len - ht->len); + } + + if (sev_encrypt_flash((uint8_t *)ht, aligned_len, errp) < 0) { + return false; + } + + return true; +} + static void sev_register_types(void) { diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h index ae6d840478..2afe108069 100644 --- a/target/i386/sev_i386.h +++ b/target/i386/sev_i386.h @@ -28,6 +28,17 @@ #define SEV_POLICY_DOMAIN 0x10 #define SEV_POLICY_SEV 0x20 +typedef struct SevKernelLoaderContext { + char *setup_data; + size_t setup_size; + char *kernel_data; + size_t kernel_size; + char *initrd_data; + size_t initrd_size; + char *cmdline_data; + size_t cmdline_size; +} SevKernelLoaderContext; + extern bool sev_es_enabled(void); extern uint64_t sev_get_me_mask(void); extern SevInfo *sev_get_info(void); @@ -37,5 +48,6 @@ extern char *sev_get_launch_measurement(void); extern SevCapability *sev_get_capabilities(Error **errp); extern SevAttestationReport * sev_get_attestation_report(const char *mnonce, Error **errp); +extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); #endif From c0c2d319d6714517cc4e0332edf99f2fccaa9442 Mon Sep 17 00:00:00 2001 From: Dov Murik Date: Thu, 30 Sep 2021 08:49:15 +0300 Subject: [PATCH 03/12] x86/sev: generate SEV kernel loader hashes in x86_load_linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If SEV is enabled and a kernel is passed via -kernel, pass the hashes of kernel/initrd/cmdline in an encrypted guest page to OVMF for SEV measured boot. Co-developed-by: James Bottomley Signed-off-by: James Bottomley Signed-off-by: Dov Murik Reviewed-by: Daniel P. Berrangé Message-Id: <20210930054915.13252-3-dovmurik@linux.ibm.com> Signed-off-by: Paolo Bonzini --- hw/i386/x86.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 41ef9a84a9..0c7c054e3a 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -47,6 +47,7 @@ #include "hw/i386/fw_cfg.h" #include "hw/intc/i8259.h" #include "hw/rtc/mc146818rtc.h" +#include "target/i386/sev_i386.h" #include "hw/acpi/cpu_hotplug.h" #include "hw/irq.h" @@ -780,6 +781,7 @@ void x86_load_linux(X86MachineState *x86ms, const char *initrd_filename = machine->initrd_filename; const char *dtb_filename = machine->dtb; const char *kernel_cmdline = machine->kernel_cmdline; + SevKernelLoaderContext sev_load_ctx = {}; /* Align to 16 bytes as a paranoia measure */ cmdline_size = (strlen(kernel_cmdline) + 16) & ~15; @@ -926,6 +928,8 @@ void x86_load_linux(X86MachineState *x86ms, fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); + sev_load_ctx.cmdline_data = (char *)kernel_cmdline; + sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1; if (protocol >= 0x202) { stl_p(header + 0x228, cmdline_addr); @@ -1007,6 +1011,8 @@ void x86_load_linux(X86MachineState *x86ms, fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size); + sev_load_ctx.initrd_data = initrd_data; + sev_load_ctx.initrd_size = initrd_size; stl_p(header + 0x218, initrd_addr); stl_p(header + 0x21c, initrd_size); @@ -1065,15 +1071,32 @@ void x86_load_linux(X86MachineState *x86ms, load_image_size(dtb_filename, setup_data->data, dtb_size); } - memcpy(setup, header, MIN(sizeof(header), setup_size)); + /* + * If we're starting an encrypted VM, it will be OVMF based, which uses the + * efi stub for booting and doesn't require any values to be placed in the + * kernel header. We therefore don't update the header so the hash of the + * kernel on the other side of the fw_cfg interface matches the hash of the + * file the user passed in. + */ + if (!sev_enabled()) { + memcpy(setup, header, MIN(sizeof(header), setup_size)); + } fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); + sev_load_ctx.kernel_data = (char *)kernel; + sev_load_ctx.kernel_size = kernel_size; fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); + sev_load_ctx.setup_data = (char *)setup; + sev_load_ctx.setup_size = setup_size; + + if (sev_enabled()) { + sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal); + } option_rom[nb_option_roms].bootindex = 0; option_rom[nb_option_roms].name = "linuxboot.bin"; From 93ddefbc3c909bb6c3b76086f1dfc8ad98dd3725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20To=CC=82rres?= Date: Mon, 4 Oct 2021 10:46:37 +0200 Subject: [PATCH 04/12] hw/misc: applesmc: use host osk as default on macs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running on a Mac, QEMU is able to get the host OSK and use it as the default value for the AppleSMC device. The OSK query operation doesn't require administrator privileges and can be executed by any user on the system. This patch is based on open-source code from Apple, just like the implementation from VirtualBox. Apple: https://opensource.apple.com/source/IOKitUser/IOKitUser-647.6.13/pwr_mgt.subproj/IOPMLibPrivate.c https://opensource.apple.com/source/PowerManagement/PowerManagement-637.60.1/pmconfigd/PrivateLib.c VirtualBox: https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/EFI/DevSmc.cpp#L516 Signed-off-by: Pedro Tôrres --- hw/misc/applesmc.c | 192 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-) diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c index 1b9acaf1d3..cec247b5ee 100644 --- a/hw/misc/applesmc.c +++ b/hw/misc/applesmc.c @@ -38,6 +38,171 @@ #include "qemu/timer.h" #include "qom/object.h" +#if defined(__APPLE__) && defined(__MACH__) +#include + +enum { + kSMCSuccess = 0x00, + kSMCKeyNotFound = 0x84 +}; + +enum { + kSMCUserClientOpen = 0x00, + kSMCUserClientClose = 0x01, + kSMCHandleYPCEvent = 0x02, + kSMCReadKey = 0x05, + kSMCGetKeyInfo = 0x09 +}; + +typedef struct SMCVersion { + uint8_t major; + uint8_t minor; + uint8_t build; + uint8_t reserved; + uint16_t release; +} SMCVersion; + +typedef struct SMCPLimitData { + uint16_t version; + uint16_t length; + uint32_t cpuPLimit; + uint32_t gpuPLimit; + uint32_t memPLimit; +} SMCPLimitData; + +typedef struct SMCKeyInfoData { + IOByteCount dataSize; + uint32_t dataType; + uint8_t dataAttributes; +} SMCKeyInfoData; + +typedef struct { + uint32_t key; + SMCVersion vers; + SMCPLimitData pLimitData; + SMCKeyInfoData keyInfo; + uint8_t result; + uint8_t status; + uint8_t data8; + uint32_t data32; + uint8_t bytes[32]; +} SMCParamStruct; + +static IOReturn smc_call_struct_method(uint32_t selector, + SMCParamStruct *inputStruct, + SMCParamStruct *outputStruct) +{ + IOReturn ret; + + size_t inputStructCnt = sizeof(SMCParamStruct); + size_t outputStructCnt = sizeof(SMCParamStruct); + + io_service_t smcService = IO_OBJECT_NULL; + io_connect_t smcConnect = IO_OBJECT_NULL; + + smcService = IOServiceGetMatchingService(kIOMasterPortDefault, + IOServiceMatching("AppleSMC")); + if (smcService == IO_OBJECT_NULL) { + ret = kIOReturnNotFound; + goto exit; + } + + ret = IOServiceOpen(smcService, mach_task_self(), 1, &smcConnect); + if (ret != kIOReturnSuccess) { + smcConnect = IO_OBJECT_NULL; + goto exit; + } + if (smcConnect == IO_OBJECT_NULL) { + ret = kIOReturnError; + goto exit; + } + + ret = IOConnectCallMethod(smcConnect, kSMCUserClientOpen, + NULL, 0, NULL, 0, + NULL, NULL, NULL, NULL); + if (ret != kIOReturnSuccess) { + goto exit; + } + + ret = IOConnectCallStructMethod(smcConnect, selector, + inputStruct, inputStructCnt, + outputStruct, &outputStructCnt); + +exit: + if (smcConnect != IO_OBJECT_NULL) { + IOConnectCallMethod(smcConnect, kSMCUserClientClose, + NULL, 0, NULL, 0, NULL, + NULL, NULL, NULL); + IOServiceClose(smcConnect); + } + + return ret; +} + +static IOReturn smc_read_key(uint32_t key, + uint8_t *bytes, + IOByteCount *dataSize) +{ + IOReturn ret; + + SMCParamStruct inputStruct; + SMCParamStruct outputStruct; + + if (key == 0 || bytes == NULL) { + ret = kIOReturnCannotWire; + goto exit; + } + + /* determine key's data size */ + memset(&inputStruct, 0, sizeof(SMCParamStruct)); + inputStruct.data8 = kSMCGetKeyInfo; + inputStruct.key = key; + + memset(&outputStruct, 0, sizeof(SMCParamStruct)); + ret = smc_call_struct_method(kSMCHandleYPCEvent, &inputStruct, &outputStruct); + if (ret != kIOReturnSuccess) { + goto exit; + } + if (outputStruct.result == kSMCKeyNotFound) { + ret = kIOReturnNotFound; + goto exit; + } + if (outputStruct.result != kSMCSuccess) { + ret = kIOReturnInternalError; + goto exit; + } + + /* get key value */ + memset(&inputStruct, 0, sizeof(SMCParamStruct)); + inputStruct.data8 = kSMCReadKey; + inputStruct.key = key; + inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize; + + memset(&outputStruct, 0, sizeof(SMCParamStruct)); + ret = smc_call_struct_method(kSMCHandleYPCEvent, &inputStruct, &outputStruct); + if (ret != kIOReturnSuccess) { + goto exit; + } + if (outputStruct.result == kSMCKeyNotFound) { + ret = kIOReturnNotFound; + goto exit; + } + if (outputStruct.result != kSMCSuccess) { + ret = kIOReturnInternalError; + goto exit; + } + + memset(bytes, 0, *dataSize); + if (*dataSize > inputStruct.keyInfo.dataSize) { + *dataSize = inputStruct.keyInfo.dataSize; + } + memcpy(bytes, outputStruct.bytes, *dataSize); + +exit: + return ret; +} +#endif + /* #define DEBUG_SMC */ #define APPLESMC_DEFAULT_IOBASE 0x300 @@ -315,6 +480,7 @@ static const MemoryRegionOps applesmc_err_io_ops = { static void applesmc_isa_realize(DeviceState *dev, Error **errp) { AppleSMCState *s = APPLE_SMC(dev); + bool valid_key = false; memory_region_init_io(&s->io_data, OBJECT(s), &applesmc_data_io_ops, s, "applesmc-data", 1); @@ -331,7 +497,31 @@ static void applesmc_isa_realize(DeviceState *dev, Error **errp) isa_register_ioport(&s->parent_obj, &s->io_err, s->iobase + APPLESMC_ERR_PORT); - if (!s->osk || (strlen(s->osk) != 64)) { + if (s->osk) { + valid_key = strlen(s->osk) == 64; + } else { +#if defined(__APPLE__) && defined(__MACH__) + IOReturn ret; + IOByteCount size = 32; + + ret = smc_read_key('OSK0', (uint8_t *) default_osk, &size); + if (ret != kIOReturnSuccess) { + goto failure; + } + + ret = smc_read_key('OSK1', (uint8_t *) default_osk + size, &size); + if (ret != kIOReturnSuccess) { + goto failure; + } + + warn_report("Using AppleSMC with host key"); + valid_key = true; + s->osk = default_osk; +failure:; +#endif + } + + if (!valid_key) { warn_report("Using AppleSMC with invalid key"); s->osk = default_osk; } From 4dba27890844146d69e84916d024697947821655 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 29 Sep 2021 17:14:43 +0200 Subject: [PATCH 05/12] configure, meson: move CPU_CFLAGS out of QEMU_CFLAGS Flags that choose the target architecture, such as -m32 on x86, affect all invocations of the compiler driver, for example including options such as --print-search-dirs. To ensure that they are treated as such, place them in the cross file in the [binaries] section instead of including them in QEMU_CFLAGS. Signed-off-by: Paolo Bonzini --- configure | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/configure b/configure index b0b1a1cc25..1d3f099498 100755 --- a/configure +++ b/configure @@ -142,11 +142,11 @@ lines: ${BASH_LINENO[*]}" } do_cc() { - do_compiler "$cc" "$@" + do_compiler "$cc" $CPU_CFLAGS "$@" } do_cxx() { - do_compiler "$cxx" "$@" + do_compiler "$cxx" $CPU_CFLAGS "$@" } # Append $2 to the variable named $1, with space separation @@ -1688,7 +1688,6 @@ esac eval "cross_cc_${cpu}=\$cc" cross_cc_vars="$cross_cc_vars cross_cc_${cpu}" -QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS" # For user-mode emulation the host arch has to be one we explicitly # support, even if we're using TCI. @@ -5114,9 +5113,9 @@ if test "$skip_meson" = no; then echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross echo "[binaries]" >> $cross - echo "c = [$(meson_quote $cc)]" >> $cross - test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross - test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross + echo "c = [$(meson_quote $cc $CPU_CFLAGS)]" >> $cross + test -n "$cxx" && echo "cpp = [$(meson_quote $cxx $CPU_CFLAGS)]" >> $cross + test -n "$objcc" && echo "objc = [$(meson_quote $objcc $CPU_CFLAGS)]" >> $cross echo "ar = [$(meson_quote $ar)]" >> $cross echo "nm = [$(meson_quote $nm)]" >> $cross echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross From 3c158eba1e11e52dbd0e14fc8fd40ec80abca436 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 5 Oct 2021 04:07:50 -0400 Subject: [PATCH 06/12] migration: block-dirty-bitmap: add missing qemu_mutex_lock_iothread init_dirty_bitmap_migration assumes the iothread lock (BQL) to be held, but instead it isn't. Instead of adding the lock to qemu_savevm_state_setup(), follow the same pattern as the other ->save_setup callbacks and lock+unlock inside dirty_bitmap_save_setup(). Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Stefan Hajnoczi Message-Id: <20211005080751.3797161-2-eesposit@redhat.com> Signed-off-by: Paolo Bonzini --- migration/block-dirty-bitmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 35f5ef688d..9aba7d9c22 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -1215,7 +1215,10 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque) { DBMSaveState *s = &((DBMState *)opaque)->save; SaveBitmapState *dbms = NULL; + + qemu_mutex_lock_iothread(); if (init_dirty_bitmap_migration(s) < 0) { + qemu_mutex_unlock_iothread(); return -1; } @@ -1223,7 +1226,7 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque) send_bitmap_start(f, s, dbms); } qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS); - + qemu_mutex_unlock_iothread(); return 0; } From 68b88468f6a4144bf0217624fbb0ff6b0fa1d694 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 5 Oct 2021 04:07:51 -0400 Subject: [PATCH 07/12] migration: add missing qemu_mutex_lock_iothread in migration_completion qemu_savevm_state_complete_postcopy assumes the iothread lock (BQL) to be held, but instead it isn't. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Dr. David Alan Gilbert Message-Id: <20211005080751.3797161-3-eesposit@redhat.com> Signed-off-by: Paolo Bonzini --- migration/migration.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/migration/migration.c b/migration/migration.c index bb909781b7..6ac807ef3d 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3168,7 +3168,10 @@ static void migration_completion(MigrationState *s) } else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) { trace_migration_completion_postcopy_end(); + qemu_mutex_lock_iothread(); qemu_savevm_state_complete_postcopy(s->to_dst_file); + qemu_mutex_unlock_iothread(); + trace_migration_completion_postcopy_end_after_complete(); } else if (s->state == MIGRATION_STATUS_CANCELLING) { goto fail; From 69c4c5c1c47f5dac140eb6485c5281a9f145dcf3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 9 Mar 2021 14:50:00 +0100 Subject: [PATCH 08/12] meson: bump submodule to 0.59.2 The update to 0.57 has been delayed due to it causing warnings for some actual issues, but it brings in important bugfixes and new features. 0.58 also brings in a bugfix that is useful for modinfo. Important bugfixes: - 0.57: https://github.com/mesonbuild/meson/pull/7760, build: use PIE objects for non-PIC static libraries if b_pie=true - 0.57: https://github.com/mesonbuild/meson/pull/7900, thus avoiding unnecessary rebuilds after running meson. - 0.58.2: https://github.com/mesonbuild/meson/pull/8900, fixes for passing extract_objects() to custom_target (useful for modinfo) Features: - 0.57: the keyval module has now been stabilized - 0.57: env argument to custom_target (useful for hexagon) - 0.57: Feature parity between "meson test" and QEMU's TAP driver - 0.57: https://github.com/mesonbuild/meson/pull/8231, allows bringing back version numbers in the configuration summary - 0.59: Utility methods for feature objects Signed-off-by: Paolo Bonzini --- meson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson b/meson index 776acd2a80..b25d94e7c7 160000 --- a/meson +++ b/meson @@ -1 +1 @@ -Subproject commit 776acd2a805c9b42b4f0375150977df42130317f +Subproject commit b25d94e7c77fda05a7fdfe8afe562cf9760d69da From 654d6b0453aa6eb19af0d75b0f087a97a5776da7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 9 Feb 2021 14:59:26 +0100 Subject: [PATCH 09/12] meson: switch minimum meson version to 0.58.2, minimum recommended to 0.59.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Meson 0.58.2 does not need b_staticpic=$pie anymore, and has stabilized the keyval module. Remove the workaround and use a few replacements for features deprecated in the 0.57.0 release cycle. One feature that we would like to use is passing dependencies to summary. However, that was broken in 0.59.0 and 0.59.1. Therefore, use the embedded Meson if the host has anything older than 0.59.2, but allow --meson= to use 0.58.2. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini --- configure | 8 ++---- docs/meson.build | 14 ++++----- meson.build | 54 ++++++++++++++++------------------- plugins/meson.build | 4 +-- scripts/mtest2make.py | 7 ++--- tests/qapi-schema/meson.build | 4 +-- tests/qtest/meson.build | 2 +- tests/unit/meson.build | 2 +- trace/meson.build | 4 +-- 9 files changed, 44 insertions(+), 55 deletions(-) diff --git a/configure b/configure index 1d3f099498..877bf3d76a 100755 --- a/configure +++ b/configure @@ -1994,7 +1994,7 @@ python_version=$($python -c 'import sys; print("%d.%d.%d" % (sys.version_info[0] python="$python -B" if test -z "$meson"; then - if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.55.3; then + if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.2; then meson=meson elif test $git_submodules_action != 'ignore' ; then meson=git @@ -5163,10 +5163,6 @@ if test "$skip_meson" = no; then mv $cross config-meson.cross rm -rf meson-private meson-info meson-logs - unset staticpic - if ! version_ge "$($meson --version)" 0.56.0; then - staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi) - fi NINJA=$ninja $meson setup \ --prefix "$prefix" \ --libdir "$libdir" \ @@ -5186,7 +5182,6 @@ if test "$skip_meson" = no; then -Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \ -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \ -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \ - ${staticpic:+-Db_staticpic=$staticpic} \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ -Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \ @@ -5222,6 +5217,7 @@ else perl -i -ne ' s/^gettext = true$/gettext = auto/; s/^gettext = false$/gettext = disabled/; + /^b_staticpic/ && next; print;' meson-private/cmd_line.txt fi fi diff --git a/docs/meson.build b/docs/meson.build index cffe1ecf1d..be4dc30f39 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -37,14 +37,14 @@ endif if build_docs SPHINX_ARGS += ['-Dversion=' + meson.project_version(), '-Drelease=' + config_host['PKGVERSION']] - sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py', - meson.source_root() / 'docs/sphinx/hxtool.py', - meson.source_root() / 'docs/sphinx/kerneldoc.py', - meson.source_root() / 'docs/sphinx/kernellog.py', - meson.source_root() / 'docs/sphinx/qapidoc.py', - meson.source_root() / 'docs/sphinx/qmp_lexer.py', + sphinx_extn_depends = [ meson.current_source_dir() / 'sphinx/depfile.py', + meson.current_source_dir() / 'sphinx/hxtool.py', + meson.current_source_dir() / 'sphinx/kerneldoc.py', + meson.current_source_dir() / 'sphinx/kernellog.py', + meson.current_source_dir() / 'sphinx/qapidoc.py', + meson.current_source_dir() / 'sphinx/qmp_lexer.py', qapi_gen_depends ] - sphinx_template_files = [ meson.source_root() / 'docs/_templates/footer.html' ] + sphinx_template_files = [ meson.project_source_root() / 'docs/_templates/footer.html' ] have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT') diff --git a/meson.build b/meson.build index 60f4f45165..17e77fe4ef 100644 --- a/meson.build +++ b/meson.build @@ -1,14 +1,10 @@ -project('qemu', ['c'], meson_version: '>=0.55.0', - default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto'] + - (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []), - version: run_command('head', meson.source_root() / 'VERSION').stdout().strip()) +project('qemu', ['c'], meson_version: '>=0.58.2', + default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto', + 'b_staticpic=false'], + version: files('VERSION')) not_found = dependency('', required: false) -if meson.version().version_compare('>=0.56.0') - keyval = import('keyval') -else - keyval = import('unstable-keyval') -endif +keyval = import('keyval') ss = import('sourceset') fs = import('fs') @@ -1972,21 +1968,21 @@ genh += configure_file(output: 'config-host.h', configuration: config_host_data) hxtool = find_program('scripts/hxtool') shaderinclude = find_program('scripts/shaderinclude.pl') qapi_gen = find_program('scripts/qapi-gen.py') -qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py', - meson.source_root() / 'scripts/qapi/commands.py', - meson.source_root() / 'scripts/qapi/common.py', - meson.source_root() / 'scripts/qapi/error.py', - meson.source_root() / 'scripts/qapi/events.py', - meson.source_root() / 'scripts/qapi/expr.py', - meson.source_root() / 'scripts/qapi/gen.py', - meson.source_root() / 'scripts/qapi/introspect.py', - meson.source_root() / 'scripts/qapi/parser.py', - meson.source_root() / 'scripts/qapi/schema.py', - meson.source_root() / 'scripts/qapi/source.py', - meson.source_root() / 'scripts/qapi/types.py', - meson.source_root() / 'scripts/qapi/visit.py', - meson.source_root() / 'scripts/qapi/common.py', - meson.source_root() / 'scripts/qapi-gen.py' +qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', + meson.current_source_dir() / 'scripts/qapi/commands.py', + meson.current_source_dir() / 'scripts/qapi/common.py', + meson.current_source_dir() / 'scripts/qapi/error.py', + meson.current_source_dir() / 'scripts/qapi/events.py', + meson.current_source_dir() / 'scripts/qapi/expr.py', + meson.current_source_dir() / 'scripts/qapi/gen.py', + meson.current_source_dir() / 'scripts/qapi/introspect.py', + meson.current_source_dir() / 'scripts/qapi/parser.py', + meson.current_source_dir() / 'scripts/qapi/schema.py', + meson.current_source_dir() / 'scripts/qapi/source.py', + meson.current_source_dir() / 'scripts/qapi/types.py', + meson.current_source_dir() / 'scripts/qapi/visit.py', + meson.current_source_dir() / 'scripts/qapi/common.py', + meson.current_source_dir() / 'scripts/qapi-gen.py' ] tracetool = [ @@ -2635,14 +2631,14 @@ foreach target : target_dirs if target.endswith('-softmmu') execs = [{ 'name': 'qemu-system-' + target_name, - 'gui': false, + 'win_subsystem': 'console', 'sources': files('softmmu/main.c'), 'dependencies': [] }] if targetos == 'windows' and (sdl.found() or gtk.found()) execs += [{ 'name': 'qemu-system-' + target_name + 'w', - 'gui': true, + 'win_subsystem': 'windows', 'sources': files('softmmu/main.c'), 'dependencies': [] }] @@ -2651,7 +2647,7 @@ foreach target : target_dirs specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) execs += [{ 'name': 'qemu-fuzz-' + target_name, - 'gui': false, + 'win_subsystem': 'console', 'sources': specific_fuzz.sources(), 'dependencies': specific_fuzz.dependencies(), }] @@ -2659,7 +2655,7 @@ foreach target : target_dirs else execs = [{ 'name': 'qemu-' + target_name, - 'gui': false, + 'win_subsystem': 'console', 'sources': [], 'dependencies': [] }] @@ -2678,7 +2674,7 @@ foreach target : target_dirs link_language: link_language, link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), link_args: link_args, - gui_app: exe['gui']) + win_subsystem: exe['win_subsystem']) if targetos == 'darwin' icon = 'pc-bios/qemu.rsrc' diff --git a/plugins/meson.build b/plugins/meson.build index bfd5c9822a..aeb386ebae 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -2,9 +2,9 @@ plugin_ldflags = [] # Modules need more symbols than just those in plugins/qemu-plugins.symbols if not enable_modules if 'CONFIG_HAS_LD_DYNAMIC_LIST' in config_host - plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.build_root() / 'qemu-plugins-ld.symbols')] + plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.project_build_root() / 'qemu-plugins-ld.symbols')] elif 'CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST' in config_host - plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.build_root() / 'qemu-plugins-ld64.symbols')] + plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.project_build_root() / 'qemu-plugins-ld64.symbols')] endif endif diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py index ee072c0502..02c0453e67 100644 --- a/scripts/mtest2make.py +++ b/scripts/mtest2make.py @@ -60,11 +60,8 @@ def process_tests(test, targets, suites): if test['workdir'] is not None: print('.test.dir.%d := %s' % (i, shlex.quote(test['workdir']))) - if 'depends' in test: - deps = (targets.get(x, []) for x in test['depends']) - deps = itertools.chain.from_iterable(deps) - else: - deps = ['all'] + deps = (targets.get(x, []) for x in test['depends']) + deps = itertools.chain.from_iterable(deps) print('.test.name.%d := %s' % (i, test['name'])) print('.test.driver.%d := %s' % (i, driver)) diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build index 6187efbd58..df5acfd08b 100644 --- a/tests/qapi-schema/meson.build +++ b/tests/qapi-schema/meson.build @@ -1,5 +1,5 @@ test_env = environment() -test_env.set('PYTHONPATH', meson.source_root() / 'scripts') +test_env.set('PYTHONPATH', meson.project_source_root() / 'scripts') test_env.set('PYTHONIOENCODING', 'utf-8') schemas = [ @@ -248,7 +248,7 @@ if build_docs # clutter up the build dir with the cache. command: [SPHINX_ARGS, '-b', 'text', '-E', - '-c', meson.source_root() / 'docs', + '-c', meson.project_source_root() / 'docs', '-D', 'master_doc=doc-good', meson.current_source_dir(), meson.current_build_dir()]) diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 19444d4752..c9d8458062 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -275,7 +275,7 @@ foreach dir : target_dirs qtest_env.set('QTEST_QEMU_IMG', './qemu-img') test_deps += [qemu_img] endif - qtest_env.set('G_TEST_DBUS_DAEMON', meson.source_root() / 'tests/dbus-vmstate-daemon.sh') + qtest_env.set('G_TEST_DBUS_DAEMON', meson.project_source_root() / 'tests/dbus-vmstate-daemon.sh') qtest_env.set('QTEST_QEMU_BINARY', './qemu-system-' + target_base) if have_tools and have_vhost_user_blk_server qtest_env.set('QTEST_QEMU_STORAGE_DAEMON_BINARY', './storage-daemon/qemu-storage-daemon') diff --git a/tests/unit/meson.build b/tests/unit/meson.build index 5736d285b2..7c297d7e5c 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -43,7 +43,7 @@ tests = { 'test-keyval': [testqapi], 'test-logging': [], 'test-uuid': [], - 'ptimer-test': ['ptimer-test-stubs.c', meson.source_root() / 'hw/core/ptimer.c'], + 'ptimer-test': ['ptimer-test-stubs.c', meson.project_source_root() / 'hw/core/ptimer.c'], 'test-qapi-util': [], } diff --git a/trace/meson.build b/trace/meson.build index e401e7c415..b8f95de200 100644 --- a/trace/meson.build +++ b/trace/meson.build @@ -4,7 +4,7 @@ specific_ss.add(files('control-target.c')) trace_events_files = [] dtrace = find_program('dtrace', required: 'CONFIG_TRACE_DTRACE' in config_host) foreach dir : [ '.' ] + trace_events_subdirs - trace_events_file = meson.source_root() / dir / 'trace-events' + trace_events_file = meson.project_source_root() / dir / 'trace-events' trace_events_files += [ trace_events_file ] group_name = dir == '.' ? 'root' : dir.underscorify() group = '--group=' + group_name @@ -70,7 +70,7 @@ foreach d : [ ] gen = custom_target(d[0], output: d[0], - input: meson.source_root() / 'trace-events', + input: meson.project_source_root() / 'trace-events', command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ], depend_files: tracetool_depends) specific_ss.add(when: 'CONFIG_TCG', if_true: gen) From 0a11c44e891221a584bf06e75871dd1425555a65 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 9 Mar 2021 18:55:57 +0100 Subject: [PATCH 10/12] hexagon: use env keyword argument to pass PYTHONPATH This feature is new in meson 0.57 and allows getting rid of the "env" wrapper. Signed-off-by: Paolo Bonzini --- target/hexagon/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index 6fd9360b74..c6d858ffb2 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -156,7 +156,8 @@ dectree_generated = custom_target( 'dectree_generated.h.inc', output: 'dectree_generated.h.inc', depends: [iset_py], - command: ['env', 'PYTHONPATH=' + meson.current_build_dir(), files('dectree.py'), '@OUTPUT@'], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('dectree.py'), '@OUTPUT@'], ) hexagon_ss.add(dectree_generated) From 2796032a51c635464481a9212e941da53b3b3a61 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 18 May 2021 12:43:24 +0200 Subject: [PATCH 11/12] target/xtensa: list cores in a text file Avoid that leftover files affect the build; instead, use the same mechanism that was in place before the Meson transition of updating a file from import_core.sh. Starting with Meson 0.57, the file can be easily read from the filesystem module, so do that instead of using run_command. Signed-off-by: Paolo Bonzini --- target/xtensa/cores.list | 9 +++++++++ target/xtensa/import_core.sh | 3 +++ target/xtensa/meson.build | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 target/xtensa/cores.list diff --git a/target/xtensa/cores.list b/target/xtensa/cores.list new file mode 100644 index 0000000000..5772a00ab2 --- /dev/null +++ b/target/xtensa/cores.list @@ -0,0 +1,9 @@ +core-dc232b.c +core-dc233c.c +core-de212.c +core-de233_fpu.c +core-dsp3400.c +core-fsf.c +core-sample_controller.c +core-test_kc705_be.c +core-test_mmuhifi_c3.c diff --git a/target/xtensa/import_core.sh b/target/xtensa/import_core.sh index 396b264be9..df66d09393 100755 --- a/target/xtensa/import_core.sh +++ b/target/xtensa/import_core.sh @@ -66,3 +66,6 @@ static XtensaConfig $NAME __attribute__((unused)) = { REGISTER_CORE($NAME) EOF + +grep -qxf core-${NAME}.c "$BASE"/cores.list || \ + echo core-${NAME}.c >> "$BASE"/cores.list diff --git a/target/xtensa/meson.build b/target/xtensa/meson.build index 7c4efa6c62..20bbf9b335 100644 --- a/target/xtensa/meson.build +++ b/target/xtensa/meson.build @@ -1,7 +1,7 @@ xtensa_ss = ss.source_set() -xtensa_cores = run_command('sh', '-c', 'cd $MESON_SOURCE_ROOT/$MESON_SUBDIR ; ls -1 core-*.c') -xtensa_ss.add(files(xtensa_cores.stdout().strip().split('\n'))) +xtensa_cores = fs.read('cores.list') +xtensa_ss.add(files(xtensa_cores.strip().split('\n'))) xtensa_ss.add(files( 'cpu.c', From bb647c49b8f1f986d8171dd61db65e8a8d255be0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 3 Jun 2021 11:24:56 +0200 Subject: [PATCH 12/12] meson: show library versions in the summary Meson 0.57 allows passing external programs and dependency objects to summary(). Use this to show library versions and paths in the summary. Signed-off-by: Paolo Bonzini --- meson.build | 112 +++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/meson.build b/meson.build index 17e77fe4ef..7b596fdcd9 100644 --- a/meson.build +++ b/meson.build @@ -2859,13 +2859,13 @@ summary_info = {} summary_info += {'git': config_host['GIT']} summary_info += {'make': config_host['MAKE']} summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} -summary_info += {'sphinx-build': sphinx_build.found()} +summary_info += {'sphinx-build': sphinx_build} if config_host.has_key('HAVE_GDB_BIN') summary_info += {'gdb': config_host['HAVE_GDB_BIN']} endif summary_info += {'genisoimage': config_host['GENISOIMAGE']} if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT') - summary_info += {'wixl': wixl.found() ? wixl.full_path() : false} + summary_info += {'wixl': wixl} endif if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} @@ -2956,7 +2956,7 @@ if get_option('cfi') summary_info += {'CFI debug support': get_option('cfi_debug')} endif summary_info += {'strip binaries': get_option('strip')} -summary_info += {'sparse': sparse.found() ? sparse.full_path() : false} +summary_info += {'sparse': sparse} summary_info += {'mingw32 support': targetos == 'windows'} # snarf the cross-compilation information for tests @@ -3028,19 +3028,19 @@ if have_block summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')} summary_info += {'qed support': config_host.has_key('CONFIG_QED')} summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')} - summary_info += {'FUSE exports': fuse.found()} + summary_info += {'FUSE exports': fuse} endif summary(summary_info, bool_yn: true, section: 'Block layer support') # Crypto summary_info = {} summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']} -summary_info += {'GNUTLS support': gnutls.found()} -summary_info += {'GNUTLS crypto': gnutls_crypto.found()} -# TODO: add back version -summary_info += {'libgcrypt': gcrypt.found()} -# TODO: add back version -summary_info += {'nettle': nettle.found()} +summary_info += {'GNUTLS support': gnutls} +if gnutls.found() + summary_info += {' GNUTLS crypto': gnutls_crypto.found()} +endif +summary_info += {'libgcrypt': gcrypt} +summary_info += {'nettle': nettle} if nettle.found() summary_info += {' XTS': xts != 'private'} endif @@ -3052,76 +3052,72 @@ summary(summary_info, bool_yn: true, section: 'Crypto') # Libraries summary_info = {} if targetos == 'darwin' - summary_info += {'Cocoa support': cocoa.found()} + summary_info += {'Cocoa support': cocoa} endif -# TODO: add back version -summary_info += {'SDL support': sdl.found()} -summary_info += {'SDL image support': sdl_image.found()} -# TODO: add back version -summary_info += {'GTK support': gtk.found()} -summary_info += {'pixman': pixman.found()} -# TODO: add back version -summary_info += {'VTE support': vte.found()} -# TODO: add back version -summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt} -summary_info += {'libtasn1': tasn1.found()} -summary_info += {'PAM': pam.found()} -summary_info += {'iconv support': iconv.found()} -summary_info += {'curses support': curses.found()} -# TODO: add back version -summary_info += {'virgl support': virgl.found()} -summary_info += {'curl support': curl.found()} -summary_info += {'Multipath support': mpathpersist.found()} -summary_info += {'VNC support': vnc.found()} +summary_info += {'SDL support': sdl} +summary_info += {'SDL image support': sdl_image} +summary_info += {'GTK support': gtk} +summary_info += {'pixman': pixman} +summary_info += {'VTE support': vte} +summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp} +summary_info += {'libtasn1': tasn1} +summary_info += {'PAM': pam} +summary_info += {'iconv support': iconv} +summary_info += {'curses support': curses} +summary_info += {'virgl support': virgl} +summary_info += {'curl support': curl} +summary_info += {'Multipath support': mpathpersist} +summary_info += {'VNC support': vnc} if vnc.found() - summary_info += {'VNC SASL support': sasl.found()} - summary_info += {'VNC JPEG support': jpeg.found()} - summary_info += {'VNC PNG support': png.found()} + summary_info += {'VNC SASL support': sasl} + summary_info += {'VNC JPEG support': jpeg} + summary_info += {'VNC PNG support': png} endif -summary_info += {'brlapi support': brlapi.found()} +summary_info += {'brlapi support': brlapi} summary_info += {'vde support': config_host.has_key('CONFIG_VDE')} summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')} summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')} -summary_info += {'Linux io_uring support': linux_io_uring.found()} -summary_info += {'ATTR/XATTR support': libattr.found()} +summary_info += {'Linux io_uring support': linux_io_uring} +summary_info += {'ATTR/XATTR support': libattr} summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')} summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')} summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} -summary_info += {'libcap-ng support': libcap_ng.found()} -summary_info += {'bpf support': libbpf.found()} +summary_info += {'libcap-ng support': libcap_ng} +summary_info += {'bpf support': libbpf} # TODO: add back protocol and server version summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')} -summary_info += {'rbd support': rbd.found()} +summary_info += {'rbd support': rbd} summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')} -summary_info += {'smartcard support': cacard.found()} -summary_info += {'U2F support': u2f.found()} -summary_info += {'libusb': libusb.found()} -summary_info += {'usb net redir': usbredir.found()} +summary_info += {'smartcard support': cacard} +summary_info += {'U2F support': u2f} +summary_info += {'libusb': libusb} +summary_info += {'usb net redir': usbredir} summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} -summary_info += {'GBM': gbm.found()} -summary_info += {'libiscsi support': libiscsi.found()} -summary_info += {'libnfs support': libnfs.found()} +summary_info += {'GBM': gbm} +summary_info += {'libiscsi support': libiscsi} +summary_info += {'libnfs support': libnfs} if targetos == 'windows' if config_host.has_key('CONFIG_GUEST_AGENT') summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')} summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')} endif endif -summary_info += {'seccomp support': seccomp.found()} -summary_info += {'GlusterFS support': glusterfs.found()} +summary_info += {'seccomp support': seccomp} +summary_info += {'GlusterFS support': glusterfs} summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')} summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')} -summary_info += {'lzo support': lzo.found()} -summary_info += {'snappy support': snappy.found()} -summary_info += {'bzip2 support': libbzip2.found()} -summary_info += {'lzfse support': liblzfse.found()} -summary_info += {'zstd support': zstd.found()} +summary_info += {'lzo support': lzo} +summary_info += {'snappy support': snappy} +summary_info += {'bzip2 support': libbzip2} +summary_info += {'lzfse support': liblzfse} +summary_info += {'zstd support': zstd} summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')} -summary_info += {'libxml2': libxml2.found()} -summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt} -summary_info += {'libpmem support': libpmem.found()} -summary_info += {'libdaxctl support': libdaxctl.found()} -summary_info += {'libudev': libudev.found()} +summary_info += {'libxml2': libxml2} +summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone} +summary_info += {'libpmem support': libpmem} +summary_info += {'libdaxctl support': libdaxctl} +summary_info += {'libudev': libudev} +# Dummy dependency, keep .found() summary_info += {'FUSE lseek': fuse_lseek.found()} summary(summary_info, bool_yn: true, section: 'Dependencies')