219c101fa7
Sleep on WFI until the VTIMER is due but allow ourselves to be woken up on IPI. In this implementation IPI is blocked on the CPU thread at startup and pselect() is used to atomically unblock the signal and begin sleeping. The signal is sent unconditionally so there's no need to worry about races between actually sleeping and the "we think we're sleeping" state. It may lead to an extra wakeup but that's better than missing it entirely. Signed-off-by: Peter Collingbourne <pcc@google.com> Signed-off-by: Alexander Graf <agraf@csgraf.de> Acked-by: Roman Bolshakov <r.bolshakov@yadro.com> Reviewed-by: Sergio Lopez <slp@redhat.com> Message-id: 20210916155404.86958-6-agraf@csgraf.de [agraf: Remove unused 'set' variable, always advance PC on WFX trap, support vm stop / continue operations and cntv offsets] Signed-off-by: Alexander Graf <agraf@csgraf.de> Acked-by: Roman Bolshakov <r.bolshakov@yadro.com> Reviewed-by: Sergio Lopez <slp@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
69 lines
1.4 KiB
C
69 lines
1.4 KiB
C
/*
|
|
* QEMU Hypervisor.framework (HVF) support
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
/* header to be included in HVF-specific code */
|
|
|
|
#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)
|
|
|
|
typedef struct hvf_slot {
|
|
uint64_t start;
|
|
uint64_t size;
|
|
uint8_t *mem;
|
|
int slot_id;
|
|
uint32_t flags;
|
|
MemoryRegion *region;
|
|
} hvf_slot;
|
|
|
|
typedef struct hvf_vcpu_caps {
|
|
uint64_t vmx_cap_pinbased;
|
|
uint64_t vmx_cap_procbased;
|
|
uint64_t vmx_cap_procbased2;
|
|
uint64_t vmx_cap_entry;
|
|
uint64_t vmx_cap_exit;
|
|
uint64_t vmx_cap_preemption_timer;
|
|
} hvf_vcpu_caps;
|
|
|
|
struct HVFState {
|
|
AccelState parent;
|
|
hvf_slot slots[32];
|
|
int num_slots;
|
|
|
|
hvf_vcpu_caps *hvf_caps;
|
|
uint64_t vtimer_offset;
|
|
};
|
|
extern HVFState *hvf_state;
|
|
|
|
struct hvf_vcpu_state {
|
|
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
|