mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
hw/arm/virt: Implement kvm-steal-time
We add the kvm-steal-time CPU property and implement it for machvirt. A tiny bit of refactoring was also done to allow pmu and pvtime to use the same vcpu device helper functions. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Andrew Jones <drjones@redhat.com> Message-id: 20201001061718.101915-7-drjones@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
05889d15d1
commit
68970d1e0d
10 changed files with 209 additions and 13 deletions
|
@ -17,6 +17,7 @@
|
|||
#include <linux/kvm.h>
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qapi/error.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
@ -397,19 +398,20 @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr)
|
||||
static bool kvm_arm_set_device_attr(CPUState *cs, struct kvm_device_attr *attr,
|
||||
const char *name)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
|
||||
if (err != 0) {
|
||||
error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err));
|
||||
error_report("%s: KVM_HAS_DEVICE_ATTR: %s", name, strerror(-err));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
|
||||
if (err != 0) {
|
||||
error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
|
||||
error_report("%s: KVM_SET_DEVICE_ATTR: %s", name, strerror(-err));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -426,7 +428,7 @@ void kvm_arm_pmu_init(CPUState *cs)
|
|||
if (!ARM_CPU(cs)->has_pmu) {
|
||||
return;
|
||||
}
|
||||
if (!kvm_arm_pmu_set_attr(cs, &attr)) {
|
||||
if (!kvm_arm_set_device_attr(cs, &attr, "PMU")) {
|
||||
error_report("failed to init PMU");
|
||||
abort();
|
||||
}
|
||||
|
@ -443,12 +445,29 @@ void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
|
|||
if (!ARM_CPU(cs)->has_pmu) {
|
||||
return;
|
||||
}
|
||||
if (!kvm_arm_pmu_set_attr(cs, &attr)) {
|
||||
if (!kvm_arm_set_device_attr(cs, &attr, "PMU")) {
|
||||
error_report("failed to set irq for PMU");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa)
|
||||
{
|
||||
struct kvm_device_attr attr = {
|
||||
.group = KVM_ARM_VCPU_PVTIME_CTRL,
|
||||
.attr = KVM_ARM_VCPU_PVTIME_IPA,
|
||||
.addr = (uint64_t)&ipa,
|
||||
};
|
||||
|
||||
if (ARM_CPU(cs)->kvm_steal_time == ON_OFF_AUTO_OFF) {
|
||||
return;
|
||||
}
|
||||
if (!kvm_arm_set_device_attr(cs, &attr, "PVTIME IPA")) {
|
||||
error_report("failed to init PVTIME IPA");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
@ -655,6 +674,36 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
return true;
|
||||
}
|
||||
|
||||
void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp)
|
||||
{
|
||||
bool has_steal_time = kvm_arm_steal_time_supported();
|
||||
|
||||
if (cpu->kvm_steal_time == ON_OFF_AUTO_AUTO) {
|
||||
if (!has_steal_time || !arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||
cpu->kvm_steal_time = ON_OFF_AUTO_OFF;
|
||||
} else {
|
||||
cpu->kvm_steal_time = ON_OFF_AUTO_ON;
|
||||
}
|
||||
} else if (cpu->kvm_steal_time == ON_OFF_AUTO_ON) {
|
||||
if (!has_steal_time) {
|
||||
error_setg(errp, "'kvm-steal-time' cannot be enabled "
|
||||
"on this host");
|
||||
return;
|
||||
} else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||
/*
|
||||
* DEN0057A chapter 2 says "This specification only covers
|
||||
* systems in which the Execution state of the hypervisor
|
||||
* as well as EL1 of virtual machines is AArch64.". And,
|
||||
* to ensure that, the smc/hvc calls are only specified as
|
||||
* smc64/hvc64.
|
||||
*/
|
||||
error_setg(errp, "'kvm-steal-time' cannot be enabled "
|
||||
"for AArch32 guests");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool kvm_arm_aarch32_supported(void)
|
||||
{
|
||||
return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
|
||||
|
@ -665,6 +714,11 @@ bool kvm_arm_sve_supported(void)
|
|||
return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
|
||||
}
|
||||
|
||||
bool kvm_arm_steal_time_supported(void)
|
||||
{
|
||||
return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME);
|
||||
}
|
||||
|
||||
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
|
||||
|
||||
void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue