|
@@ -20,18 +20,60 @@
|
|
|
#include <asm/kvm_ppc.h>
|
|
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
-void doorbell_setup_this_cpu(void)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Doorbells must only be used if CPU_FTR_DBELL is available.
|
|
|
+ * msgsnd is used in HV, and msgsndp is used in !HV.
|
|
|
+ *
|
|
|
+ * These should be used by platform code that is aware of restrictions.
|
|
|
+ * Other arch code should use ->cause_ipi.
|
|
|
+ *
|
|
|
+ * doorbell_global_ipi() sends a dbell to any target CPU.
|
|
|
+ * Must be used only by architectures that address msgsnd target
|
|
|
+ * by PIR/get_hard_smp_processor_id.
|
|
|
+ */
|
|
|
+void doorbell_global_ipi(int cpu)
|
|
|
{
|
|
|
- unsigned long tag = mfspr(SPRN_DOORBELL_CPUTAG) & PPC_DBELL_TAG_MASK;
|
|
|
+ u32 tag = get_hard_smp_processor_id(cpu);
|
|
|
|
|
|
- smp_muxed_ipi_set_data(smp_processor_id(), tag);
|
|
|
+ kvmppc_set_host_ipi(cpu, 1);
|
|
|
+ /* Order previous accesses vs. msgsnd, which is treated as a store */
|
|
|
+ mb();
|
|
|
+ ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
|
|
|
}
|
|
|
|
|
|
-void doorbell_cause_ipi(int cpu, unsigned long data)
|
|
|
+/*
|
|
|
+ * doorbell_core_ipi() sends a dbell to a target CPU in the same core.
|
|
|
+ * Must be used only by architectures that address msgsnd target
|
|
|
+ * by TIR/cpu_thread_in_core.
|
|
|
+ */
|
|
|
+void doorbell_core_ipi(int cpu)
|
|
|
{
|
|
|
+ u32 tag = cpu_thread_in_core(cpu);
|
|
|
+
|
|
|
+ kvmppc_set_host_ipi(cpu, 1);
|
|
|
/* Order previous accesses vs. msgsnd, which is treated as a store */
|
|
|
mb();
|
|
|
- ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, data);
|
|
|
+ ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Attempt to cause a core doorbell if destination is on the same core.
|
|
|
+ * Returns 1 on success, 0 on failure.
|
|
|
+ */
|
|
|
+int doorbell_try_core_ipi(int cpu)
|
|
|
+{
|
|
|
+ int this_cpu = get_cpu();
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu))) {
|
|
|
+ doorbell_core_ipi(cpu);
|
|
|
+ ret = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ put_cpu();
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
void doorbell_exception(struct pt_regs *regs)
|