[Qemu-devel] [PATCH v9 2/2] target: arm: Add support for VCPU event states
This patch extends the qemu-kvm state sync logic with support for KVM_GET/SET_VCPU_EVENTS, giving access to yet missing SError exception. And also it can support the exception state migration. The SError exception states include SError pending state and ESR value, the kvm_put/get_vcpu_events() will be called when set or get system registers. When do migration, if source machine has SError pending, QEMU will do this migration regardless whether the target machine supports to specify guest ESR value, because if target machine does not support that, it can also inject the SError with zero ESR value. Signed-off-by: Dongjiu Geng --- Change since v8: 1. Update the commit message Change since v7: 1. Change "pending" and "has_esr" from uint32_t to uint8_t for CPUARMState 2. Add error_report() in kvm_get_vcpu_events() Change since v6: 1. Add cover letter 2. Change name "cpu/ras" to "cpu/serror" 3. Add some comments and check the ioctl return value for kvm_put_vcpu_events() Change since v5: address Peter's comments: 1. Move the "struct serror" before the "end_reset_fields" in CPUARMState 2. Remove ARM_FEATURE_RAS_EXT and add a variable have_inject_serror_esr 3. Use the variable have_inject_serror_esr to track whether the kernel has state we need to migrate 4. Remove printf() in kvm_arch_put_registers() 5. ras_needed/vmstate_ras to serror_needed/vmstate_serror 6. Check to use "return env.serror.pending != 0" instead of "arm_feature(env, ARM_FEATURE_RAS_EXT)" in the ras_needed() Change since v4: 1. Rebase the code to latest --- target/arm/cpu.h | 7 ++ target/arm/kvm64.c | 69 target/arm/machine.c | 22 + 3 files changed, 98 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 62c36b4..034b035 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -530,6 +530,13 @@ typedef struct CPUARMState { */ } exception; +/* Information associated with an SError */ +struct { +uint8_t pending; +uint8_t has_esr; +uint64_t esr; +} serror; + /* Thumb-2 EE state. */ uint32_t teecr; uint32_t teehbr; diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index e0b8246..e8705e2 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -29,6 +29,7 @@ #include "hw/arm/arm.h" static bool have_guest_debug; +static bool have_inject_serror_esr; /* * Although the ARM implementation of hardware assisted debugging @@ -546,6 +547,10 @@ int kvm_arch_init_vcpu(CPUState *cs) kvm_arm_init_debug(cs); +/* Check whether userspace can specify guest syndrome value */ +have_inject_serror_esr = kvm_check_extension(cs->kvm_state, + KVM_CAP_ARM_INJECT_SERROR_ESR); + return kvm_arm_init_cpreg_list(cpu); } @@ -600,6 +605,60 @@ int kvm_arm_cpreg_level(uint64_t regidx) #define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) +static int kvm_put_vcpu_events(ARMCPU *cpu) +{ +CPUARMState *env = &cpu->env; +struct kvm_vcpu_events events = {}; +int ret; + +if (!kvm_has_vcpu_events()) { +return 0; +} + +memset(&events, 0, sizeof(events)); +events.exception.serror_pending = env->serror.pending; + +/* Inject SError to guest with specified syndrome if host kernel + * supports it, otherwise inject SError without syndrome. + */ +if (have_inject_serror_esr) { +events.exception.serror_has_esr = env->serror.has_esr; +events.exception.serror_esr = env->serror.esr; +} + +ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events); +if (ret) { +error_report("failed to put vcpu events"); +} + +return ret; +} + +static int kvm_get_vcpu_events(ARMCPU *cpu) +{ +CPUARMState *env = &cpu->env; +struct kvm_vcpu_events events; +int ret; + +if (!kvm_has_vcpu_events()) { +return 0; +} + +memset(&events, 0, sizeof(events)); +ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_VCPU_EVENTS, &events); + +if (ret) { +error_report("failed to get vcpu events"); +return ret; +} + +env->serror.pending = events.exception.serror_pending; +env->serror.has_esr = events.exception.serror_has_esr; +env->serror.esr = events.exception.serror_esr; + +return 0; +} + int kvm_arch_put_registers(CPUState *cs, int level) { struct kvm_one_reg reg; @@ -727,6 +786,11 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } +ret = kvm_put_vcpu_events(cpu); +if (ret) { +return ret; +} + if (!write_list_to_kvmstate(cpu, level)) { return EINVAL; } @@ -863,6 +927,11 @@ int kvm_arch_get_registers(CPUState *cs) } vfp_set_fpcr(env, fpr); +ret = kvm_get_vcpu_events(cpu); +if (ret) { +return ret; +} + if (!write_kvmstate_to_lis
[Qemu-devel] [PATCH v9 1/2] linux-headers: Update to kernel mainline commit 815f0ddb3
Update our kernel headers to mainline commit 815f0ddb346c196018d4d8f8f55c12b83da1de3f (include/linux/compiler*.h: make compiler-*.h mutually exclusive) Signed-off-by: Dongjiu Geng --- include/standard-headers/linux/input.h | 9 + linux-headers/asm-arm/kvm.h| 13 + linux-headers/asm-arm64/kvm.h | 13 + linux-headers/linux/kvm.h | 1 + 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h index 6d6128c..c0ad9fc 100644 --- a/include/standard-headers/linux/input.h +++ b/include/standard-headers/linux/input.h @@ -267,10 +267,11 @@ struct input_mask { /* * MT_TOOL types */ -#define MT_TOOL_FINGER 0 -#define MT_TOOL_PEN1 -#define MT_TOOL_PALM 2 -#define MT_TOOL_MAX2 +#define MT_TOOL_FINGER 0x00 +#define MT_TOOL_PEN0x01 +#define MT_TOOL_PALM 0x02 +#define MT_TOOL_DIAL 0x0a +#define MT_TOOL_MAX0x0f /* * Values describing the status of a force-feedback effect diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h index 72aa226..e1f8b74 100644 --- a/linux-headers/asm-arm/kvm.h +++ b/linux-headers/asm-arm/kvm.h @@ -27,6 +27,7 @@ #define __KVM_HAVE_GUEST_DEBUG #define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_READONLY_MEM +#define __KVM_HAVE_VCPU_EVENTS #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 @@ -125,6 +126,18 @@ struct kvm_sync_regs { struct kvm_arch_memory_slot { }; +/* for KVM_GET/SET_VCPU_EVENTS */ +struct kvm_vcpu_events { + struct { + __u8 serror_pending; + __u8 serror_has_esr; + /* Align it to 8 bytes */ + __u8 pad[6]; + __u64 serror_esr; + } exception; + __u32 reserved[12]; +}; + /* If you need to interpret the index values, here is the key: */ #define KVM_REG_ARM_COPROC_MASK0x0FFF #define KVM_REG_ARM_COPROC_SHIFT 16 diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 99cb9ad..e6a98c1 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -39,6 +39,7 @@ #define __KVM_HAVE_GUEST_DEBUG #define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_READONLY_MEM +#define __KVM_HAVE_VCPU_EVENTS #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 @@ -154,6 +155,18 @@ struct kvm_sync_regs { struct kvm_arch_memory_slot { }; +/* for KVM_GET/SET_VCPU_EVENTS */ +struct kvm_vcpu_events { + struct { + __u8 serror_pending; + __u8 serror_has_esr; + /* Align it to 8 bytes */ + __u8 pad[6]; + __u64 serror_esr; + } exception; + __u32 reserved[12]; +}; + /* If you need to interpret the index values, here is the key: */ #define KVM_REG_ARM_COPROC_MASK0x0FFF #define KVM_REG_ARM_COPROC_SHIFT 16 diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 6679072..bae1c89 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -951,6 +951,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_HYPERV_TLBFLUSH 155 #define KVM_CAP_S390_HPAGE_1M 156 #define KVM_CAP_NESTED_STATE 157 +#define KVM_CAP_ARM_INJECT_SERROR_ESR 158 #ifdef KVM_CAP_IRQ_ROUTING -- 1.8.3.1
[Qemu-devel] [PATCH v9 0/2] add support for VCPU event states
Support KVM_GET/SET_VCPU_EVENTS to get/set the SError exception state, and support the state migration. Now the VCPU event only includes the SError exception status, it can be extended if needed. When do migration, If source machine has serror pending, the target machine is also needed to pend this serror regardless of whether target machine can support to set the serror syndrome. Dongjiu Geng (2): linux-headers: Update to kernel mainline commit 815f0ddb3 target: arm: Add support for VCPU event states include/standard-headers/linux/input.h | 9 +++-- linux-headers/asm-arm/kvm.h| 13 +++ linux-headers/asm-arm64/kvm.h | 13 +++ linux-headers/linux/kvm.h | 1 + target/arm/cpu.h | 7 target/arm/kvm64.c | 69 ++ target/arm/machine.c | 22 +++ 7 files changed, 130 insertions(+), 4 deletions(-) -- 1.8.3.1
[Qemu-devel] [Bug 1792193] Re: AMD Athlon(tm) X2 Dual-Core QL-64 bug
I can't do bisect, but I have installed qemu version 3.0.50 (v3.0.0-614-g19b599f766-dirty) from git and this works fine. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1792193 Title: AMD Athlon(tm) X2 Dual-Core QL-64 bug Status in QEMU: New Bug description: I upgrade my qemu 2.12.0-2 => 3.0.0-1. After that I can't load virtual machine with "-cpu host" option. Full command line is qemu-system-x86_64 \ -monitor stdio \ -enable-kvm \ -cpu host \ -smp cpus=2 \ -m 1G \ -vga virtio \ -display gtk,gl=on \ -soundhw ac97 \ -drive file=/ehdd/qemu/arch_hw_12_08_2018/arch_shrinked.raw,format=raw,if=virtio I have Arch Linux on virtual machine. When I start QEMU, GRUB tries to load initial ramdisk and stops. System doesn't load. If I try to start virtual machine with "-cpu athlon" option then get the same bug. I downgrade back to qemu 2.12.0-2 and virtual machine works fine, system loads. My processor is AMD Athlon(tm) X2 Dual-Core QL-64. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1792193/+subscriptions
[Qemu-devel] [PATCH v2] qemu-img.c: add help for each command
Add the ability for the user to display help for a certain command. Example: qemu-img create --help What is printed is all the options available to this command and an example. Signed-off-by: John Arbuckle --- v2 changes: Removed block of string comparison code for each command. Added a help_func field to the img_cmd_t struct. Made strings longer than 80 characters wide. qemu-img.c | 659 +++-- 1 file changed, 558 insertions(+), 101 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 1acddf693c..7b9f6101b3 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -52,6 +52,7 @@ typedef struct img_cmd_t { const char *name; int (*handler)(int argc, char **argv); +void (*help_func)(void); } img_cmd_t; enum { @@ -76,11 +77,6 @@ typedef enum OutputFormat { /* Default to cache=writeback as data integrity is not important for qemu-img */ #define BDRV_DEFAULT_CACHE "writeback" -static void format_print(void *opaque, const char *name) -{ -printf(" %s", name); -} - static void QEMU_NORETURN GCC_FMT_ATTR(1, 2) error_exit(const char *fmt, ...) { va_list ap; @@ -105,102 +101,546 @@ static void QEMU_NORETURN unrecognized_option(const char *option) error_exit("unrecognized option '%s'", option); } -/* Please keep in synch with qemu-img.texi */ -static void QEMU_NORETURN help(void) +/* Prints an overview of available help options */ +static void help(void) { const char *help_msg = - QEMU_IMG_VERSION - "usage: qemu-img [standard options] command [command options]\n" - "QEMU disk image utility\n" - "\n" - "'-h', '--help' display this help and exit\n" - "'-V', '--version'output version information and exit\n" - "'-T', '--trace' [[enable=]][,events=][,file=]\n" - " specify tracing options\n" - "\n" - "Command syntax:\n" -#define DEF(option, callback, arg_string)\ - " " arg_string "\n" -#include "qemu-img-cmds.h" -#undef DEF - "\n" - "Command parameters:\n" - " 'filename' is a disk image filename\n" - " 'objectdef' is a QEMU user creatable object definition. See the qemu(1)\n" - "manual page for a description of the object properties. The most common\n" - "object type is a 'secret', which is used to supply passwords and/or\n" - "encryption keys.\n" - " 'fmt' is the disk image format. It is guessed automatically in most cases\n" - " 'cache' is the cache mode used to write the output disk image, the valid\n" - "options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n" - "'directsync' and 'unsafe' (default for convert)\n" - " 'src_cache' is the cache mode used to read input disk images, the valid\n" - "options are the same as for the 'cache' option\n" - " 'size' is the disk image size in bytes. Optional suffixes\n" - "'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n" - "'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P) are\n" - "supported. 'b' is ignored.\n" - " 'output_filename' is the destination disk image filename\n" - " 'output_fmt' is the destination format\n" - " 'options' is a comma separated list of format specific options in a\n" - "name=value format. Use -o ? for an overview of the options supported by the\n" - "used format\n" - " 'snapshot_param' is param used for internal snapshot, format\n" - "is 'snapshot.id=[ID],snapshot.name=[NAME]', or\n" - "'[ID_OR_NAME]'\n" - " '-c' indicates that target image must be compressed (qcow format only)\n" - " '-u' allows unsafe backing chains. For rebasing, it is assumed that old and\n" - " new backing file match exactly. The image doesn't need a working\n" - " backing file before rebasing in this case (useful for renaming the\n" - " backing file). For image creation, allow creating without attempting\n" - " to open the backing file.\n" - " '-h' with or without a command shows this help and lists the supported formats\n" - " '-p' show progress of command (only certain commands)\n" - " '-q' use Quiet mode - do not print any output (except errors)\n" - " '-S' indicates the consecutive number of bytes (defaults to 4k) that must\n" - " contain only zeros for qemu-img to create a sparse image during\n" - " conversion. If the number of bytes is 0, the source will not be scanned for\n" - " unallocated or zero sectors, and the destination image wil
[Qemu-devel] [RFC PATCH 00/13] target/arm: Derive cpu id regs from features
This is something we talked about in the context of enabling sve in system mode. We don't want to replicate info between these two locations. I'm not 100% happy with this, thus the RFC. In particular, there are several places in id_isar0, id_isar2, and id_isar4 that expose micro- architectural details of the cpus. We cannot infer these values. We'll not be able to replicate the exact id values without additional changes. But I'll also note that with ARM_FEATURE_SWP, we're now at 60 feature bits, which means that we only have 4 remaining before we have to come up with another solution there. I do wonder if we should instead introduce some little inline functions to test each of the current feature bits, and once that's done convert those to test cpu->id_* bits. Most, but not all, of the feature bits would go away. We'd have the exact id values one would expect for a given cpu without having to replicate the info. Thoughts, one way or the other? r~ Richard Henderson (13): target/arm: Add ARM_FEATURE_SWP target/arm: Derive id_isar0 from features target/arm: Derive id_isar1 from features target/arm: Derive id_isar2 from features target/arm: Derive id_isar3 from features target/arm: Derive id_isar4 from features target/arm: Derive id_isar5 and id_isar6 from features target/arm: Derive id_pfr0 from features target/arm: Derive id_pfr1 from features target/arm: Derive id_aa64isar0 from features target/arm: Derive id_aa64isar1 from features target/arm: Derive id_aa64pfr0 from features target/arm: Remove assertions from resolve_id_regs target/arm/cpu.h | 1 + linux-user/elfload.c | 3 +- target/arm/cpu.c | 381 + target/arm/translate.c | 4 + 4 files changed, 388 insertions(+), 1 deletion(-) -- 2.17.1
[Qemu-devel] [PATCH 05/13] target/arm: Derive id_isar3 from features
??? The assertion does fire for the old cpus; they may be existing bugs. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 36 1 file changed, 36 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 379d6a08a4..2b199845fc 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -855,6 +855,38 @@ static uint32_t resolve_id_isar2(CPUARMState *env, uint32_t orig) return ret; } +static uint32_t resolve_id_isar3(CPUARMState *env) +{ +uint32_t ret = 0; + +if (arm_feature(env, ARM_FEATURE_V5)) { +ret = deposit32(ret, 0, 4, 1);/* Saturate */ +} +if (arm_feature(env, ARM_FEATURE_V6)) { +ret = deposit32(ret, 4, 4, 3);/* SIMD */ +} +ret = deposit32(ret, 8, 4, 1);/* SVC -- no pre-armv4t */ +/* SynchPrim */ +if (arm_feature(env, ARM_FEATURE_V6K)) { +ret = deposit32(ret, 12, 4, 2); /* ldrex, ldrexb, ldrexd */ +} else if (arm_feature(env, ARM_FEATURE_V6)) { +ret = deposit32(ret, 12, 4, 1); /* ldrex only */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2)) { +ret = deposit32(ret, 16, 4, 1); /* TabBranch */ +ret = deposit32(ret, 20, 4, 1); /* T32Copy */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2) || +arm_feature(env, ARM_FEATURE_V6K)) { +ret = deposit32(ret, 24, 4, 1); /* TrueNOP */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { +ret = deposit32(ret, 28, 4, 1); /* T32EE */ +} + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -871,6 +903,10 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_isar2; cpu->id_isar2 = resolve_id_isar2(env, orig); g_assert_cmphex(cpu->id_isar2, ==, orig); + +orig = cpu->id_isar3; +cpu->id_isar3 = resolve_id_isar3(env); +g_assert_cmphex(cpu->id_isar3, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 03/13] target/arm: Derive id_isar1 from features
??? The assertion does fire for quite a lot of cpus, ??? but quite a few of them appear to be existing bugs. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 37 - 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 44483e3dea..a477e722af 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -791,13 +791,48 @@ static uint32_t resolve_id_isar0(CPUARMState *env, uint32_t orig) return ret; } +static uint32_t resolve_id_isar1(CPUARMState *env) +{ +uint32_t ret = 0; + +if (arm_feature(env, ARM_FEATURE_V6)) { +ret = deposit32(ret, 0, 4, 1);/* Endian */ +if (!arm_feature(env, ARM_FEATURE_M)) { +ret = deposit32(ret, 4, 4, 1);/* Except */ +ret = deposit32(ret, 8, 4, 1);/* Except_AR */ +} +/* Extend */ +ret = deposit32(ret, 12, 4, + arm_feature(env, ARM_FEATURE_THUMB_DSP) ? 2 : 1); +} +if (arm_feature(env, ARM_FEATURE_THUMB2)) { +ret = deposit32(ret, 16, 4, 1); /* IfThen */ +ret = deposit32(ret, 20, 4, 1); /* Immediate */ +} +/* Interwork -- note we don't support pre-armv4t. */ +ret = deposit32(ret, 24, 4, + arm_feature(env, ARM_FEATURE_V7) + && !arm_feature(env, ARM_FEATURE_M) ? 3 : + arm_feature(env, ARM_FEATURE_V5) ? 2 : 1); +if (arm_feature(env, ARM_FEATURE_JAZELLE)) { +ret = deposit32(ret, 28, 4, 1); /* Jazelle */ +} + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; uint64_t orig; -cpu->id_isar0 = resolve_id_isar0(env, orig = cpu->id_isar0); +orig = cpu->id_isar0; +cpu->id_isar0 = resolve_id_isar0(env, orig); g_assert_cmphex(cpu->id_isar0, ==, orig); + +orig = cpu->id_isar1; +cpu->id_isar1 = resolve_id_isar1(env); +g_assert_cmphex(cpu->id_isar1, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 02/13] target/arm: Derive id_isar0 from features
??? Test with -machine none -cpu foo. ??? The assertion does fire for quite a lot of cpus, ??? but quite a few of them appear to be existing bugs. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 45 + 1 file changed, 45 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3bc7a16327..44483e3dea 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -756,6 +756,50 @@ static void arm_cpu_finalizefn(Object *obj) } } +static uint32_t resolve_id_isar0(CPUARMState *env, uint32_t orig) +{ +uint32_t ret = 0; + +if (arm_feature(env, ARM_FEATURE_SWP)) { +ret = deposit32(ret, 0, 4, 1);/* Swap */ +} +if (arm_feature(env, ARM_FEATURE_V5)) { +ret = deposit32(ret , 4, 4, 1); /* BitCount */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2)) { +ret = deposit32(ret, 8, 4, 1);/* BitField */ +ret = deposit32(ret, 12, 4, 1); /* CmpBranch */ +} + +/* + * Coproc -- generically, v5te has mcrr (3), v6 has mcrr2 (4), + * and v8 requires none (0). There does not appear to be a way + * to guess the value though, as some v6 and v7 cores also use none. + */ +ret |= orig & MAKE_64BIT_MASK(16, 4); + +if (arm_feature(env, ARM_FEATURE_V5)) { +ret = deposit32(ret, 20, 4, 1); /* Debug */ +} +/* Divide */ +if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { +ret = deposit32(ret, 24, 4, 2); +} else if (arm_feature(env, ARM_FEATURE_THUMB_DIV)) { +ret = deposit32(ret, 24, 4, 1); +} + +return ret; +} + +static void resolve_id_regs(ARMCPU *cpu) +{ +CPUARMState *env = &cpu->env; +uint64_t orig; + +cpu->id_isar0 = resolve_id_isar0(env, orig = cpu->id_isar0); +g_assert_cmphex(cpu->id_isar0, ==, orig); +} + static void arm_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -1003,6 +1047,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) set_feature(env, ARM_FEATURE_VBAR); } +resolve_id_regs(cpu); register_cp_regs_for_features(cpu); arm_cpu_register_gdb_regs_for_features(cpu); -- 2.17.1
[Qemu-devel] [PATCH 01/13] target/arm: Add ARM_FEATURE_SWP
These insns have been removed from the ISA, but are also not present on some cpus with V7VE. Signed-off-by: Richard Henderson --- target/arm/cpu.h | 1 + linux-user/elfload.c | 3 ++- target/arm/cpu.c | 10 ++ target/arm/translate.c | 4 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 65c0fa0a65..acfb2f9104 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1495,6 +1495,7 @@ enum arm_features { ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */ ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */ ARM_FEATURE_M_MAIN, /* M profile Main Extension */ +ARM_FEATURE_SWP, /* implements swp/swpb */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8638612aec..fcac2563f1 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -450,7 +450,6 @@ static uint32_t get_elf_hwcap(void) ARMCPU *cpu = ARM_CPU(thread_cpu); uint32_t hwcaps = 0; -hwcaps |= ARM_HWCAP_ARM_SWP; hwcaps |= ARM_HWCAP_ARM_HALF; hwcaps |= ARM_HWCAP_ARM_THUMB; hwcaps |= ARM_HWCAP_ARM_FAST_MULT; @@ -458,7 +457,9 @@ static uint32_t get_elf_hwcap(void) /* probe for the extra features */ #define GET_FEATURE(feat, hwcap) \ do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) + /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */ +GET_FEATURE(ARM_FEATURE_SWP, ARM_HWCAP_ARM_SWP); GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP); GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP); GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 258ba6dcaa..3bc7a16327 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1075,6 +1075,7 @@ static void arm926_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); set_feature(&cpu->env, ARM_FEATURE_JAZELLE); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x41069265; cpu->reset_fpsid = 0x41011090; cpu->ctr = 0x1dd20d2; @@ -1089,6 +1090,7 @@ static void arm946_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_PMSA); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x41059461; cpu->ctr = 0x0f004006; cpu->reset_sctlr = 0x0078; @@ -1105,6 +1107,7 @@ static void arm1026_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); set_feature(&cpu->env, ARM_FEATURE_JAZELLE); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x4106a262; cpu->reset_fpsid = 0x410110a0; cpu->ctr = 0x1dd20d2; @@ -1139,6 +1142,7 @@ static void arm1136_r2_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x4107b362; cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x; @@ -1171,6 +1175,7 @@ static void arm1136_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x4117b363; cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x; @@ -1204,6 +1209,7 @@ static void arm1176_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); set_feature(&cpu->env, ARM_FEATURE_EL3); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x410fb767; cpu->reset_fpsid = 0x410120b5; cpu->mvfr0 = 0x; @@ -1235,6 +1241,7 @@ static void arm11mpcore_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VAPA); set_feature(&cpu->env, ARM_FEATURE_MPIDR); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x410fb022; cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x; @@ -1378,6 +1385,7 @@ static void cortex_r5_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); set_feature(&cpu->env, ARM_FEATURE_V7MP); set_feature(&cpu->env, ARM_FEATURE_PMSA); +set_feature(&cpu->env, ARM_FEATURE_SWP); cpu->midr = 0x411fc153; /* r1p3 */ cpu->id_pfr0 = 0x0131; cpu->id_pfr1 = 0x001; @@ -1426,6 +1434,7 @@ static void cortex_a8_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_EL3); +set_feat
[Qemu-devel] [PATCH 08/13] target/arm: Derive id_pfr0 from features
??? The assertion does fire for old cpus; they may be existing bugs. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index c227044946..0151c278e8 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -969,6 +969,29 @@ static uint32_t resolve_id_isar6(CPUARMState *env) return ret; } +static uint32_t resolve_id_pfr0(CPUARMState *env) +{ +uint32_t ret = 0; + +if (!arm_feature(env, ARM_FEATURE_M)) { +ret = deposit32(ret, 0, 4, 1);/* State0 -- A32 */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2)) { +ret = deposit32(ret, 4, 4, 3);/* State1 -- T32 */ +} else if (arm_feature(env, ARM_FEATURE_V5)) { +ret = deposit32(ret, 4, 4, 1);/* State1 -- bl/blx only */ +} +if (arm_feature(env, ARM_FEATURE_JAZELLE)) { +ret = deposit32(ret, 8, 4, 1);/* State2 -- Jazelle */ +} +if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { +ret = deposit32(ret, 12, 4, 1); /* State3 -- T32EE */ +} +/* RAS -- not implemented yet */ + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -997,6 +1020,10 @@ static void resolve_id_regs(ARMCPU *cpu) cpu->id_isar5 = resolve_id_isar5(env); cpu->id_isar6 = resolve_id_isar6(env); + +orig = cpu->id_pfr0; +cpu->id_pfr0 = resolve_id_pfr0(env); +g_assert_cmphex(cpu->id_pfr0, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 06/13] target/arm: Derive id_isar4 from features
??? The assertion does fire for the old cpus; they may be existing bugs. ??? Willfully provide a value for SWP_frac that matches our implementation. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 44 1 file changed, 44 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 2b199845fc..3c6ddd6532 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -887,6 +887,45 @@ static uint32_t resolve_id_isar3(CPUARMState *env) return ret; } +static uint32_t resolve_id_isar4(CPUARMState *env) +{ +uint32_t ret = 0; + +/* Unpriv -- note we don't support pre-armv4t. */ +ret = deposit32(ret, 0, 4, arm_feature(env, ARM_FEATURE_THUMB2) ? 2 : 1); +/* WithShifts */ +if (!arm_feature(env, ARM_FEATURE_M)) { +ret = deposit32(ret, 4, 4, 4); +} else if (arm_feature(env, ARM_FEATURE_V8)) { +ret = deposit32(ret, 4, 4, 3); +} +ret = deposit32(ret, 8, 4, 1);/* Writeback */ +if (arm_feature(env, ARM_FEATURE_EL3)) { +/* Note that EL3 indicates Security Extensions. */ +/* ??? In translate.c we check V6K instead. */ +ret = deposit32(ret, 12, 4, 1); /* SMC */ +} +if (arm_feature(env, ARM_FEATURE_V7)) { +ret = deposit32(ret, 16, 4, 1); /* Barrier */ +} +if (!arm_feature(env, ARM_FEATURE_V6K) && +arm_feature(env, ARM_FEATURE_V6)) { +ret = deposit32(ret, 20, 4, 3); /* SyncPrim_frac */ +} +if (arm_feature(env, ARM_FEATURE_M)) { +ret = deposit32(ret, 24, 4, 1); /* PSR_M */ +} +/* + * SWP_frac -- Value 1 indicates that SWP and SWPB only work in a + * uniprocessor context. Looking at ARM_FEATURE_SWP, we will have + * already set ID_ISAR0.Swap to 1, which means that SWP_frac must + * be ignored. While leaving this field 0 may not match certain + * real cpus, it is correct with respect to our implementation. + */ + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -907,6 +946,11 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_isar3; cpu->id_isar3 = resolve_id_isar3(env); g_assert_cmphex(cpu->id_isar3, ==, orig); + +orig = cpu->id_isar4; +cpu->id_isar4 = resolve_id_isar4(env); +/* Willfully ignore the SWP_frac field. */ +g_assert_cmphex(cpu->id_isar4 & 0x0fff, ==, orig & 0x0fff); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 04/13] target/arm: Derive id_isar2 from features
??? The assertion does fire for the old cpus; they may be existing bugs. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a477e722af..379d6a08a4 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -821,6 +821,40 @@ static uint32_t resolve_id_isar1(CPUARMState *env) return ret; } +static uint32_t resolve_id_isar2(CPUARMState *env, uint32_t orig) +{ +uint32_t ret = 0; + +/* LoadStore */ +ret = deposit32(ret, 0, 4, +arm_feature(env, ARM_FEATURE_V8) ? 2 : +arm_feature(env, ARM_FEATURE_V5) ? 1 : 0); +/* + * MemHint -- v7mp has pldw (4), v7 has pli (3), but values 1 & 2 + * mean the same thing, and there does not seem to be a way to tell + * them apart for v5 & v6. + */ +ret |= orig & MAKE_64BIT_MASK(4, 4); +/* MultiAccessInt -- micro-architectural detail. */ +ret |= orig & MAKE_64BIT_MASK(8, 4); +/* Mult -- note we don't support pre-armv4t. */ +ret = deposit32(ret, 12, 4, arm_feature(env, ARM_FEATURE_THUMB2) ? 2 : 1); +/* MultS -- note we don't support pre-armv4t. */ +ret = deposit32(ret, 16, 4, +arm_feature(env, ARM_FEATURE_V6) ? 3 : +arm_feature(env, ARM_FEATURE_V5) ? 2 : 1); +/* MultU -- note we don't support pre-armv4t. */ +ret = deposit32(ret, 20, 4, arm_feature(env, ARM_FEATURE_V6) ? 2 : 1); +/* PSR_AR */ +ret = deposit32(ret, 24, 4, arm_feature(env, ARM_FEATURE_M) ? 0 : 1); +/* Reversal */ +ret = deposit32(ret, 28, 4, +arm_feature(env, ARM_FEATURE_THUMB2) ? 2 : +arm_feature(env, ARM_FEATURE_V6) ? 1 : 0); + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -833,6 +867,10 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_isar1; cpu->id_isar1 = resolve_id_isar1(env); g_assert_cmphex(cpu->id_isar1, ==, orig); + +orig = cpu->id_isar2; +cpu->id_isar2 = resolve_id_isar2(env, orig); +g_assert_cmphex(cpu->id_isar2, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 09/13] target/arm: Derive id_pfr1 from features
Signed-off-by: Richard Henderson --- target/arm/cpu.c | 29 + 1 file changed, 29 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 0151c278e8..4fb3e0a9ea 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -992,6 +992,31 @@ static uint32_t resolve_id_pfr0(CPUARMState *env) return ret; } +static uint32_t resolve_id_pfr1(CPUARMState *env) +{ +uint32_t ret = 0; + +if (arm_feature(env, ARM_FEATURE_M)) { +ret = deposit32(ret, 8, 4, 2);/* MProgMod */ +} else { +ret = deposit32(ret, 0, 4, 1);/* ProgMod */ +} +if (arm_feature(env, ARM_FEATURE_EL3)) { +ret = deposit32(ret, 4, 4, 1);/* Security */ +} +if (arm_feature(env, ARM_FEATURE_EL2)) { +ret = deposit32(ret, 12, 4, 1); /* Virtualization */ +} +if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) { +ret = deposit32(ret, 16, 4, 1); /* GenTimer */ +} +/* Sec_frac -- no partial features implemented without EL3 */ +/* Virt_frac -- no partial features implemented without EL2 */ +/* GIC -- info not available yet; filled in by id_pfr1_read */ + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -1024,6 +1049,10 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_pfr0; cpu->id_pfr0 = resolve_id_pfr0(env); g_assert_cmphex(cpu->id_pfr0, ==, orig); + +orig = cpu->id_pfr1; +cpu->id_pfr1 = resolve_id_pfr1(env); +g_assert_cmphex(cpu->id_pfr1, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 13/13] target/arm: Remove assertions from resolve_id_regs
This is a prerequisite to removing the now-redundant initializations from within the individual cpus. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 41 +++-- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 2ec71104c9..79103926a4 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1108,49 +1108,22 @@ static uint64_t resolve_id_aa64pfr0(CPUARMState *env) static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; -uint64_t orig; -orig = cpu->id_isar0; -cpu->id_isar0 = resolve_id_isar0(env, orig); -g_assert_cmphex(cpu->id_isar0, ==, orig); - -orig = cpu->id_isar1; +cpu->id_isar0 = resolve_id_isar0(env, cpu->id_isar0); cpu->id_isar1 = resolve_id_isar1(env); -g_assert_cmphex(cpu->id_isar1, ==, orig); - -orig = cpu->id_isar2; -cpu->id_isar2 = resolve_id_isar2(env, orig); -g_assert_cmphex(cpu->id_isar2, ==, orig); - -orig = cpu->id_isar3; +cpu->id_isar2 = resolve_id_isar2(env, cpu->id_isar2); cpu->id_isar3 = resolve_id_isar3(env); -g_assert_cmphex(cpu->id_isar3, ==, orig); - -orig = cpu->id_isar4; cpu->id_isar4 = resolve_id_isar4(env); -/* Willfully ignore the SWP_frac field. */ -g_assert_cmphex(cpu->id_isar4 & 0x0fff, ==, orig & 0x0fff); - cpu->id_isar5 = resolve_id_isar5(env); cpu->id_isar6 = resolve_id_isar6(env); - -orig = cpu->id_pfr0; cpu->id_pfr0 = resolve_id_pfr0(env); -g_assert_cmphex(cpu->id_pfr0, ==, orig); - -orig = cpu->id_pfr1; cpu->id_pfr1 = resolve_id_pfr1(env); -g_assert_cmphex(cpu->id_pfr1, ==, orig); -orig = cpu->id_aa64isar0; -cpu->id_aa64isar0 = resolve_id_aa64isar0(env); -g_assert_cmphex(cpu->id_aa64isar0, ==, orig); - -cpu->id_aa64isar1 = resolve_id_aa64isar1(env); - -orig = cpu->id_aa64pfr0; -cpu->id_aa64pfr0 = resolve_id_aa64pfr0(env); -g_assert_cmphex(cpu->id_aa64pfr0, ==, orig); +if (arm_feature(env, ARM_FEATURE_AARCH64)) { +cpu->id_aa64isar0 = resolve_id_aa64isar0(env); +cpu->id_aa64isar1 = resolve_id_aa64isar1(env); +cpu->id_aa64pfr0 = resolve_id_aa64pfr0(env); +} } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 11/13] target/arm: Derive id_aa64isar1 from features
Signed-off-by: Richard Henderson --- target/arm/cpu.c | 20 1 file changed, 20 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 1c51b9f631..a9724f3bb1 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1062,6 +1062,24 @@ static uint64_t resolve_id_aa64isar0(CPUARMState *env) return ret; } +static uint64_t resolve_id_aa64isar1(CPUARMState *env) +{ +uint64_t ret = 0; + +/* DPB -- not implemented yet */ +/* APA -- not implemented yet */ +/* API -- not implemented yet */ +/* JSCVT -- not implemented yet */ +if (arm_feature(env, ARM_FEATURE_V8_FCMA)) { +ret = deposit64(ret, 16, 4, 1); +} +/* LRCPC -- not implemented yet */ +/* GPA -- not implemented yet */ +/* GPI -- not implemented yet */ + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -1102,6 +1120,8 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_aa64isar0; cpu->id_aa64isar0 = resolve_id_aa64isar0(env); g_assert_cmphex(cpu->id_aa64isar0, ==, orig); + +cpu->id_aa64isar1 = resolve_id_aa64isar1(env); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 07/13] target/arm: Derive id_isar5 and id_isar6 from features
Unlike the other id_sar registers, these contain post-v8.0 features that are not included with any existing cpu models. They would be enabled by -cpu max when we enable them for system mode. Signed-off-by: Richard Henderson --- target/arm/cpu.c | 46 ++ 1 file changed, 46 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3c6ddd6532..c227044946 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -926,6 +926,49 @@ static uint32_t resolve_id_isar4(CPUARMState *env) return ret; } +static uint32_t resolve_id_isar5(CPUARMState *env) +{ +uint32_t ret = 0; + +/* SEVL -- we always implement as NOP. */ +/* AES */ +if (arm_feature(env, ARM_FEATURE_V8_PMULL)) { +ret = deposit32(ret, 4, 4, 2); +} else if (arm_feature(env, ARM_FEATURE_V8_AES)) { +ret = deposit32(ret, 4, 4, 1); +} +if (arm_feature(env, ARM_FEATURE_V8_SHA1)) { +ret = deposit32(ret, 8, 4, 1);/* SHA1 */ +} +if (arm_feature(env, ARM_FEATURE_V8_SHA256)) { +ret = deposit32(ret, 12, 4, 1); /* SHA2 */ +} +if (arm_feature(env, ARM_FEATURE_CRC)) { +ret = deposit32(ret, 16, 4, 1); /* CRC32 */ +} +if (arm_feature(env, ARM_FEATURE_V8_RDM)) { +ret = deposit32(ret, 24, 4, 1); /* RDM */ +} +if (arm_feature(env, ARM_FEATURE_V8_FCMA)) { +ret = deposit32(ret, 28, 4, 1); /* VCMA */ +} + +return ret; +} + +static uint32_t resolve_id_isar6(CPUARMState *env) +{ +uint32_t ret = 0; + +/* JSCVT -- not implemented yet */ +/* FHM -- not implemented yet */ +if (arm_feature(env, ARM_FEATURE_V8_DOTPROD)) { +ret = deposit32(ret, 4, 4, 1);/* DP */ +} + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -951,6 +994,9 @@ static void resolve_id_regs(ARMCPU *cpu) cpu->id_isar4 = resolve_id_isar4(env); /* Willfully ignore the SWP_frac field. */ g_assert_cmphex(cpu->id_isar4 & 0x0fff, ==, orig & 0x0fff); + +cpu->id_isar5 = resolve_id_isar5(env); +cpu->id_isar6 = resolve_id_isar6(env); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 12/13] target/arm: Derive id_aa64pfr0 from features
Signed-off-by: Richard Henderson --- target/arm/cpu.c | 29 + 1 file changed, 29 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a9724f3bb1..2ec71104c9 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1080,6 +1080,31 @@ static uint64_t resolve_id_aa64isar1(CPUARMState *env) return ret; } +static uint64_t resolve_id_aa64pfr0(CPUARMState *env) +{ +uint64_t ret = 0; + +ret = deposit64(ret, 0, 4, 2);/* EL0 */ +ret = deposit64(ret, 4, 4, 2);/* EL1 */ +if (arm_feature(env, ARM_FEATURE_EL2)) { +ret = deposit64(ret, 8, 4, 2);/* EL2 */ +} +if (arm_feature(env, ARM_FEATURE_EL3)) { +ret = deposit64(ret, 12, 4, 2); /* EL3 */ +} +if (arm_feature(env, ARM_FEATURE_V8_FP16)) { +ret = deposit64(ret, 16, 4, 1); /* FP */ +ret = deposit64(ret, 20, 4, 1); /* AdvSIMD */ +} +/* GIC -- info not available yet; filled in by id_aa64pfr0_read */ +/* RAS -- not implemented yet */ +if (arm_feature(env, ARM_FEATURE_SVE)) { +ret = deposit64(ret, 32, 4, 1); /* SVE */ +} + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -1122,6 +1147,10 @@ static void resolve_id_regs(ARMCPU *cpu) g_assert_cmphex(cpu->id_aa64isar0, ==, orig); cpu->id_aa64isar1 = resolve_id_aa64isar1(env); + +orig = cpu->id_aa64pfr0; +cpu->id_aa64pfr0 = resolve_id_aa64pfr0(env); +g_assert_cmphex(cpu->id_aa64pfr0, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] [PATCH 10/13] target/arm: Derive id_aa64isar0 from features
Signed-off-by: Richard Henderson --- target/arm/cpu.c | 49 1 file changed, 49 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 4fb3e0a9ea..1c51b9f631 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1017,6 +1017,51 @@ static uint32_t resolve_id_pfr1(CPUARMState *env) return ret; } +static uint64_t resolve_id_aa64isar0(CPUARMState *env) +{ +uint64_t ret = 0; + +/* AES */ +if (arm_feature(env, ARM_FEATURE_V8_PMULL)) { +ret = deposit64(ret, 4, 4, 2); +} else if (arm_feature(env, ARM_FEATURE_V8_AES)) { +ret = deposit64(ret, 4, 4, 1); +} +if (arm_feature(env, ARM_FEATURE_V8_SHA1)) { +ret = deposit64(ret, 8, 4, 1);/* SHA1 */ +} +/* SHA2 */ +if (arm_feature(env, ARM_FEATURE_V8_SHA512)) { +ret = deposit64(ret, 12, 4, 2); +} else if (arm_feature(env, ARM_FEATURE_V8_SHA256)) { +ret = deposit64(ret, 12, 4, 1); +} +if (arm_feature(env, ARM_FEATURE_CRC)) { +ret = deposit64(ret, 16, 4, 1); /* CRC32 */ +} +if (arm_feature(env, ARM_FEATURE_V8_ATOMICS)) { +ret = deposit64(ret, 20, 4, 2); /* Atomic */ +} +if (arm_feature(env, ARM_FEATURE_V8_RDM)) { +ret = deposit64(ret, 28, 4, 1); /* RDM */ +} +if (arm_feature(env, ARM_FEATURE_V8_SHA3)) { +ret = deposit64(ret, 32, 4, 1); /* SHA3 */ +} +if (arm_feature(env, ARM_FEATURE_V8_SM3)) { +ret = deposit64(ret, 36, 4, 1); /* SM3 */ +} +if (arm_feature(env, ARM_FEATURE_V8_SM4)) { +ret = deposit64(ret, 40, 4, 1); /* SM4 */ +} +if (arm_feature(env, ARM_FEATURE_V8_DOTPROD)) { +ret = deposit64(ret, 44, 4, 1); /* DP */ +} +/* FHM -- not implemented yet */ + +return ret; +} + static void resolve_id_regs(ARMCPU *cpu) { CPUARMState *env = &cpu->env; @@ -1053,6 +1098,10 @@ static void resolve_id_regs(ARMCPU *cpu) orig = cpu->id_pfr1; cpu->id_pfr1 = resolve_id_pfr1(env); g_assert_cmphex(cpu->id_pfr1, ==, orig); + +orig = cpu->id_aa64isar0; +cpu->id_aa64isar0 = resolve_id_aa64isar0(env); +g_assert_cmphex(cpu->id_aa64isar0, ==, orig); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -- 2.17.1
[Qemu-devel] Freeze / spin in virtio blk...flatview do translate
Hi qemu-devel, So we're using QEMU 2.12 for recent Android Emulator canaryies, and we're seeing a lot of hangs on mac in flatview_translate in qemu 2.12. What would be some pointers for diagnosing excessive I/O? Especially, metrics to see if a system is on the verge of getting into main loop spins. We have not reproduced this hang so far, this is from user crash reports that triggered our hang detector (where 15+ seconds pass without main loop / VCPU threads being able to go back and ping their loopers in main loop / vcpu threads. 0x0001024e9fcb(qemu-system-x86_64 -exec.c:511)flatview_translate 0x0001024f2390(qemu-system-x86_64 -memory.h:1865)address_space_lduw_internal_cached 0x00010246ff11(qemu-system-x86_64 -virtio-access.h:166)virtio_queue_set_notification 0x0001024fa2c9(qemu-system-x86_64+ 0x000a72c9)virtio_blk_handle_vq 0x0001024746ee(qemu-system-x86_64 -virtio.c:1521)virtio_queue_host_notifier_aio_read 0x000103a5ed8a(qemu-system-x86_64 -aio-posix.c:406)aio_dispatch_handlers 0x000103a5ecc8(qemu-system-x86_64 -aio-posix.c:437)aio_dispatch 0x000103a5c158(qemu-system-x86_64 -async.c:261)aio_ctx_dispatch 0x000103a92103(qemu-system-x86_64 -gmain.c:3072)g_main_context_dispatch 0x000103a5e4ad(qemu-system-x86_64 -main-loop.c:224)main_loop_wait 0x000102468ab8(qemu-system-x86_64 -vl.c:2172)main_impl 0x000102461a3a(qemu-system-x86_64 -vl.c:3332)run_qemu_main 0x00010246eef3(qemu-system-x86_64 -main.cpp:577)enter_qemu_main_loop(int, char**) 0x0001062b63a9(libQt5Core.5.dylib -qthread_unix.cpp:344)QThreadPrivate::start(void*) 0x7fff65118660 0x7fff6511850c 0x7fff65117bf8 0x0001062b623f(libQt5Core.5.dylib+ 0x0002623f) Thanks, Frank
Re: [Qemu-devel] [PATCH 2/2] KVM: i386: Add support for save and restore nested state
> On 14 Sep 2018, at 18:08, Paolo Bonzini wrote: > > On 14/09/2018 16:31, Liran Alon wrote: >>> There is still a problem, however, in that the same input stream would >>> be parsed differently depending on the kernel version. In particular, >>> if in the future the maximum nested state size grows, you break all >>> existing save files. >> >> I’m not sure I agree with this. >> 1) Newer kernels should change struct only by utilizing unused fields in >> current struct >> or enlarging it with extra fields. It should not change the meaning of >> existing fields. > > Newer kernels will return a larger size, which is stored in > env->nested_state_len, and the file format depends on it: > >> +VMSTATE_VBUFFER_UINT32(env.nested_state, X86CPU, >> + 0, NULL, >> + env.nested_state_len), > Oh. I thought that QEMU will just receive to dest buffer only what was sent from source buffer. I didn’t know that it also enforces that the sizes of the source and dest buffer are equal. (I thought that dest_buffer_size only needed to be >= src_buffer_size). Anyway, my intention here was that QEMU will only enforce (dest_buffer_size >= source_buffer_size) and if so, receive source buffer into destination buffer. Is there a simple way to do this in QEMU’s VMSTATE framework without implementing custom save/load callbacks? >>> >>> By defining more HF flags. I'd rather avoid having multiple ways to >>> store the same thing, in case for example in the future HVF implements >>> nested virt. >> >> I agree it is possible to define more hflags and to translate >> kvm_nested_flags->flags to flags in hflags and vice-versa. >> However, I am not sure I understand the extra value provided by doing so. >> I think it makes more sense to rename struct kvm_nested_state to struct >> nested_state and >> use this as a generic interface to get/set nested_state for all hypervisors. >> If a given hypervisor, such as HVF, needs to store different blob than KVM >> VMX, it can just add another struct field to >> the union-part of struct kvm_nested_state. >> This way, the code that handles the save/restore of nested_state can remain >> generic for all hypervisors. > > I agree that the value is small, but it's there. For example, the > debugging commands support AMD nested paging, and sharing the flags > means that it works for KVM too, not just TCG. So I'd prefer to do it > the same way for Intel too. Can you explain this example? I’m not sure I follow. In the solution I proposed above, the nested_state fixed-size header is also shared between hypervisors. Thus, flags here are shared exactly the same as hflags are shared. Only the blob union-part is not necessarely shared between hypervisors (Which makes sense as it may differ). Am I missing something trivial? -Liran > > Paolo
Re: [Qemu-devel] [PATCH 2/2] KVM: i386: Add support for save and restore nested state
> On 15 Sep 2018, at 23:48, Liran Alon wrote: > > > >> On 14 Sep 2018, at 18:08, Paolo Bonzini wrote: >> >> On 14/09/2018 16:31, Liran Alon wrote: There is still a problem, however, in that the same input stream would be parsed differently depending on the kernel version. In particular, if in the future the maximum nested state size grows, you break all existing save files. >>> >>> I’m not sure I agree with this. >>> 1) Newer kernels should change struct only by utilizing unused fields in >>> current struct >>> or enlarging it with extra fields. It should not change the meaning of >>> existing fields. >> >> Newer kernels will return a larger size, which is stored in >> env->nested_state_len, and the file format depends on it: >> >>> +VMSTATE_VBUFFER_UINT32(env.nested_state, X86CPU, >>> + 0, NULL, >>> + env.nested_state_len), >> > > Oh. I thought that QEMU will just receive to dest buffer only what was sent > from source buffer. > I didn’t know that it also enforces that the sizes of the source and dest > buffer are equal. > (I thought that dest_buffer_size only needed to be >= src_buffer_size). > > Anyway, my intention here was that QEMU will only enforce (dest_buffer_size > >= source_buffer_size) > and if so, receive source buffer into destination buffer. > Is there a simple way to do this in QEMU’s VMSTATE framework without > implementing custom save/load callbacks? > One possible, but not so elegant, way to do so is to put env.nested_state_len as part of VMState and change env.nested_state to be declared in VMState as VMSTATE_VBUFFER_ALLOC_UINT32(). Then, make nested_state_post_load() to realloc env.nested_state in size specified by kvm_nested_state_length(). To guarantee that env.nested_state is always at max size that local kernel supports. -Liran
Re: [Qemu-devel] Freeze / spin in virtio blk...flatview do translate
I notice at least two commits in upstream QEMU that might impact this: https://github.com/qemu/qemu/commit/ce3a9eaff4e5f29514dba35a001894cb7a238e07#diff-8bfe2ea13d8c6dab17a555f300ac2f66 https://github.com/qemu/qemu/commit/45641dba38f6f44c3ea44c2d1c37b31619276ce3#diff-a9288ea1a561573c7d3036de7d7048e8 On Sat, Sep 15, 2018 at 11:41 AM Frank Yang wrote: > Hi qemu-devel, > > So we're using QEMU 2.12 for recent Android Emulator canaryies, and we're > seeing a lot of hangs on mac in flatview_translate in qemu 2.12. > > What would be some pointers for diagnosing excessive I/O? > > Especially, metrics to see if a system is on the verge of getting into > main loop spins. > > We have not reproduced this hang so far, this is from user crash reports > that triggered our hang detector (where 15+ seconds pass without main loop > / VCPU threads being able to go back and ping their loopers in main loop / > vcpu threads. > > 0x0001024e9fcb(qemu-system-x86_64 -exec.c:511)flatview_translate > 0x0001024f2390(qemu-system-x86_64 > -memory.h:1865)address_space_lduw_internal_cached > 0x00010246ff11(qemu-system-x86_64 > -virtio-access.h:166)virtio_queue_set_notification > 0x0001024fa2c9(qemu-system-x86_64+ 0x000a72c9)virtio_blk_handle_vq > 0x0001024746ee(qemu-system-x86_64 > -virtio.c:1521)virtio_queue_host_notifier_aio_read > 0x000103a5ed8a(qemu-system-x86_64 > -aio-posix.c:406)aio_dispatch_handlers > 0x000103a5ecc8(qemu-system-x86_64 -aio-posix.c:437)aio_dispatch > 0x000103a5c158(qemu-system-x86_64 -async.c:261)aio_ctx_dispatch > 0x000103a92103(qemu-system-x86_64 -gmain.c:3072)g_main_context_dispatch > 0x000103a5e4ad(qemu-system-x86_64 -main-loop.c:224)main_loop_wait > 0x000102468ab8(qemu-system-x86_64 -vl.c:2172)main_impl > 0x000102461a3a(qemu-system-x86_64 -vl.c:3332)run_qemu_main > 0x00010246eef3(qemu-system-x86_64 > -main.cpp:577)enter_qemu_main_loop(int, char**) > 0x0001062b63a9(libQt5Core.5.dylib > -qthread_unix.cpp:344)QThreadPrivate::start(void*) > 0x7fff65118660 > 0x7fff6511850c > 0x7fff65117bf8 > 0x0001062b623f(libQt5Core.5.dylib+ 0x0002623f) > > Thanks, > > Frank >
Re: [Qemu-devel] [PATCH 01/13] target/arm: Add ARM_FEATURE_SWP
On 15 September 2018 at 17:17, Richard Henderson wrote: > These insns have been removed from the ISA, but are also not > present on some cpus with V7VE. > > Signed-off-by: Richard Henderson > --- > target/arm/cpu.h | 1 + > linux-user/elfload.c | 3 ++- > target/arm/cpu.c | 10 ++ > target/arm/translate.c | 4 > 4 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 65c0fa0a65..acfb2f9104 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1495,6 +1495,7 @@ enum arm_features { > ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */ > ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */ > ARM_FEATURE_M_MAIN, /* M profile Main Extension */ > +ARM_FEATURE_SWP, /* implements swp/swpb */ > }; > > static inline int arm_feature(CPUARMState *env, int feature) > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 8638612aec..fcac2563f1 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -450,7 +450,6 @@ static uint32_t get_elf_hwcap(void) > ARMCPU *cpu = ARM_CPU(thread_cpu); > uint32_t hwcaps = 0; > > -hwcaps |= ARM_HWCAP_ARM_SWP; > hwcaps |= ARM_HWCAP_ARM_HALF; > hwcaps |= ARM_HWCAP_ARM_THUMB; > hwcaps |= ARM_HWCAP_ARM_FAST_MULT; > @@ -458,7 +457,9 @@ static uint32_t get_elf_hwcap(void) > /* probe for the extra features */ > #define GET_FEATURE(feat, hwcap) \ > do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) > + > /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */ > +GET_FEATURE(ARM_FEATURE_SWP, ARM_HWCAP_ARM_SWP); > GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP); This has separated the comment about EDSP from the code line it refers to. > GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP); > GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT); > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index 258ba6dcaa..3bc7a16327 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -1075,6 +1075,7 @@ static void arm926_initfn(Object *obj) > set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); > set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); > set_feature(&cpu->env, ARM_FEATURE_JAZELLE); > +set_feature(&cpu->env, ARM_FEATURE_SWP); > cpu->midr = 0x41069265; > cpu->reset_fpsid = 0x41011090; > cpu->ctr = 0x1dd20d2; In the current scheme of doing things I'd look for whether we could say that some more generic thing implied SWP rather than setting it in a lot of initfns (eg v5-but-not-v7VE?), but maybe the later patches make that a bad approach (haven't looked at the meat of this series). > diff --git a/target/arm/translate.c b/target/arm/translate.c > index c6a5d2ac44..2688380ae6 100644 > --- a/target/arm/translate.c > +++ b/target/arm/translate.c > @@ -9390,6 +9390,10 @@ static void disas_arm_insn(DisasContext *s, unsigned > int insn) > TCGv taddr; > TCGMemOp opc = s->be_data; > > +if (!arm_dc_feature(s, ARM_FEATURE_SWP)) { > +goto illegal_op; > +} > + We want to arrange to have SWP work anyway on linux-user, I think, since the kernel will typically trap-and-emulate it assuming it was built with CONFIG_SWP_EMULATE. (I don't know if those kernels will advertise swp in the hwcaps, but I guess not.) > rm = (insn) & 0xf; > > if (insn & (1 << 22)) { > -- > 2.17.1 thanks -- PMM