target-arm queue:

* arm/kvm: drop the split between "common KVM support" and
    "64-bit KVM support", since 32-bit Arm KVM no longer exists
  * arm/kvm: clean up APIs to be consistent about CPU arguments
  * Don't implement *32_EL2 registers when EL1 is AArch64 only
  * Restrict DC CVAP & DC CVADP instructions to TCG accel
  * Restrict TCG specific helpers
  * Propagate MDCR_EL2.HPMN into PMCR_EL0.N
  * Include missing 'exec/exec-all.h' header
  * fsl-imx: add simple RTC emulation for i.MX6 and i.MX7 boards
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmWB6o0ZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3mxMEACRpRxJ81pLs8fFYC5BgRhU
 BCxr+ZqarBygzsH9YWUN2TFFKlEZi7mLu6lzFsfN/qEmYCg8VslPbulQHqcGkx51
 kVxXFp/KuGlKt4zGRagZUJxgYAwwU5mnK6dTZT5/ZF6yWX67dXn8V7MP9lqqEPw5
 5gut7Mu4f7MiAQbwZY1CWP+iu5uZmdsBuKxA6zkxOWJh/A1SfaqQRO6xVQttLAxS
 DPMTpQGmwPS4I+3gGNnqlSu6etp2tdy2K0cW3fhMp6hx70uNMHmFNzRhT/6TaKka
 9AqXQsFHQiFXDGAm6PmCvfQI6KpLljDyNL/TuUkQWi72bGEHjUsJAdG0aXVOa30W
 uC7vuJkdZrP/t5P1AkZhWQUrlawDRV2YHNDD+gY4fxJL/STkGyU6M8R1nm1J+InN
 n0SeK0VHRC6DRPXCMQhC5QwKUH6ZjFZRs/r2opTu9p+ThQAQRmZBiVfdISCDMYnN
 DCiSb78gIFaUkwtiP44qq8MJQjsHnXtTD1Akqyo2fXSKs66jDK9Gnc8gENYdpghe
 7V36bOp6scROHOB2a/r8gT42RKzSN6uh6xByaaToza63/bPgvHnn8vvQQbB01AgX
 zJC1xs3dwY8JMyqDefda0K0NDPS8TzNsXYmgxxxcQJpUvB4VVjet9VIMF3T+d8HO
 Pas41Z1gsQY+rcaRk/9mPA==
 =GWIA
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20231219' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * arm/kvm: drop the split between "common KVM support" and
   "64-bit KVM support", since 32-bit Arm KVM no longer exists
 * arm/kvm: clean up APIs to be consistent about CPU arguments
 * Don't implement *32_EL2 registers when EL1 is AArch64 only
 * Restrict DC CVAP & DC CVADP instructions to TCG accel
 * Restrict TCG specific helpers
 * Propagate MDCR_EL2.HPMN into PMCR_EL0.N
 * Include missing 'exec/exec-all.h' header
 * fsl-imx: add simple RTC emulation for i.MX6 and i.MX7 boards

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmWB6o0ZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3mxMEACRpRxJ81pLs8fFYC5BgRhU
# BCxr+ZqarBygzsH9YWUN2TFFKlEZi7mLu6lzFsfN/qEmYCg8VslPbulQHqcGkx51
# kVxXFp/KuGlKt4zGRagZUJxgYAwwU5mnK6dTZT5/ZF6yWX67dXn8V7MP9lqqEPw5
# 5gut7Mu4f7MiAQbwZY1CWP+iu5uZmdsBuKxA6zkxOWJh/A1SfaqQRO6xVQttLAxS
# DPMTpQGmwPS4I+3gGNnqlSu6etp2tdy2K0cW3fhMp6hx70uNMHmFNzRhT/6TaKka
# 9AqXQsFHQiFXDGAm6PmCvfQI6KpLljDyNL/TuUkQWi72bGEHjUsJAdG0aXVOa30W
# uC7vuJkdZrP/t5P1AkZhWQUrlawDRV2YHNDD+gY4fxJL/STkGyU6M8R1nm1J+InN
# n0SeK0VHRC6DRPXCMQhC5QwKUH6ZjFZRs/r2opTu9p+ThQAQRmZBiVfdISCDMYnN
# DCiSb78gIFaUkwtiP44qq8MJQjsHnXtTD1Akqyo2fXSKs66jDK9Gnc8gENYdpghe
# 7V36bOp6scROHOB2a/r8gT42RKzSN6uh6xByaaToza63/bPgvHnn8vvQQbB01AgX
# zJC1xs3dwY8JMyqDefda0K0NDPS8TzNsXYmgxxxcQJpUvB4VVjet9VIMF3T+d8HO
# Pas41Z1gsQY+rcaRk/9mPA==
# =GWIA
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 19 Dec 2023 14:10:05 EST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20231219' of https://git.linaro.org/people/pmaydell/qemu-arm: (43 commits)
  fsl-imx: add simple RTC emulation for i.MX6 and i.MX7 boards
  target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N
  target/arm/tcg: Including missing 'exec/exec-all.h' header
  target/arm: Restrict DC CVAP & DC CVADP instructions to TCG accel
  target/arm: Restrict TCG specific helpers
  target/arm: Don't implement *32_EL2 registers when EL1 is AArch64 only
  target/arm/kvm: Have kvm_arm_hw_debug_active take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_handle_debug take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_handle_dabt_nisv take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_verify_ext_dabt_pending take a ARMCPU arg
  target/arm/kvm: Have kvm_arm_[get|put]_virtual_time take ARMCPU argument
  target/arm/kvm: Have kvm_arm_vcpu_finalize take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_vcpu_init take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_pmu_set_irq take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_pmu_init take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_pvtime_init take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_set_device_attr take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_sve_get_vls take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_sve_set_vls take a ARMCPU argument
  target/arm/kvm: Have kvm_arm_add_vcpu_properties take a ARMCPU argument
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-12-20 09:39:45 -05:00
commit 63d6632512
16 changed files with 1592 additions and 1656 deletions

View File

@ -98,7 +98,7 @@ bool kvm_allowed;
bool kvm_readonly_mem_allowed;
bool kvm_vm_attributes_allowed;
bool kvm_msi_use_devid;
bool kvm_has_guest_debug;
static bool kvm_has_guest_debug;
static int kvm_sstep_flags;
static bool kvm_immediate_exit;
static hwaddr kvm_max_slot_size = ~0;

View File

@ -1998,13 +1998,14 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
if (pmu) {
assert(arm_feature(&ARM_CPU(cpu)->env, ARM_FEATURE_PMU));
if (kvm_irqchip_in_kernel()) {
kvm_arm_pmu_set_irq(cpu, VIRTUAL_PMU_IRQ);
kvm_arm_pmu_set_irq(ARM_CPU(cpu), VIRTUAL_PMU_IRQ);
}
kvm_arm_pmu_init(cpu);
kvm_arm_pmu_init(ARM_CPU(cpu));
}
if (steal_time) {
kvm_arm_pvtime_init(cpu, pvtime_reg_base +
cpu->cpu_index * PVTIME_SIZE_PER_CPU);
kvm_arm_pvtime_init(ARM_CPU(cpu), pvtime_reg_base
+ cpu->cpu_index
* PVTIME_SIZE_PER_CPU);
}
}
} else {

View File

@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "hw/intc/arm_gicv3_its_common.h"
#include "hw/qdev-properties.h"
#include "sysemu/runstate.h"

View File

@ -13,28 +13,100 @@
*/
#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/timer.h"
#include "migration/vmstate.h"
#include "hw/misc/imx7_snvs.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
#include "sysemu/sysemu.h"
#include "sysemu/rtc.h"
#include "sysemu/runstate.h"
#include "trace.h"
#define RTC_FREQ 32768ULL
static const VMStateDescription vmstate_imx7_snvs = {
.name = TYPE_IMX7_SNVS,
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT64(tick_offset, IMX7SNVSState),
VMSTATE_UINT64(lpcr, IMX7SNVSState),
VMSTATE_END_OF_LIST()
}
};
static uint64_t imx7_snvs_get_count(IMX7SNVSState *s)
{
uint64_t ticks = muldiv64(qemu_clock_get_ns(rtc_clock), RTC_FREQ,
NANOSECONDS_PER_SECOND);
return s->tick_offset + ticks;
}
static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
{
trace_imx7_snvs_read(offset, 0);
IMX7SNVSState *s = IMX7_SNVS(opaque);
uint64_t ret = 0;
return 0;
switch (offset) {
case SNVS_LPSRTCMR:
ret = extract64(imx7_snvs_get_count(s), 32, 15);
break;
case SNVS_LPSRTCLR:
ret = extract64(imx7_snvs_get_count(s), 0, 32);
break;
case SNVS_LPCR:
ret = s->lpcr;
break;
}
trace_imx7_snvs_read(offset, ret, size);
return ret;
}
static void imx7_snvs_reset(DeviceState *dev)
{
IMX7SNVSState *s = IMX7_SNVS(dev);
s->lpcr = 0;
}
static void imx7_snvs_write(void *opaque, hwaddr offset,
uint64_t v, unsigned size)
{
const uint32_t value = v;
const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
trace_imx7_snvs_write(offset, v, size);
trace_imx7_snvs_write(offset, value);
IMX7SNVSState *s = IMX7_SNVS(opaque);
if (offset == SNVS_LPCR && ((value & mask) == mask)) {
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
uint64_t new_value = 0, snvs_count = 0;
if (offset == SNVS_LPSRTCMR || offset == SNVS_LPSRTCLR) {
snvs_count = imx7_snvs_get_count(s);
}
switch (offset) {
case SNVS_LPSRTCMR:
new_value = deposit64(snvs_count, 32, 32, v);
break;
case SNVS_LPSRTCLR:
new_value = deposit64(snvs_count, 0, 32, v);
break;
case SNVS_LPCR: {
s->lpcr = v;
const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
if ((v & mask) == mask) {
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
}
break;
}
}
if (offset == SNVS_LPSRTCMR || offset == SNVS_LPSRTCLR) {
s->tick_offset += new_value - snvs_count;
}
}
@ -59,17 +131,24 @@ static void imx7_snvs_init(Object *obj)
{
SysBusDevice *sd = SYS_BUS_DEVICE(obj);
IMX7SNVSState *s = IMX7_SNVS(obj);
struct tm tm;
memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
TYPE_IMX7_SNVS, 0x1000);
sysbus_init_mmio(sd, &s->mmio);
qemu_get_timedate(&tm, 0);
s->tick_offset = mktimegm(&tm) -
qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND;
}
static void imx7_snvs_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->reset = imx7_snvs_reset;
dc->vmsd = &vmstate_imx7_snvs;
dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
}

View File

@ -116,8 +116,8 @@ imx7_gpr_read(uint64_t offset) "addr 0x%08" PRIx64
imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" PRIx64 "value 0x%08" PRIx64
# imx7_snvs.c
imx7_snvs_read(uint64_t offset, uint32_t value) "addr 0x%08" PRIx64 "value 0x%08" PRIx32
imx7_snvs_write(uint64_t offset, uint32_t value) "addr 0x%08" PRIx64 "value 0x%08" PRIx32
imx7_snvs_read(uint64_t offset, uint64_t value, unsigned size) "i.MX SNVS read: offset 0x%08" PRIx64 " value 0x%08" PRIx64 " size %u"
imx7_snvs_write(uint64_t offset, uint64_t value, unsigned size) "i.MX SNVS write: offset 0x%08" PRIx64 " value 0x%08" PRIx64 " size %u"
# mos6522.c
mos6522_set_counter(int index, unsigned int val) "T%d.counter=%d"

View File

@ -20,7 +20,9 @@
enum IMX7SNVSRegisters {
SNVS_LPCR = 0x38,
SNVS_LPCR_TOP = BIT(6),
SNVS_LPCR_DP_EN = BIT(5)
SNVS_LPCR_DP_EN = BIT(5),
SNVS_LPSRTCMR = 0x050, /* Secure Real Time Counter MSB Register */
SNVS_LPSRTCLR = 0x054, /* Secure Real Time Counter LSB Register */
};
#define TYPE_IMX7_SNVS "imx7.snvs"
@ -31,6 +33,9 @@ struct IMX7SNVSState {
SysBusDevice parent_obj;
MemoryRegion mmio;
uint64_t tick_offset;
uint64_t lpcr;
};
#endif /* IMX7_SNVS_H */

View File

@ -1686,7 +1686,7 @@ void arm_cpu_post_init(Object *obj)
}
if (kvm_enabled()) {
kvm_arm_add_vcpu_properties(obj);
kvm_arm_add_vcpu_properties(cpu);
}
#ifndef CONFIG_USER_ONLY

View File

@ -66,7 +66,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
*/
if (kvm_enabled()) {
if (kvm_arm_sve_supported()) {
cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
cpu->sve_vq.supported = kvm_arm_sve_get_vls(cpu);
vq_supported = cpu->sve_vq.supported;
} else {
assert(!cpu_isar_feature(aa64_sve, cpu));

View File

@ -1026,14 +1026,6 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL1_RW, .accessfn = access_tda,
.type = ARM_CP_NOP },
/*
* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
* to save and restore a 32-bit guest's DBGVCR)
*/
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL2_RW, .accessfn = access_tda,
.type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
/*
* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
* Channel but Linux may try to access this register. The 32-bit
@ -1062,6 +1054,18 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },
};
/* These are present only when EL1 supports AArch32 */
static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
/*
* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
* to save and restore a 32-bit guest's DBGVCR)
*/
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL2_RW, .accessfn = access_tda,
.type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
};
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
/* 64 bit access versions of the (dummy) debug registers */
{ .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
@ -1207,6 +1211,9 @@ void define_debug_regs(ARMCPU *cpu)
assert(ctx_cmps <= brps);
define_arm_cp_regs(cpu, debug_cp_reginfo);
if (cpu_isar_feature(aa64_aa32_el1, cpu)) {
define_arm_cp_regs(cpu, debug_aa32_el1_reginfo);
}
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);

View File

@ -1475,6 +1475,22 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
pmu_op_finish(env);
}
static uint64_t pmcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
uint64_t pmcr = env->cp15.c9_pmcr;
/*
* If EL2 is implemented and enabled for the current security state, reads
* of PMCR.N from EL1 or EL0 return the value of MDCR_EL2.HPMN or HDCR.HPMN.
*/
if (arm_current_el(env) <= 1 && arm_is_el2_enabled(env)) {
pmcr &= ~PMCRN_MASK;
pmcr |= (env->cp15.mdcr_el2 & MDCR_HPMN) << PMCRN_SHIFT;
}
return pmcr;
}
static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@ -5698,20 +5714,6 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
.type = ARM_CP_NO_RAW,
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
.access = PL2_RW,
.type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
.access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
.writefn = dacr_write, .raw_writefn = raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
.access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
@ -5746,6 +5748,24 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
};
/* These are present only when EL1 supports AArch32 */
static const ARMCPRegInfo v8_aa32_el1_reginfo[] = {
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
.access = PL2_RW,
.type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
.access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
.writefn = dacr_write, .raw_writefn = raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
.access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
};
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
{
ARMCPU *cpu = env_archcpu(env);
@ -7154,8 +7174,9 @@ static void define_pmu_regs(ARMCPU *cpu)
.fgt = FGT_PMCR_EL0,
.type = ARM_CP_IO | ARM_CP_ALIAS,
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
.accessfn = pmreg_access, .writefn = pmcr_write,
.raw_writefn = raw_write,
.accessfn = pmreg_access,
.readfn = pmcr_read, .raw_readfn = raw_read,
.writefn = pmcr_write, .raw_writefn = raw_write,
};
ARMCPRegInfo pmcr64 = {
.name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
@ -7165,6 +7186,7 @@ static void define_pmu_regs(ARMCPU *cpu)
.type = ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
.resetvalue = cpu->isar.reset_pmcr_el0,
.readfn = pmcr_read, .raw_readfn = raw_read,
.writefn = pmcr_write, .raw_writefn = raw_write,
};
@ -7645,6 +7667,7 @@ static const ARMCPRegInfo rndr_reginfo[] = {
static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
uint64_t value)
{
#ifdef CONFIG_TCG
ARMCPU *cpu = env_archcpu(env);
/* CTR_EL0 System register -> DminLine, bits [19:16] */
uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
@ -7669,6 +7692,10 @@ static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
}
#endif /*CONFIG_USER_ONLY*/
}
#else
/* Handled by hardware accelerator. */
g_assert_not_reached();
#endif /* CONFIG_TCG */
}
static const ARMCPRegInfo dcpop_reg[] = {
@ -8716,6 +8743,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
define_arm_cp_regs(cpu, v8_idregs);
define_arm_cp_regs(cpu, v8_cp_reginfo);
if (cpu_isar_feature(aa64_aa32_el1, cpu)) {
define_arm_cp_regs(cpu, v8_aa32_el1_reginfo);
}
for (i = 4; i < 16; i++) {
/*
@ -10135,61 +10165,6 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
}
}
/* Sign/zero extend */
uint32_t HELPER(sxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(int8_t)x;
res |= (uint32_t)(int8_t)(x >> 16) << 16;
return res;
}
static void handle_possible_div0_trap(CPUARMState *env, uintptr_t ra)
{
/*
* Take a division-by-zero exception if necessary; otherwise return
* to get the usual non-trapping division behaviour (result of 0)
*/
if (arm_feature(env, ARM_FEATURE_M)
&& (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_DIV_0_TRP_MASK)) {
raise_exception_ra(env, EXCP_DIVBYZERO, 0, 1, ra);
}
}
uint32_t HELPER(uxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(uint8_t)x;
res |= (uint32_t)(uint8_t)(x >> 16) << 16;
return res;
}
int32_t HELPER(sdiv)(CPUARMState *env, int32_t num, int32_t den)
{
if (den == 0) {
handle_possible_div0_trap(env, GETPC());
return 0;
}
if (num == INT_MIN && den == -1) {
return INT_MIN;
}
return num / den;
}
uint32_t HELPER(udiv)(CPUARMState *env, uint32_t num, uint32_t den)
{
if (den == 0) {
handle_possible_div0_trap(env, GETPC());
return 0;
}
return num / den;
}
uint32_t HELPER(rbit)(uint32_t x)
{
return revbit32(x);
}
#ifdef CONFIG_USER_ONLY
static void switch_mode(CPUARMState *env, int mode)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,46 +12,10 @@
#define QEMU_KVM_ARM_H
#include "sysemu/kvm.h"
#include "exec/memory.h"
#include "qemu/error-report.h"
#define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1)
/**
* kvm_arm_init_debug() - initialize guest debug capabilities
* @s: KVMState
*
* Should be called only once before using guest debug capabilities.
*/
void kvm_arm_init_debug(KVMState *s);
/**
* kvm_arm_vcpu_init:
* @cs: CPUState
*
* Initialize (or reinitialize) the VCPU by invoking the
* KVM_ARM_VCPU_INIT ioctl with the CPU type and feature
* bitmask specified in the CPUState.
*
* Returns: 0 if success else < 0 error code
*/
int kvm_arm_vcpu_init(CPUState *cs);
/**
* kvm_arm_vcpu_finalize:
* @cs: CPUState
* @feature: feature to finalize
*
* Finalizes the configuration of the specified VCPU feature by
* invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring
* this are documented in the "KVM_ARM_VCPU_FINALIZE" section of
* KVM's API documentation.
*
* Returns: 0 if success else < 0 error code
*/
int kvm_arm_vcpu_finalize(CPUState *cs, int feature);
/**
* kvm_arm_register_device:
* @mr: memory region for this device
@ -73,37 +37,6 @@ int kvm_arm_vcpu_finalize(CPUState *cs, int feature);
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
uint64_t attr, int dev_fd, uint64_t addr_ormask);
/**
* kvm_arm_init_cpreg_list:
* @cpu: ARMCPU
*
* Initialize the ARMCPU cpreg list according to the kernel's
* definition of what CPU registers it knows about (and throw away
* the previous TCG-created cpreg list).
*
* Returns: 0 if success, else < 0 error code
*/
int kvm_arm_init_cpreg_list(ARMCPU *cpu);
/**
* kvm_arm_reg_syncs_via_cpreg_list:
* @regidx: KVM register index
*
* Return true if this KVM register should be synchronized via the
* cpreg list of arbitrary system registers, false if it is synchronized
* by hand using code in kvm_arch_get/put_registers().
*/
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
/**
* kvm_arm_cpreg_level:
* @regidx: KVM register index
*
* Return the level of this coprocessor/system register. Return value is
* either KVM_PUT_RUNTIME_STATE, KVM_PUT_RESET_STATE, or KVM_PUT_FULL_STATE.
*/
int kvm_arm_cpreg_level(uint64_t regidx);
/**
* write_list_to_kvmstate:
* @cpu: ARMCPU
@ -163,34 +96,6 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu);
*/
void kvm_arm_reset_vcpu(ARMCPU *cpu);
/**
* kvm_arm_init_serror_injection:
* @cs: CPUState
*
* Check whether KVM can set guest SError syndrome.
*/
void kvm_arm_init_serror_injection(CPUState *cs);
/**
* kvm_get_vcpu_events:
* @cpu: ARMCPU
*
* Get VCPU related state from kvm.
*
* Returns: 0 if success else < 0 error code
*/
int kvm_get_vcpu_events(ARMCPU *cpu);
/**
* kvm_put_vcpu_events:
* @cpu: ARMCPU
*
* Put VCPU related state to kvm.
*
* Returns: 0 if success else < 0 error code
*/
int kvm_put_vcpu_events(ARMCPU *cpu);
#ifdef CONFIG_KVM
/**
* kvm_arm_create_scratch_host_vcpu:
@ -222,37 +127,15 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
*/
void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
/**
* ARMHostCPUFeatures: information about the host CPU (identified
* by asking the host kernel)
*/
typedef struct ARMHostCPUFeatures {
ARMISARegisters isar;
uint64_t features;
uint32_t target;
const char *dtb_compatible;
} ARMHostCPUFeatures;
/**
* kvm_arm_get_host_cpu_features:
* @ahcf: ARMHostCPUClass to fill in
*
* Probe the capabilities of the host kernel's preferred CPU and fill
* in the ARMHostCPUClass struct accordingly.
*
* Returns true on success and false otherwise.
*/
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
/**
* kvm_arm_sve_get_vls:
* @cs: CPUState
* @cpu: ARMCPU
*
* Get all the SVE vector lengths supported by the KVM host, setting
* the bits corresponding to their length in quadwords minus one
* (vq - 1) up to ARM_MAX_VQ. Return the resulting map.
*/
uint32_t kvm_arm_sve_get_vls(CPUState *cs);
uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
/**
* kvm_arm_set_cpu_features_from_host:
@ -265,12 +148,12 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
/**
* kvm_arm_add_vcpu_properties:
* @obj: The CPU object to add the properties to
* @cpu: The CPU object to add the properties to
*
* Add all KVM specific CPU properties to the CPU object. These
* are the CPU properties with "kvm-" prefixed names.
*/
void kvm_arm_add_vcpu_properties(Object *obj);
void kvm_arm_add_vcpu_properties(ARMCPU *cpu);
/**
* kvm_arm_steal_time_finalize:
@ -282,14 +165,6 @@ void kvm_arm_add_vcpu_properties(Object *obj);
*/
void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp);
/**
* kvm_arm_steal_time_supported:
*
* Returns: true if KVM can enable steal time reporting
* and false otherwise.
*/
bool kvm_arm_steal_time_supported(void);
/**
* kvm_arm_aarch32_supported:
*
@ -323,57 +198,19 @@ bool kvm_arm_sve_supported(void);
*/
int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa);
/**
* kvm_arm_sync_mpstate_to_kvm:
* @cpu: ARMCPU
*
* If supported set the KVM MP_STATE based on QEMU's model.
*
* Returns 0 on success and -1 on failure.
*/
int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu);
/**
* kvm_arm_sync_mpstate_to_qemu:
* @cpu: ARMCPU
*
* If supported get the MP_STATE from KVM and store in QEMU's model.
*
* Returns 0 on success and aborts on failure.
*/
int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
/**
* kvm_arm_get_virtual_time:
* @cs: CPUState
*
* Gets the VCPU's virtual counter and stores it in the KVM CPU state.
*/
void kvm_arm_get_virtual_time(CPUState *cs);
/**
* kvm_arm_put_virtual_time:
* @cs: CPUState
*
* Sets the VCPU's virtual counter to the value stored in the KVM CPU state.
*/
void kvm_arm_put_virtual_time(CPUState *cs);
void kvm_arm_vm_state_change(void *opaque, bool running, RunState state);
int kvm_arm_vgic_probe(void);
void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
void kvm_arm_pmu_init(CPUState *cs);
void kvm_arm_pmu_init(ARMCPU *cpu);
void kvm_arm_pmu_set_irq(ARMCPU *cpu, int irq);
/**
* kvm_arm_pvtime_init:
* @cs: CPUState
* @cpu: ARMCPU
* @ipa: Per-vcpu guest physical base address of the pvtime structures
*
* Initializes PVTIME for the VCPU, setting the PVTIME IPA to @ipa.
*/
void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
void kvm_arm_pvtime_init(ARMCPU *cpu, uint64_t ipa);
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
@ -398,11 +235,6 @@ static inline bool kvm_arm_sve_supported(void)
return false;
}
static inline bool kvm_arm_steal_time_supported(void)
{
return false;
}
/*
* These functions should never actually be called without KVM support.
*/
@ -411,7 +243,7 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
g_assert_not_reached();
}
static inline void kvm_arm_add_vcpu_properties(Object *obj)
static inline void kvm_arm_add_vcpu_properties(ARMCPU *cpu)
{
g_assert_not_reached();
}
@ -426,17 +258,17 @@ static inline int kvm_arm_vgic_probe(void)
g_assert_not_reached();
}
static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
static inline void kvm_arm_pmu_set_irq(ARMCPU *cpu, int irq)
{
g_assert_not_reached();
}
static inline void kvm_arm_pmu_init(CPUState *cs)
static inline void kvm_arm_pmu_init(ARMCPU *cpu)
{
g_assert_not_reached();
}
static inline void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa)
static inline void kvm_arm_pvtime_init(ARMCPU *cpu, uint64_t ipa)
{
g_assert_not_reached();
}
@ -446,48 +278,11 @@ static inline void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp)
g_assert_not_reached();
}
static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)
static inline uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
{
g_assert_not_reached();
}
#endif
/**
* kvm_arm_handle_debug:
* @cs: CPUState
* @debug_exit: debug part of the KVM exit structure
*
* Returns: TRUE if the debug exception was handled.
*/
bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit);
/**
* kvm_arm_hw_debug_active:
* @cs: CPU State
*
* Return: TRUE if any hardware breakpoints in use.
*/
bool kvm_arm_hw_debug_active(CPUState *cs);
/**
* kvm_arm_copy_hw_debug_data:
* @ptr: kvm_guest_debug_arch structure
*
* Copy the architecture specific debug registers into the
* kvm_guest_debug ioctl structure.
*/
struct kvm_guest_debug_arch;
void kvm_arm_copy_hw_debug_data(struct kvm_guest_debug_arch *ptr);
/**
* kvm_arm_verify_ext_dabt_pending:
* @cs: CPUState
*
* Verify the fault status code wrt the Ext DABT injection
*
* Returns: true if the fault status code is as expected, false otherwise
*/
bool kvm_arm_verify_ext_dabt_pending(CPUState *cs);
#endif

View File

@ -8,7 +8,7 @@ arm_ss.add(files(
))
arm_ss.add(zlib)
arm_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c', 'kvm64.c'), if_false: files('kvm-stub.c'))
arm_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'), if_false: files('kvm-stub.c'))
arm_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(

View File

@ -121,6 +121,61 @@ void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
}
}
/* Sign/zero extend */
uint32_t HELPER(sxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(int8_t)x;
res |= (uint32_t)(int8_t)(x >> 16) << 16;
return res;
}
static void handle_possible_div0_trap(CPUARMState *env, uintptr_t ra)
{
/*
* Take a division-by-zero exception if necessary; otherwise return
* to get the usual non-trapping division behaviour (result of 0)
*/
if (arm_feature(env, ARM_FEATURE_M)
&& (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_DIV_0_TRP_MASK)) {
raise_exception_ra(env, EXCP_DIVBYZERO, 0, 1, ra);
}
}
uint32_t HELPER(uxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(uint8_t)x;
res |= (uint32_t)(uint8_t)(x >> 16) << 16;
return res;
}
int32_t HELPER(sdiv)(CPUARMState *env, int32_t num, int32_t den)
{
if (den == 0) {
handle_possible_div0_trap(env, GETPC());
return 0;
}
if (num == INT_MIN && den == -1) {
return INT_MIN;
}
return num / den;
}
uint32_t HELPER(udiv)(CPUARMState *env, uint32_t num, uint32_t den)
{
if (den == 0) {
handle_possible_div0_trap(env, GETPC());
return 0;
}
return num / den;
}
uint32_t HELPER(rbit)(uint32_t x)
{
return revbit32(x);
}
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
{
uint32_t res = a + b;

View File

@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
#include "exec/exec-all.h"
#include "translate.h"
#include "translate-a64.h"
#include "qemu/log.h"