mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -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/Makefile.objs
|
||||||
F: accel/stubs/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
|
X86 HVF CPUs
|
||||||
M: Cameron Esfahani <dirty@apple.com>
|
M: Cameron Esfahani <dirty@apple.com>
|
||||||
M: Roman Bolshakov <r.bolshakov@yadro.com>
|
M: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||||
|
|||||||
@@ -60,6 +60,10 @@
|
|||||||
|
|
||||||
HVFState *hvf_state;
|
HVFState *hvf_state;
|
||||||
|
|
||||||
|
#ifdef __aarch64__
|
||||||
|
#define HV_VM_DEFAULT NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Memory slots */
|
/* Memory slots */
|
||||||
|
|
||||||
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
|
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);
|
pthread_sigmask(SIG_BLOCK, NULL, &set);
|
||||||
sigdelset(&set, SIG_IPI);
|
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);
|
r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
|
||||||
|
#endif
|
||||||
cpu->vcpu_dirty = 1;
|
cpu->vcpu_dirty = 1;
|
||||||
assert_hvf_ok(r);
|
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);
|
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
|
||||||
|
|
||||||
ops->create_vcpu_thread = hvf_start_vcpu_thread;
|
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_reset = hvf_cpu_synchronize_post_reset;
|
||||||
ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
|
ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
|
||||||
|
|||||||
@@ -11,7 +11,11 @@
|
|||||||
#ifndef HVF_INT_H
|
#ifndef HVF_INT_H
|
||||||
#define HVF_INT_H
|
#define HVF_INT_H
|
||||||
|
|
||||||
|
#ifdef __aarch64__
|
||||||
|
#include <Hypervisor/Hypervisor.h>
|
||||||
|
#else
|
||||||
#include <Hypervisor/hv.h>
|
#include <Hypervisor/hv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* hvf_slot flags */
|
/* hvf_slot flags */
|
||||||
#define HVF_SLOT_LOG (1 << 0)
|
#define HVF_SLOT_LOG (1 << 0)
|
||||||
@@ -40,11 +44,14 @@ struct HVFState {
|
|||||||
int num_slots;
|
int num_slots;
|
||||||
|
|
||||||
hvf_vcpu_caps *hvf_caps;
|
hvf_vcpu_caps *hvf_caps;
|
||||||
|
uint64_t vtimer_offset;
|
||||||
};
|
};
|
||||||
extern HVFState *hvf_state;
|
extern HVFState *hvf_state;
|
||||||
|
|
||||||
struct hvf_vcpu_state {
|
struct hvf_vcpu_state {
|
||||||
int fd;
|
uint64_t fd;
|
||||||
|
void *exit;
|
||||||
|
bool vtimer_masked;
|
||||||
};
|
};
|
||||||
|
|
||||||
void assert_hvf_ok(hv_return_t ret);
|
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);
|
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
|
||||||
int hvf_put_registers(CPUState *);
|
int hvf_put_registers(CPUState *);
|
||||||
int hvf_get_registers(CPUState *);
|
int hvf_get_registers(CPUState *);
|
||||||
|
void hvf_kick_vcpu_thread(CPUState *cpu);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2169,6 +2169,7 @@ if have_system or have_user
|
|||||||
'accel/tcg',
|
'accel/tcg',
|
||||||
'hw/core',
|
'hw/core',
|
||||||
'target/arm',
|
'target/arm',
|
||||||
|
'target/arm/hvf',
|
||||||
'target/hppa',
|
'target/hppa',
|
||||||
'target/i386',
|
'target/i386',
|
||||||
'target/i386/kvm',
|
'target/i386/kvm',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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.h"
|
||||||
#include "sysemu/hvf_int.h"
|
#include "sysemu/hvf_int.h"
|
||||||
#include "sysemu/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
|
#include "sysemu/cpus.h"
|
||||||
#include "hvf-i386.h"
|
#include "hvf-i386.h"
|
||||||
#include "vmcs.h"
|
#include "vmcs.h"
|
||||||
#include "vmx.h"
|
#include "vmx.h"
|
||||||
@@ -206,6 +207,11 @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
|
|||||||
return env->apic_bus_freq != 0;
|
return env->apic_bus_freq != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hvf_kick_vcpu_thread(CPUState *cpu)
|
||||||
|
{
|
||||||
|
cpus_kick_thread(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
int hvf_arch_init(void)
|
int hvf_arch_init(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user