Commit 466d27e4 authored by Marc Zyngier's avatar Marc Zyngier Committed by Paolo Bonzini

KVM: arm64: Simplify the CPUHP logic

For a number of historical reasons, the KVM/arm64 hotplug setup is pretty
complicated, and we have two extra CPUHP notifiers for vGIC and timers.

It looks pretty pointless, and gets in the way of further changes.
So let's just expose some helpers that can be called from the core
CPUHP callback, and get rid of everything else.

This gives us the opportunity to drop a useless notifier entry,
as well as tidy-up the timer enable/disable, which was a bit odd.
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarIsaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20221130230934.1014142-17-seanjc@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3af4a9e6
...@@ -811,12 +811,20 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) ...@@ -811,12 +811,20 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
ptimer->host_timer_irq_flags = host_ptimer_irq_flags; ptimer->host_timer_irq_flags = host_ptimer_irq_flags;
} }
static void kvm_timer_init_interrupt(void *info) void kvm_timer_cpu_up(void)
{ {
enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags); enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags);
if (host_ptimer_irq)
enable_percpu_irq(host_ptimer_irq, host_ptimer_irq_flags); enable_percpu_irq(host_ptimer_irq, host_ptimer_irq_flags);
} }
void kvm_timer_cpu_down(void)
{
disable_percpu_irq(host_vtimer_irq);
if (host_ptimer_irq)
disable_percpu_irq(host_ptimer_irq);
}
int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
{ {
struct arch_timer_context *timer; struct arch_timer_context *timer;
...@@ -976,18 +984,6 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, ...@@ -976,18 +984,6 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu,
preempt_enable(); preempt_enable();
} }
static int kvm_timer_starting_cpu(unsigned int cpu)
{
kvm_timer_init_interrupt(NULL);
return 0;
}
static int kvm_timer_dying_cpu(unsigned int cpu)
{
disable_percpu_irq(host_vtimer_irq);
return 0;
}
static int timer_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) static int timer_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
{ {
if (vcpu) if (vcpu)
...@@ -1185,9 +1181,6 @@ int kvm_timer_hyp_init(bool has_gic) ...@@ -1185,9 +1181,6 @@ int kvm_timer_hyp_init(bool has_gic)
goto out_free_irq; goto out_free_irq;
} }
cpuhp_setup_state(CPUHP_AP_KVM_ARM_TIMER_STARTING,
"kvm/arm/timer:starting", kvm_timer_starting_cpu,
kvm_timer_dying_cpu);
return 0; return 0;
out_free_irq: out_free_irq:
free_percpu_irq(host_vtimer_irq, kvm_get_running_vcpus()); free_percpu_irq(host_vtimer_irq, kvm_get_running_vcpus());
......
...@@ -1677,7 +1677,15 @@ static void _kvm_arch_hardware_enable(void *discard) ...@@ -1677,7 +1677,15 @@ static void _kvm_arch_hardware_enable(void *discard)
int kvm_arch_hardware_enable(void) int kvm_arch_hardware_enable(void)
{ {
int was_enabled = __this_cpu_read(kvm_arm_hardware_enabled);
_kvm_arch_hardware_enable(NULL); _kvm_arch_hardware_enable(NULL);
if (!was_enabled) {
kvm_vgic_cpu_up();
kvm_timer_cpu_up();
}
return 0; return 0;
} }
...@@ -1691,6 +1699,11 @@ static void _kvm_arch_hardware_disable(void *discard) ...@@ -1691,6 +1699,11 @@ static void _kvm_arch_hardware_disable(void *discard)
void kvm_arch_hardware_disable(void) void kvm_arch_hardware_disable(void)
{ {
if (__this_cpu_read(kvm_arm_hardware_enabled)) {
kvm_timer_cpu_down();
kvm_vgic_cpu_down();
}
if (!is_protected_kvm_enabled()) if (!is_protected_kvm_enabled())
_kvm_arch_hardware_disable(NULL); _kvm_arch_hardware_disable(NULL);
} }
......
...@@ -465,17 +465,15 @@ int kvm_vgic_map_resources(struct kvm *kvm) ...@@ -465,17 +465,15 @@ int kvm_vgic_map_resources(struct kvm *kvm)
/* GENERIC PROBE */ /* GENERIC PROBE */
static int vgic_init_cpu_starting(unsigned int cpu) void kvm_vgic_cpu_up(void)
{ {
enable_percpu_irq(kvm_vgic_global_state.maint_irq, 0); enable_percpu_irq(kvm_vgic_global_state.maint_irq, 0);
return 0;
} }
static int vgic_init_cpu_dying(unsigned int cpu) void kvm_vgic_cpu_down(void)
{ {
disable_percpu_irq(kvm_vgic_global_state.maint_irq); disable_percpu_irq(kvm_vgic_global_state.maint_irq);
return 0;
} }
static irqreturn_t vgic_maintenance_handler(int irq, void *data) static irqreturn_t vgic_maintenance_handler(int irq, void *data)
...@@ -584,19 +582,6 @@ int kvm_vgic_hyp_init(void) ...@@ -584,19 +582,6 @@ int kvm_vgic_hyp_init(void)
return ret; return ret;
} }
ret = cpuhp_setup_state(CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
"kvm/arm/vgic:starting",
vgic_init_cpu_starting, vgic_init_cpu_dying);
if (ret) {
kvm_err("Cannot register vgic CPU notifier\n");
goto out_free_irq;
}
kvm_info("vgic interrupt IRQ%d\n", kvm_vgic_global_state.maint_irq); kvm_info("vgic interrupt IRQ%d\n", kvm_vgic_global_state.maint_irq);
return 0; return 0;
out_free_irq:
free_percpu_irq(kvm_vgic_global_state.maint_irq,
kvm_get_running_vcpus());
return ret;
} }
...@@ -104,4 +104,8 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, ...@@ -104,4 +104,8 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu,
u32 timer_get_ctl(struct arch_timer_context *ctxt); u32 timer_get_ctl(struct arch_timer_context *ctxt);
u64 timer_get_cval(struct arch_timer_context *ctxt); u64 timer_get_cval(struct arch_timer_context *ctxt);
/* CPU HP callbacks */
void kvm_timer_cpu_up(void);
void kvm_timer_cpu_down(void);
#endif #endif
...@@ -432,4 +432,8 @@ int vgic_v4_load(struct kvm_vcpu *vcpu); ...@@ -432,4 +432,8 @@ int vgic_v4_load(struct kvm_vcpu *vcpu);
void vgic_v4_commit(struct kvm_vcpu *vcpu); void vgic_v4_commit(struct kvm_vcpu *vcpu);
int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db);
/* CPU HP callbacks */
void kvm_vgic_cpu_up(void);
void kvm_vgic_cpu_down(void);
#endif /* __KVM_ARM_VGIC_H */ #endif /* __KVM_ARM_VGIC_H */
...@@ -188,9 +188,6 @@ enum cpuhp_state { ...@@ -188,9 +188,6 @@ enum cpuhp_state {
CPUHP_AP_TI_GP_TIMER_STARTING, CPUHP_AP_TI_GP_TIMER_STARTING,
CPUHP_AP_HYPERV_TIMER_STARTING, CPUHP_AP_HYPERV_TIMER_STARTING,
CPUHP_AP_KVM_STARTING, CPUHP_AP_KVM_STARTING,
CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
CPUHP_AP_KVM_ARM_VGIC_STARTING,
CPUHP_AP_KVM_ARM_TIMER_STARTING,
/* Must be the last timer callback */ /* Must be the last timer callback */
CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_DUMMY_TIMER_STARTING,
CPUHP_AP_ARM_XEN_STARTING, CPUHP_AP_ARM_XEN_STARTING,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment