On Tue, 30 Mar 2021 15:40:34 PDT (-0700), Stephen Rothwell wrote:
Hi all,
Today's linux-next merge of the risc-v tree got a conflict in:
arch/riscv/mm/kasan_init.c
between commits:
f3773dd031de ("riscv: Ensure page table writes are flushed when initializing KASAN vmalloc")
78947bdfd752 ("RISC-V: kasan: Declare kasan_shallow_populate() static")
from Linus' tree and commit:
2da073c19641 ("riscv: Cleanup KASAN_VMALLOC support")
from the risc-v tree.
I fixed it up (I think - see below) and can carry the fix as
necessary. This is now fixed as far as linux-next is concerned, but any
non trivial conflicts should be mentioned to your upstream maintainer
when your tree is submitted for merging. You may also want to consider
cooperating with the maintainer of the conflicting tree to minimise any
particularly complex conflicts.
They're my own trees ;)
I'm not so great at reading merge diffs, but the right fix here is to
have the local_flush_tlb_all() after the call to
kasan_shallow_populate_pgd(), just as there is one after
kasan_populate_pgd(). My merge diff looks like this
diff --cc arch/riscv/mm/kasan_init.c
index 2c39f0386673,4f85c6d0ddf8..ec0029097251
--- a/arch/riscv/mm/kasan_init.c
+++ b/arch/riscv/mm/kasan_init.c
@@@ -162,8 -159,36 +162,10 @@@ static void __init kasan_shallow_popula
{
unsigned long vaddr = (unsigned long)start & PAGE_MASK;
unsigned long vend = PAGE_ALIGN((unsigned long)end);
- unsigned long pfn;
- int index;
- void *p;
- pud_t *pud_dir, *pud_k;
- pgd_t *pgd_dir, *pgd_k;
- p4d_t *p4d_dir, *p4d_k;
-
- while (vaddr < vend) {
- index = pgd_index(vaddr);
- pfn = csr_read(CSR_SATP) & SATP_PPN;
- pgd_dir = (pgd_t *)pfn_to_virt(pfn) + index;
- pgd_k = init_mm.pgd + index;
- pgd_dir = pgd_offset_k(vaddr);
- set_pgd(pgd_dir, *pgd_k);
-
- p4d_dir = p4d_offset(pgd_dir, vaddr);
- p4d_k = p4d_offset(pgd_k, vaddr);
-
- vaddr = (vaddr + PUD_SIZE) & PUD_MASK;
- pud_dir = pud_offset(p4d_dir, vaddr);
- pud_k = pud_offset(p4d_k, vaddr);
-
- if (pud_present(*pud_dir)) {
- p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
- pud_populate(&init_mm, pud_dir, p);
- }
- vaddr += PAGE_SIZE;
- }
+
+ kasan_shallow_populate_pgd(vaddr, vend);
+
+ local_flush_tlb_all();
}
void __init kasan_init(void)
which doesn't include the diff to kasan_shallow_populate_pgd(). Not
sure if that's just because my diff is in the other direction, though.
The expected result is that kasan_shallow_populate_pgd() exists both pre
and post merge.
--
Cheers,
Stephen Rothwell
diff --cc arch/riscv/mm/kasan_init.c
index 4f85c6d0ddf8,2c39f0386673..000000000000
--- a/arch/riscv/mm/kasan_init.c
+++ b/arch/riscv/mm/kasan_init.c
@@@ -153,44 -141,31 +141,33 @@@ static void __init kasan_populate(void
local_flush_tlb_all();
memset(start, KASAN_SHADOW_INIT, end - start);
}
+ static void __init kasan_shallow_populate_pgd(unsigned long vaddr, unsigned long end)
+ {
+ unsigned long next;
+ void *p;
+ pgd_t *pgd_k = pgd_offset_k(vaddr);
+
+ do {
+ next = pgd_addr_end(vaddr, end);
+ if (pgd_page_vaddr(*pgd_k) == (unsigned long)lm_alias(kasan_early_shadow_pmd)) {
+ p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+ set_pgd(pgd_k, pfn_pgd(PFN_DOWN(__pa(p)), PAGE_TABLE));
+ }
+ } while (pgd_k++, vaddr = next, vaddr != end);
+ }
+
static void __init kasan_shallow_populate(void *start, void *end)
{
unsigned long vaddr = (unsigned long)start & PAGE_MASK;
unsigned long vend = PAGE_ALIGN((unsigned long)end);
- unsigned long pfn;
- int index;
- void *p;
- pud_t *pud_dir, *pud_k;
- pgd_t *pgd_dir, *pgd_k;
- p4d_t *p4d_dir, *p4d_k;
-
- while (vaddr < vend) {
- index = pgd_index(vaddr);
- pfn = csr_read(CSR_SATP) & SATP_PPN;
- pgd_dir = (pgd_t *)pfn_to_virt(pfn) + index;
- pgd_k = init_mm.pgd + index;
- pgd_dir = pgd_offset_k(vaddr);
- set_pgd(pgd_dir, *pgd_k);
-
- p4d_dir = p4d_offset(pgd_dir, vaddr);
- p4d_k = p4d_offset(pgd_k, vaddr);
-
- vaddr = (vaddr + PUD_SIZE) & PUD_MASK;
- pud_dir = pud_offset(p4d_dir, vaddr);
- pud_k = pud_offset(p4d_k, vaddr);
-
- if (pud_present(*pud_dir)) {
- p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
- pud_populate(&init_mm, pud_dir, p);
- }
- vaddr += PAGE_SIZE;
- }
+
+ kasan_shallow_populate_pgd(vaddr, vend);
+
+ local_flush_tlb_all();
}
void __init kasan_init(void)
{
phys_addr_t _start, _end;