arm: Add an option to turn on/off vPMU support
This patch adds a pmu=[on/off] option to enable/disable vPMU support in guest vCPU. It allows virt tools, such as libvirt, to determine the exsitence of vPMU and configure it. Note this option is only available for cortex-a57/cortex-53/ host CPUs, but unavailable on ARMv7 and other processors. Also even though "pmu=" option is available for TCG mode, setting it doesn't turn PMU on. Signed-off-by: Wei Huang <wei@redhat.com> Reviewed-by: Andrew Jones <drjones@redhat.com> Message-id: 1477463301-17175-2-git-send-email-wei@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									d1df5cf363
								
							
						
					
					
						commit
						929e754d5a
					
				@ -594,7 +594,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
 | 
			
		||||
        gicc->uid = i;
 | 
			
		||||
        gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
 | 
			
		||||
 | 
			
		||||
        if (armcpu->has_pmu) {
 | 
			
		||||
        if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
 | 
			
		||||
            gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -490,7 +490,7 @@ static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype)
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(cpu) {
 | 
			
		||||
        armcpu = ARM_CPU(cpu);
 | 
			
		||||
        if (!armcpu->has_pmu ||
 | 
			
		||||
        if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||
 | 
			
		||||
            !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qemu/osdep.h"
 | 
			
		||||
#include "qemu/error-report.h"
 | 
			
		||||
#include "qapi/error.h"
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "internals.h"
 | 
			
		||||
@ -496,6 +497,10 @@ static Property arm_cpu_rvbar_property =
 | 
			
		||||
static Property arm_cpu_has_el3_property =
 | 
			
		||||
            DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
 | 
			
		||||
 | 
			
		||||
/* use property name "pmu" to match other archs and virt tools */
 | 
			
		||||
static Property arm_cpu_has_pmu_property =
 | 
			
		||||
            DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
 | 
			
		||||
 | 
			
		||||
static Property arm_cpu_has_mpu_property =
 | 
			
		||||
            DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
 | 
			
		||||
 | 
			
		||||
@ -539,6 +544,11 @@ static void arm_cpu_post_init(Object *obj)
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
 | 
			
		||||
        qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property,
 | 
			
		||||
                                 &error_abort);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) {
 | 
			
		||||
        qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
 | 
			
		||||
                                 &error_abort);
 | 
			
		||||
@ -677,6 +687,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
			
		||||
        cpu->id_aa64pfr0 &= ~0xf000;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!cpu->has_pmu || !kvm_enabled()) {
 | 
			
		||||
        cpu->has_pmu = false;
 | 
			
		||||
        unset_feature(env, ARM_FEATURE_PMU);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!arm_feature(env, ARM_FEATURE_EL2)) {
 | 
			
		||||
        /* Disable the hypervisor feature bits in the processor feature
 | 
			
		||||
         * registers if we don't have EL2. These are id_pfr1[15:12] and
 | 
			
		||||
 | 
			
		||||
@ -1124,6 +1124,7 @@ enum arm_features {
 | 
			
		||||
    ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
 | 
			
		||||
    ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
 | 
			
		||||
    ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
 | 
			
		||||
    ARM_FEATURE_PMU, /* has PMU support */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int arm_feature(CPUARMState *env, int feature)
 | 
			
		||||
 | 
			
		||||
@ -111,6 +111,7 @@ static void aarch64_a57_initfn(Object *obj)
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_CRC);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_EL3);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_PMU);
 | 
			
		||||
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
 | 
			
		||||
    cpu->midr = 0x411fd070;
 | 
			
		||||
    cpu->revidr = 0x00000000;
 | 
			
		||||
@ -166,6 +167,7 @@ static void aarch64_a53_initfn(Object *obj)
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_CRC);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_EL3);
 | 
			
		||||
    set_feature(&cpu->env, ARM_FEATURE_PMU);
 | 
			
		||||
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
 | 
			
		||||
    cpu->midr = 0x410fd034;
 | 
			
		||||
    cpu->revidr = 0x00000000;
 | 
			
		||||
 | 
			
		||||
@ -428,6 +428,11 @@ static inline void set_feature(uint64_t *features, int feature)
 | 
			
		||||
    *features |= 1ULL << feature;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void unset_feature(uint64_t *features, int feature)
 | 
			
		||||
{
 | 
			
		||||
    *features &= ~(1ULL << feature);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
 | 
			
		||||
{
 | 
			
		||||
    /* Identify the feature bits corresponding to the host CPU, and
 | 
			
		||||
@ -469,6 +474,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
 | 
			
		||||
    set_feature(&features, ARM_FEATURE_VFP4);
 | 
			
		||||
    set_feature(&features, ARM_FEATURE_NEON);
 | 
			
		||||
    set_feature(&features, ARM_FEATURE_AARCH64);
 | 
			
		||||
    set_feature(&features, ARM_FEATURE_PMU);
 | 
			
		||||
 | 
			
		||||
    ahcc->features = features;
 | 
			
		||||
 | 
			
		||||
@ -482,6 +488,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 | 
			
		||||
    int ret;
 | 
			
		||||
    uint64_t mpidr;
 | 
			
		||||
    ARMCPU *cpu = ARM_CPU(cs);
 | 
			
		||||
    CPUARMState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
 | 
			
		||||
        !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
 | 
			
		||||
@ -501,10 +508,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
 | 
			
		||||
    if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
 | 
			
		||||
        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
 | 
			
		||||
    }
 | 
			
		||||
    if (kvm_irqchip_in_kernel() &&
 | 
			
		||||
        kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
 | 
			
		||||
        cpu->has_pmu = true;
 | 
			
		||||
    if (!kvm_irqchip_in_kernel() ||
 | 
			
		||||
        !kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
 | 
			
		||||
            cpu->has_pmu = false;
 | 
			
		||||
    }
 | 
			
		||||
    if (cpu->has_pmu) {
 | 
			
		||||
        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
 | 
			
		||||
    } else {
 | 
			
		||||
        unset_feature(&env->features, ARM_FEATURE_PMU);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do KVM_ARM_VCPU_INIT ioctl */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user