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

Unverified Commit f99fb607 authored by Atish Patra's avatar Atish Patra Committed by Palmer Dabbelt
Browse files

RISC-V: Use Linux logical CPU number instead of hartid



Setup the cpu_logical_map during boot. Moreover, every SBI call
and PLIC context are based on the physical hartid. Use the logical
CPU to hartid mapping to pass correct hartid to respective functions.

Signed-off-by: default avatarAtish Patra <atish.patra@wdc.com>
Reviewed-by: default avatarAnup Patel <anup@brainfault.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarPalmer Dabbelt <palmer@sifive.com>
parent 6825c7a8
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define _ASM_RISCV_TLBFLUSH_H

#include <linux/mm_types.h>
#include <asm/smp.h>

/*
 * Flush entire local TLB.  'sfence.vma' implicitly fences with the instruction
@@ -49,13 +50,22 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,

#include <asm/sbi.h>

static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start,
				     unsigned long size)
{
	struct cpumask hmask;

	cpumask_clear(&hmask);
	riscv_cpuid_to_hartid_mask(cmask, &hmask);
	sbi_remote_sfence_vma(hmask.bits, start, size);
}

#define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1)
#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
#define flush_tlb_range(vma, start, end) \
	sbi_remote_sfence_vma(mm_cpumask((vma)->vm_mm)->bits, \
			      start, (end) - (start))
	remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start))
#define flush_tlb_mm(mm) \
	sbi_remote_sfence_vma(mm_cpumask(mm)->bits, 0, -1)
	remote_sfence_vma(mm_cpumask(mm), 0, -1)

#endif /* CONFIG_SMP */

+5 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <asm/smp.h>

/*
 * Returns the hart ID of the given device tree node, or -1 if the device tree
@@ -138,11 +139,12 @@ static void c_stop(struct seq_file *m, void *v)

static int c_show(struct seq_file *m, void *v)
{
	unsigned long hart_id = (unsigned long)v - 1;
	struct device_node *node = of_get_cpu_node(hart_id, NULL);
	unsigned long cpu_id = (unsigned long)v - 1;
	struct device_node *node = of_get_cpu_node(cpuid_to_hartid_map(cpu_id),
						   NULL);
	const char *compat, *isa, *mmu;

	seq_printf(m, "hart\t: %lu\n", hart_id);
	seq_printf(m, "hart\t: %lu\n", cpu_id);
	if (!of_property_read_string(node, "riscv,isa", &isa))
		print_isa(m, isa);
	if (!of_property_read_string(node, "mmu-type", &mmu))
+3 −1
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ ENTRY(_start)
	/* Save hart ID and DTB physical address */
	mv s0, a0
	mv s1, a1
	la a2, boot_cpu_hartid
	REG_S a0, (a2)

	/* Initialize page tables and relocate to virtual addresses */
	la sp, init_thread_union + THREAD_SIZE
@@ -55,7 +57,7 @@ ENTRY(_start)

	/* Restore C environment */
	la tp, init_task
	sw s0, TASK_TI_CPU(tp)
	sw zero, TASK_TI_CPU(tp)

	la sp, init_thread_union
	li a0, ASM_THREAD_SIZE
+6 −0
Original line number Diff line number Diff line
@@ -81,11 +81,17 @@ EXPORT_SYMBOL(empty_zero_page);

/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;

unsigned long __cpuid_to_hartid_map[NR_CPUS] = {
	[0 ... NR_CPUS-1] = INVALID_HARTID
};

void __init smp_setup_processor_id(void)
{
	cpuid_to_hartid_map(0) = boot_cpu_hartid;
}

#ifdef CONFIG_BLK_DEV_INITRD
static void __init setup_initrd(void)
{
+15 −9
Original line number Diff line number Diff line
@@ -97,14 +97,18 @@ void riscv_software_interrupt(void)
static void
send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
{
	int i;
	int cpuid, hartid;
	struct cpumask hartid_mask;

	cpumask_clear(&hartid_mask);
	mb();
	for_each_cpu(i, to_whom)
		set_bit(operation, &ipi_data[i].bits);

	for_each_cpu(cpuid, to_whom) {
		set_bit(operation, &ipi_data[cpuid].bits);
		hartid = cpuid_to_hartid_map(cpuid);
		cpumask_set_cpu(hartid, &hartid_mask);
	}
	mb();
	sbi_send_ipi(cpumask_bits(to_whom));
	sbi_send_ipi(cpumask_bits(&hartid_mask));
}

void arch_send_call_function_ipi_mask(struct cpumask *mask)
@@ -146,7 +150,7 @@ void smp_send_reschedule(int cpu)
void flush_icache_mm(struct mm_struct *mm, bool local)
{
	unsigned int cpu;
	cpumask_t others, *mask;
	cpumask_t others, hmask, *mask;

	preempt_disable();

@@ -164,9 +168,11 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
	 */
	cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
	local |= cpumask_empty(&others);
	if (mm != current->active_mm || !local)
		sbi_remote_fence_i(others.bits);
	else {
	if (mm != current->active_mm || !local) {
		cpumask_clear(&hmask);
		riscv_cpuid_to_hartid_mask(&others, &hmask);
		sbi_remote_fence_i(hmask.bits);
	} else {
		/*
		 * It's assumed that at least one strongly ordered operation is
		 * performed on this hart between setting a hart's cpumask bit
Loading