Merge branches 'pm-cpufreq', 'pm-sleep' and 'pm-em'
[linux-2.6-microblaze.git] / arch / arm64 / kvm / reset.c
index cba7872..5ce36b0 100644 (file)
@@ -210,10 +210,16 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
  */
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 {
+       struct vcpu_reset_state reset_state;
        int ret;
        bool loaded;
        u32 pstate;
 
+       mutex_lock(&vcpu->kvm->lock);
+       reset_state = vcpu->arch.reset_state;
+       WRITE_ONCE(vcpu->arch.reset_state.reset, false);
+       mutex_unlock(&vcpu->kvm->lock);
+
        /* Reset PMU outside of the non-preemptible section */
        kvm_pmu_vcpu_reset(vcpu);
 
@@ -276,8 +282,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
         * Additional reset state handling that PSCI may have imposed on us.
         * Must be done after all the sys_reg reset.
         */
-       if (vcpu->arch.reset_state.reset) {
-               unsigned long target_pc = vcpu->arch.reset_state.pc;
+       if (reset_state.reset) {
+               unsigned long target_pc = reset_state.pc;
 
                /* Gracefully handle Thumb2 entry point */
                if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
@@ -286,13 +292,11 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
                }
 
                /* Propagate caller endianness */
-               if (vcpu->arch.reset_state.be)
+               if (reset_state.be)
                        kvm_vcpu_set_be(vcpu);
 
                *vcpu_pc(vcpu) = target_pc;
-               vcpu_set_reg(vcpu, 0, vcpu->arch.reset_state.r0);
-
-               vcpu->arch.reset_state.reset = false;
+               vcpu_set_reg(vcpu, 0, reset_state.r0);
        }
 
        /* Reset timer */
@@ -311,31 +315,26 @@ u32 get_kvm_ipa_limit(void)
 
 int kvm_set_ipa_limit(void)
 {
-       unsigned int parange, tgran_2;
+       unsigned int parange;
        u64 mmfr0;
 
        mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
        parange = cpuid_feature_extract_unsigned_field(mmfr0,
                                ID_AA64MMFR0_PARANGE_SHIFT);
+       /*
+        * IPA size beyond 48 bits could not be supported
+        * on either 4K or 16K page size. Hence let's cap
+        * it to 48 bits, in case it's reported as larger
+        * on the system.
+        */
+       if (PAGE_SIZE != SZ_64K)
+               parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48);
 
        /*
         * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
         * Stage-2. If not, things will stop very quickly.
         */
-       switch (PAGE_SIZE) {
-       default:
-       case SZ_4K:
-               tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT;
-               break;
-       case SZ_16K:
-               tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT;
-               break;
-       case SZ_64K:
-               tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT;
-               break;
-       }
-
-       switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) {
+       switch (cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_TGRAN_2_SHIFT)) {
        case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE:
                kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
                return -EINVAL;
@@ -369,7 +368,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type)
        phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
        if (phys_shift) {
                if (phys_shift > kvm_ipa_limit ||
-                   phys_shift < 32)
+                   phys_shift < ARM64_MIN_PARANGE_BITS)
                        return -EINVAL;
        } else {
                phys_shift = KVM_PHYS_SHIFT;