kvm_arch_vcpu_load(vcpu, smp_processor_id());
        preempt_enable();
+
+       kvm_pmu_nested_transition(vcpu);
 }
 
 static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2,
        kvm_arch_vcpu_load(vcpu, smp_processor_id());
        preempt_enable();
 
+       kvm_pmu_nested_transition(vcpu);
+
        return 1;
 }
 
 
 
        return u64_replace_bits(pmcr, vcpu->kvm->arch.pmcr_n, ARMV8_PMU_PMCR_N);
 }
+
+void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu)
+{
+       bool reprogrammed = false;
+       unsigned long mask;
+       int i;
+
+       if (!kvm_vcpu_has_pmu(vcpu))
+               return;
+
+       mask = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
+       for_each_set_bit(i, &mask, 32) {
+               struct kvm_pmc *pmc = kvm_vcpu_idx_to_pmc(vcpu, i);
+
+               /*
+                * We only need to reconfigure events where the filter is
+                * different at EL1 vs. EL2, as we're multiplexing the true EL1
+                * event filter bit for nested.
+                */
+               if (kvm_pmc_counts_at_el1(pmc) == kvm_pmc_counts_at_el2(pmc))
+                       continue;
+
+               kvm_pmu_create_perf_event(pmc);
+               reprogrammed = true;
+       }
+
+       if (reprogrammed)
+               kvm_vcpu_pmu_restore_guest(vcpu);
+}
 
 
 u64 kvm_vcpu_read_pmcr(struct kvm_vcpu *vcpu);
 bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx);
+void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu);
 #else
 struct kvm_pmu {
 };
        return false;
 }
 
+static inline void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu) {}
+
 #endif
 
 #endif