Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9062d888 authored by Fernando Luis [** ISO-8859-1 charset **] VzquezCao's avatar Fernando Luis [** ISO-8859-1 charset **] VzquezCao Committed by Andi Kleen
Browse files

[PATCH] x86-64: __send_IPI_dest_field - x86_64



Implement __send_IPI_dest_field which can be used to send IPIs when the
"destination shorthand" field of the ICR is set to 00 (destination
field). Use it whenever possible.

Signed-off-by: default avatarFernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 45ae5e96
Loading
Loading
Loading
Loading
+1 −22
Original line number Diff line number Diff line
@@ -61,31 +61,10 @@ static void flat_init_apic_ldr(void)
static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
{
	unsigned long mask = cpus_addr(cpumask)[0];
	unsigned long cfg;
	unsigned long flags;

	local_irq_save(flags);

	/*
	 * Wait for idle.
	 */
	apic_wait_icr_idle();

	/*
	 * prepare target chip field
	 */
	cfg = __prepare_ICR2(mask);
	apic_write(APIC_ICR2, cfg);

	/*
	 * program the ICR
	 */
	cfg = __prepare_ICR(0, vector, APIC_DEST_LOGICAL);

	/*
	 * Send the IPI. The write to APIC_ICR fires this off.
	 */
	apic_write(APIC_ICR, cfg);
	__send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
	local_irq_restore(flags);
}

+32 −22
Original line number Diff line number Diff line
@@ -74,20 +74,14 @@ static inline void __send_IPI_shortcut(unsigned int shortcut, int vector, unsign
	apic_write(APIC_ICR, cfg);
}


static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
{
	unsigned long cfg, flags;
	unsigned long query_cpu;

/*
	 * Hack. The clustered APIC addressing mode doesn't allow us to send
	 * to an arbitrary mask, so I do a unicast to each CPU instead.
	 * - mbligh
 * This is used to send an IPI with no shorthand notation (the destination is
 * specified in bits 56 to 63 of the ICR).
 */
	local_irq_save(flags);
static inline void __send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
{
	unsigned long cfg;

	for_each_cpu_mask(query_cpu, mask) {
	/*
	 * Wait for idle.
	 */
@@ -96,19 +90,35 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
	/*
	 * prepare target chip field
	 */
		cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]);
	cfg = __prepare_ICR2(mask);
	apic_write(APIC_ICR2, cfg);

	/*
	 * program the ICR
	 */
		cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL);
	cfg = __prepare_ICR(0, vector, dest);

	/*
	 * Send the IPI. The write to APIC_ICR fires this off.
	 */
	apic_write(APIC_ICR, cfg);
}

static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
{
	unsigned long flags;
	unsigned long query_cpu;

	/*
	 * Hack. The clustered APIC addressing mode doesn't allow us to send
	 * to an arbitrary mask, so I do a unicast to each CPU instead.
	 * - mbligh
	 */
	local_irq_save(flags);
	for_each_cpu_mask(query_cpu, mask) {
		__send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
				      vector, APIC_DEST_PHYSICAL);
	}
	local_irq_restore(flags);
}