Skip to contentSkip to conversation

m68k: fix for systems with memory at end of 32-bit address space

PATCH In review Kars de Jong 3 participants 8 messages Feb 23, 2023 – Mar 6, 2023 m68k architecture

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 m68k: fix for systems with memory at end of 32-bit address space

The calculation of end addresses of memory chunks overflowed to 0 when a memory chunk is located at the end of 32-bit address space. This is the case for the HP300 architecture.

---
 arch/m68k/mm/motorola.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/m68k/mm/motorola.c +5 -5
index 2a375637e007..911301224078 100644
@@ -437,7 +437,7 @@ void __init paging_init(void)
 	}
 
 	min_addr = m68k_memory[0].addr;
-	max_addr = min_addr + m68k_memory[0].size;
+	max_addr = min_addr + m68k_memory[0].size - 1;
 	memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0,
 			  MEMBLOCK_NONE);
 	for (i = 1; i < m68k_num_memory;) {
@@ -452,21 +452,21 @@ void __init paging_init(void)
 		}
 		memblock_add_node(m68k_memory[i].addr, m68k_memory[i].size, i,
 				  MEMBLOCK_NONE);
-		addr = m68k_memory[i].addr + m68k_memory[i].size;
+		addr = m68k_memory[i].addr + m68k_memory[i].size - 1;
 		if (addr > max_addr)
 			max_addr = addr;
 		i++;
 	}
 	m68k_memoffset = min_addr - PAGE_OFFSET;
-	m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
+	m68k_virt_to_node_shift = fls(max_addr - min_addr) - 6;
 
 	module_fixup(NULL, __start_fixup, __stop_fixup);
 	flush_icache();
 
-	high_memory = phys_to_virt(max_addr);
+	high_memory = phys_to_virt(max_addr) + 1;
 
 	min_low_pfn = availmem >> PAGE_SHIFT;
-	max_pfn = max_low_pfn = max_addr >> PAGE_SHIFT;
+	max_pfn = max_low_pfn = (max_addr >> PAGE_SHIFT) + 1;
 
 	/* Reserve kernel text/data/bss and the memory allocated in head.S */
 	memblock_reserve(m68k_memory[0].addr, availmem - m68k_memory[0].addr);

base-commit: b1b5209c1e80a9c9912dfe38986fabbc71a2904e

Signature · 1 line
2.17.1
#1 lore raw

Hi Kars,

Quoted 6 lines · Kars de Jong

The calculation of end addresses of memory chunks overflowed to 0 when a memory chunk is located at the end of 32-bit address space. This is the case for the HP300 architecture.

Thanks for your patch!

So this has been broken for the last 15 years?

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
#2 lore raw

Op do 23 feb. 2023 om 13:39 schreef Geert Uytterhoeven <[email protected]>:

Quoted 2 lines

So this has been broken for the last 15 years?

Yes, looks like this commit broke it:
https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git/commit/arch/m68k/mm/motorola.c?id=12d810c1b8c2b913d48e629e2b5c01d105029839,
so slightly longer than 15 years :-).
Looking at my old 2.6 trees, it looks like the last time I was really actively developing for the HP300 was in 2006.
How time flies...

Anyway, now it boots to the point of attempting to run init, which fails, the network driver appears to get stuck.

Kind regards,

Kars.

#3 lore raw

Op do 23 feb. 2023 om 15:05 schreef Kars de Jong <[email protected]>:

Quoted 8 lines

Op do 23 feb. 2023 om 13:39 schreef Geert Uytterhoeven <[email protected]>:

Quoted 2 lines

So this has been broken for the last 15 years?

Yes, looks like this commit broke it:
https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git/commit/arch/m68k/mm/motorola.c?id=12d810c1b8c2b913d48e629e2b5c01d105029839,
so slightly longer than 15 years :-).

I found the original thread where I reported this here:
https://marc.info/?t=117175647600006&r=1&w=2, including a version of this same patch, created by Roman Zippel:
https://marc.info/?l=linux-m68k&m=117184910524555&w=2. This was still in CVS times.

Apparently I used to work around this issue by subtracting 1 from the memory size in my boot loader.

Now I just need to figure out why the last page of memory is excluded. Do you also see this on other machines?

Zone ranges:
DMA [mem 0x00000000fc000000-0x00000fffffffefff]
Normal empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x00000000fc000000-0x00000000ffffefff]
Initmem setup node 0 [mem 0x00000000fc000000-0x00000000ffffefff]

Kind regards,

Kars.

#4 lore raw

Hi Kars,

Quoted 9 lines · Kars de Jong

Op do 23 feb. 2023 om 15:05 schreef Kars de Jong <[email protected]>:

Quoted 7 lines

Op do 23 feb. 2023 om 13:39 schreef Geert Uytterhoeven <[email protected]>:

Quoted 2 lines

So this has been broken for the last 15 years?

Yes, looks like this commit broke it:
https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git/commit/arch/m68k/mm/motorola.c?id=12d810c1b8c2b913d48e629e2b5c01d105029839,
so slightly longer than 15 years :-).

Quoted 8 lines

I found the original thread where I reported this here:
https://marc.info/?t=117175647600006&r=1&w=2, including a version of this same patch, created by Roman Zippel:
https://marc.info/?l=linux-m68k&m=117184910524555&w=2. This was still in CVS times.

Apparently I used to work around this issue by subtracting 1 from the memory size in my boot loader.

;-)

Quoted 10 lines

Now I just need to figure out why the last page of memory is excluded. Do you also see this on other machines?

Zone ranges:
DMA [mem 0x00000000fc000000-0x00000fffffffefff]
Normal empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x00000000fc000000-0x00000000ffffefff]
Initmem setup node 0 [mem 0x00000000fc000000-0x00000000ffffefff]

I don't see that on ARAnyM or on qemu-system-m68k, but those don't have memory at the end of the address space.

ISTR something about not mapping the last page of RAM, if it's at the end of the address space, to avoid wrap-around while prefetching?

[searching]

I think it's a side-effect of:

static inline phys_addr_t memblock_cap_size(phys_addr_t base,
phys_addr_t *size)

    {
            return *size = min(*size, PHYS_ADDR_MAX - base);
    }

with

    #define PHYS_ADDR_MAX  (~(phys_addr_t)0)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#5 lore raw

Hi Geert,

Am 25.02.2023 um 00:01 schrieb Geert Uytterhoeven:

Quoted 11 lines
Quoted 10 lines

Now I just need to figure out why the last page of memory is excluded. Do you also see this on other machines?

Zone ranges:
DMA [mem 0x00000000fc000000-0x00000fffffffefff]
Normal empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x00000000fc000000-0x00000000ffffefff]
Initmem setup node 0 [mem 0x00000000fc000000-0x00000000ffffefff]

Quoted 5 lines

I don't see that on ARAnyM or on qemu-system-m68k, but those don't have memory at the end of the address space.

ISTR something about not mapping the last page of RAM, if it's at the end of the address space, to avoid wrap-around while prefetching?

What would that achieve? The prefetch would still hit an unmapped page.

I can see that excluding the last page from use by memory allocators will prevent wrap, but that last page must then still be mapped, no?

Cheers,

Michael

Quoted 26 lines

[searching]

I think it's a side-effect of:

static inline phys_addr_t memblock_cap_size(phys_addr_t base,
phys_addr_t *size)

    {
            return *size = min(*size, PHYS_ADDR_MAX - base);
    }

with

    #define PHYS_ADDR_MAX  (~(phys_addr_t)0)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#6 lore raw
In reply to Kars de Jong

Op do 23 feb. 2023 om 12:26 schreef Kars de Jong <[email protected]>:

Quoted 6 lines

The calculation of end addresses of memory chunks overflowed to 0 when a memory chunk is located at the end of 32-bit address space. This is the case for the HP300 architecture.

Whoops, looks like I botched the "Signed-off-by" in the commit, thinking I was in vi when it was nano.
Please remove the extra "a" at the end when you commit it :-)

Kind regards,

Kars.

maintainer Reviewed-by
#7 lore raw
Quoted 10 lines · Kars de Jong

Op do 23 feb. 2023 om 12:26 schreef Kars de Jong <[email protected]>:

Quoted 5 lines

The calculation of end addresses of memory chunks overflowed to 0 when a memory chunk is located at the end of 32-bit address space. This is the case for the HP300 architecture.

Whoops, looks like I botched the "Signed-off-by" in the commit, thinking I was in vi when it was nano.
Please remove the extra "a" at the end when you commit it :-)

i.e. will queue as a fix in the m68k for-v6.3 branch, with the above fixed.

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds