mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-03-26 18:22:55 -07:00
hvf: Add Apple Silicon support
With Apple Silicon available to the masses, it's a good time to add support for driving its virtualization extensions from QEMU. This patch adds all necessary architecture specific code to get basic VMs working, including save/restore. Known limitations: - WFI handling is missing (follows in later patch) - No watchpoint/breakpoint support Signed-off-by: Alexander Graf <agraf@csgraf.de> Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com> Reviewed-by: Sergio Lopez <slp@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20210916155404.86958-5-agraf@csgraf.de [PMM: added missing #include] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
ce7f5b1c50
commit
a1477da3dd
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
@@ -376,7 +380,11 @@ static int hvf_init_vcpu(CPUState *cpu)
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &set);
|
||||
sigdelset(&set, 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);
|
||||
|
||||
@@ -452,6 +460,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;
|
||||
|
||||
@@ -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)
|
||||
@@ -40,11 +44,14 @@ 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;
|
||||
};
|
||||
|
||||
void assert_hvf_ok(hv_return_t ret);
|
||||
@@ -55,5 +62,6 @@ 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
|
||||
|
||||
@@ -2169,6 +2169,7 @@ if have_system or have_user
|
||||
'accel/tcg',
|
||||
'hw/core',
|
||||
'target/arm',
|
||||
'target/arm/hvf',
|
||||
'target/hppa',
|
||||
'target/i386',
|
||||
'target/i386/kvm',
|
||||
|
||||
794
target/arm/hvf/hvf.c
Normal file
794
target/arm/hvf/hvf.c
Normal file
File diff suppressed because it is too large
Load Diff
10
target/arm/hvf/trace-events
Normal file
10
target/arm/hvf/trace-events
Normal file
@@ -0,0 +1,10 @@
|
||||
hvf_unhandled_sysreg_read(uint64_t pc, uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2) "unhandled sysreg read at pc=0x%"PRIx64": 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d)"
|
||||
hvf_unhandled_sysreg_write(uint64_t pc, uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2) "unhandled sysreg write at pc=0x%"PRIx64": 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d)"
|
||||
hvf_inject_fiq(void) "injecting FIQ"
|
||||
hvf_inject_irq(void) "injecting IRQ"
|
||||
hvf_data_abort(uint64_t pc, uint64_t va, uint64_t pa, bool isv, bool iswrite, bool s1ptw, uint32_t len, uint32_t srt) "data abort: [pc=0x%"PRIx64" va=0x%016"PRIx64" pa=0x%016"PRIx64" isv=%d iswrite=%d s1ptw=%d len=%d srt=%d]"
|
||||
hvf_sysreg_read(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg read 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d) = 0x%016"PRIx64
|
||||
hvf_sysreg_write(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg write 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d, val=0x%016"PRIx64")"
|
||||
hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64
|
||||
hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
|
||||
hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "sysemu/hvf.h"
|
||||
#include "sysemu/hvf_int.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "hvf-i386.h"
|
||||
#include "vmcs.h"
|
||||
#include "vmx.h"
|
||||
@@ -206,6 +207,11 @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
|
||||
return env->apic_bus_freq != 0;
|
||||
}
|
||||
|
||||
void hvf_kick_vcpu_thread(CPUState *cpu)
|
||||
{
|
||||
cpus_kick_thread(cpu);
|
||||
}
|
||||
|
||||
int hvf_arch_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user