Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2…
Browse files Browse the repository at this point in the history
…0210921' into staging

target-arm queue:
 * Optimize codegen for MVE when predication not active
 * hvf: Add Apple Silicon support
 * hw/intc: Set GIC maintenance interrupt level to only 0 or 1
 * Fix mishandling of MVE FPSCR.LTPSIZE reset for usermode emulator
 * elf2dmp: Fix coverity nits

# gpg: Signature made Tue 21 Sep 2021 16:31:17 BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20210921: (27 commits)
  target/arm: Optimize MVE 1op-immediate insns
  target/arm: Optimize MVE VSLI and VSRI
  target/arm: Optimize MVE VSHLL and VMOVL
  target/arm: Optimize MVE VSHL, VSHR immediate forms
  target/arm: Optimize MVE VMVN
  target/arm: Optimize MVE VDUP
  target/arm: Optimize MVE VNEG, VABS
  target/arm: Optimize MVE arithmetic ops
  target/arm: Optimize MVE logic ops
  target/arm: Add TB flag for "MVE insns not predicated"
  target/arm: Enforce that FPDSCR.LTPSIZE is 4 on inbound migration
  target/arm: Avoid goto_tb if we're trying to exit to the main loop
  hvf: arm: Add rudimentary PMC support
  arm: Add Hypervisor.framework build target
  hvf: arm: Implement PSCI handling
  hvf: arm: Implement -cpu host
  arm/hvf: Add a WFI handler
  hvf: Add Apple Silicon support
  hvf: Introduce hvf_arch_init() callback
  hvf: Add execute to dirty log permission bitmap
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Sep 21, 2021
2 parents 1c81a38 + 4b445c9 commit 81ceb36
Show file tree
Hide file tree
Showing 24 changed files with 1,825 additions and 168 deletions.
5 changes: 5 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,11 @@ F: accel/accel-*.c
F: accel/Makefile.objs
F: accel/stubs/Makefile.objs

Apple Silicon HVF CPUs
M: Alexander Graf <agraf@csgraf.de>
S: Maintained
F: target/arm/hvf/

X86 HVF CPUs
M: Cameron Esfahani <dirty@apple.com>
M: Roman Bolshakov <r.bolshakov@yadro.com>
Expand Down
21 changes: 15 additions & 6 deletions accel/hvf/hvf-accel-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@

HVFState *hvf_state;

#ifdef __aarch64__
#define HV_VM_DEFAULT NULL
#endif

/* Memory slots */

hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
Expand Down Expand Up @@ -239,12 +243,12 @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
if (on) {
slot->flags |= HVF_SLOT_LOG;
hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
HV_MEMORY_READ);
HV_MEMORY_READ | HV_MEMORY_EXEC);
/* stop tracking region*/
} else {
slot->flags &= ~HVF_SLOT_LOG;
hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
HV_MEMORY_READ | HV_MEMORY_WRITE);
HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
}
}

Expand Down Expand Up @@ -324,7 +328,8 @@ static int hvf_accel_init(MachineState *ms)

hvf_state = s;
memory_listener_register(&hvf_memory_listener, &address_space_memory);
return 0;

return hvf_arch_init();
}

static void hvf_accel_class_init(ObjectClass *oc, void *data)
Expand Down Expand Up @@ -365,17 +370,20 @@ static int hvf_init_vcpu(CPUState *cpu)
cpu->hvf = g_malloc0(sizeof(*cpu->hvf));

/* init cpu signals */
sigset_t set;
struct sigaction sigact;

memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = dummy_signal;
sigaction(SIG_IPI, &sigact, NULL);

pthread_sigmask(SIG_BLOCK, NULL, &set);
sigdelset(&set, SIG_IPI);
pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask);
sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI);

#ifdef __aarch64__
r = hv_vcpu_create(&cpu->hvf->fd, (hv_vcpu_exit_t **)&cpu->hvf->exit, NULL);
#else
r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
#endif
cpu->vcpu_dirty = 1;
assert_hvf_ok(r);

Expand Down Expand Up @@ -451,6 +459,7 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, void *data)
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);

ops->create_vcpu_thread = hvf_start_vcpu_thread;
ops->kick_vcpu_thread = hvf_kick_vcpu_thread;

ops->synchronize_post_reset = hvf_cpu_synchronize_post_reset;
ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
Expand Down
22 changes: 10 additions & 12 deletions contrib/elf2dmp/download.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,19 @@ int download_url(const char *name, const char *url)
goto out_curl;
}

curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);

if (curl_easy_perform(curl) != CURLE_OK) {
err = 1;
fclose(file);
if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_WRITEDATA, file) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0) != CURLE_OK
|| curl_easy_perform(curl) != CURLE_OK) {
unlink(name);
goto out_curl;
fclose(file);
err = 1;
} else {
err = fclose(file);
}

err = fclose(file);

out_curl:
curl_easy_cleanup(curl);

Expand Down
4 changes: 4 additions & 0 deletions contrib/elf2dmp/pdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ static int pdb_init_symbols(struct pdb_reader *r)

static int pdb_reader_ds_init(struct pdb_reader *r, PDB_DS_HEADER *hdr)
{
if (hdr->block_size == 0) {
return 1;
}

memset(r->file_used, 0, sizeof(r->file_used));
r->ds.header = hdr;
r->ds.toc = pdb_ds_read(hdr, (uint32_t *)((uint8_t *)hdr +
Expand Down
5 changes: 3 additions & 2 deletions hw/intc/arm_gicv3_cpuif.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,9 @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
}
}

if (cs->ich_hcr_el2 & ICH_HCR_EL2_EN) {
maintlevel = maintenance_interrupt_state(cs);
if ((cs->ich_hcr_el2 & ICH_HCR_EL2_EN) &&
maintenance_interrupt_state(cs) != 0) {
maintlevel = 1;
}

trace_gicv3_cpuif_virt_set_irqs(gicv3_redist_affid(cs), fiqlevel,
Expand Down
12 changes: 11 additions & 1 deletion include/sysemu/hvf_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
#ifndef HVF_INT_H
#define HVF_INT_H

#ifdef __aarch64__
#include <Hypervisor/Hypervisor.h>
#else
#include <Hypervisor/hv.h>
#endif

/* hvf_slot flags */
#define HVF_SLOT_LOG (1 << 0)
Expand Down Expand Up @@ -40,19 +44,25 @@ struct HVFState {
int num_slots;

hvf_vcpu_caps *hvf_caps;
uint64_t vtimer_offset;
};
extern HVFState *hvf_state;

struct hvf_vcpu_state {
int fd;
uint64_t fd;
void *exit;
bool vtimer_masked;
sigset_t unblock_ipi_mask;
};

void assert_hvf_ok(hv_return_t ret);
int hvf_arch_init(void);
int hvf_arch_init_vcpu(CPUState *cpu);
void hvf_arch_vcpu_destroy(CPUState *cpu);
int hvf_vcpu_exec(CPUState *);
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
int hvf_put_registers(CPUState *);
int hvf_get_registers(CPUState *);
void hvf_kick_vcpu_thread(CPUState *cpu);

#endif
8 changes: 8 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ else
endif

accelerator_targets = { 'CONFIG_KVM': kvm_targets }

if cpu in ['aarch64']
accelerator_targets += {
'CONFIG_HVF': ['aarch64-softmmu']
}
endif

if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
# i386 emulator provides xenpv machine type for multiple architectures
accelerator_targets += {
Expand Down Expand Up @@ -2169,6 +2176,7 @@ if have_system or have_user
'accel/tcg',
'hw/core',
'target/arm',
'target/arm/hvf',
'target/hppa',
'target/i386',
'target/i386/kvm',
Expand Down
56 changes: 39 additions & 17 deletions target/arm/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "sysemu/tcg.h"
#include "sysemu/hw_accel.h"
#include "kvm_arm.h"
#include "hvf_arm.h"
#include "disas/capstone.h"
#include "fpu/softfloat.h"

Expand Down Expand Up @@ -266,11 +267,24 @@ static void arm_cpu_reset(DeviceState *dev)
}
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;

/* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
* executing as AArch32 then check if highvecs are enabled and
* adjust the PC accordingly.
*/
if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
env->regs[15] = 0xFFFF0000;
}

env->vfp.xregs[ARM_VFP_FPEXC] = 0;
#endif

if (arm_feature(env, ARM_FEATURE_M)) {
#ifndef CONFIG_USER_ONLY
uint32_t initial_msp; /* Loaded from 0x0 */
uint32_t initial_pc; /* Loaded from 0x4 */
uint8_t *rom;
uint32_t vecbase;
#endif

if (cpu_isar_feature(aa32_lob, cpu)) {
/*
Expand Down Expand Up @@ -324,6 +338,8 @@ static void arm_cpu_reset(DeviceState *dev)
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
}

#ifndef CONFIG_USER_ONLY
/* Unlike A/R profile, M profile defines the reset LR value */
env->regs[14] = 0xffffffff;

Expand Down Expand Up @@ -352,14 +368,19 @@ static void arm_cpu_reset(DeviceState *dev)
env->regs[13] = initial_msp & 0xFFFFFFFC;
env->regs[15] = initial_pc & ~1;
env->thumb = initial_pc & 1;
}

/* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
* executing as AArch32 then check if highvecs are enabled and
* adjust the PC accordingly.
*/
if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
env->regs[15] = 0xFFFF0000;
#else
/*
* For user mode we run non-secure and with access to the FPU.
* The FPU context is active (ie does not need further setup)
* and is owned by non-secure.
*/
env->v7m.secure = false;
env->v7m.nsacr = 0xcff;
env->v7m.cpacr[M_REG_NS] = 0xf0ffff;
env->v7m.fpccr[M_REG_S] &=
~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK);
env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
#endif
}

/* M profile requires that reset clears the exclusive monitor;
Expand All @@ -368,9 +389,6 @@ static void arm_cpu_reset(DeviceState *dev)
*/
arm_clear_exclusive(env);

env->vfp.xregs[ARM_VFP_FPEXC] = 0;
#endif

if (arm_feature(env, ARM_FEATURE_PMSA)) {
if (cpu->pmsav7_dregion > 0) {
if (arm_feature(env, ARM_FEATURE_V8)) {
Expand Down Expand Up @@ -1095,8 +1113,8 @@ static void arm_cpu_initfn(Object *obj)
cpu->psci_version = 1; /* By default assume PSCI v0.1 */
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;

if (tcg_enabled()) {
cpu->psci_version = 2; /* TCG implements PSCI 0.2 */
if (tcg_enabled() || hvf_enabled()) {
cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
}
}

Expand Down Expand Up @@ -1400,8 +1418,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* this is the first point where we can report it.
*/
if (cpu->host_cpu_probe_failed) {
if (!kvm_enabled()) {
error_setg(errp, "The 'host' CPU type can only be used with KVM");
if (!kvm_enabled() && !hvf_enabled()) {
error_setg(errp, "The 'host' CPU type can only be used with KVM or HVF");
} else {
error_setg(errp, "Failed to retrieve host CPU features");
}
Expand Down Expand Up @@ -2061,15 +2079,19 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
#endif /* CONFIG_TCG */
}

#ifdef CONFIG_KVM
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
static void arm_host_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);

#ifdef CONFIG_KVM
kvm_arm_set_cpu_features_from_host(cpu);
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
aarch64_add_sve_properties(obj);
}
#else
hvf_arm_set_cpu_features_from_host(cpu);
#endif
arm_cpu_post_init(obj);
}

Expand Down Expand Up @@ -2129,7 +2151,7 @@ static void arm_cpu_register_types(void)
{
type_register_static(&arm_cpu_type_info);

#ifdef CONFIG_KVM
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
type_register_static(&host_arm_cpu_type_info);
#endif
}
Expand Down
6 changes: 5 additions & 1 deletion target/arm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3015,6 +3015,8 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
#define CPU_RESOLVING_TYPE TYPE_ARM_CPU

#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU

#define cpu_signal_handler cpu_arm_signal_handler
#define cpu_list arm_cpu_list

Expand Down Expand Up @@ -3439,7 +3441,7 @@ typedef ARMCPU ArchCPU;
* | TBFLAG_AM32 | +-----+----------+
* | | |TBFLAG_M32|
* +-------------+----------------+----------+
* 31 23 5 4 0
* 31 23 6 5 0
*
* Unless otherwise noted, these bits are cached in env->hflags.
*/
Expand Down Expand Up @@ -3497,6 +3499,8 @@ FIELD(TBFLAG_M32, LSPACT, 2, 1) /* Not cached. */
FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
/* Set if FPCCR.S does not match current security state */
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */

/*
* Bit usage when in AArch64 state
Expand Down
Loading

0 comments on commit 81ceb36

Please sign in to comment.