'BUILD_BUG_ON(dt_virt_base % SZ_2M) gives me error when NR_CPUS is reduced to 2

When I set NR_CPUS to 2, I get this error while building linux-5.10.0rc (when NR_CPUS is 4, it does not).

arch/arm64/mm/mmu.c: In function 'fixmap_remap_fdt': ././include/linux/compiler_types.h:315:38: error: call to '__compiletime_assert_404' declared with attribute error: BUILD_BUG_ON failed: dt_virt_base % SZ_2M 315 | _compiletime_assert(condition, msg, _compiletime_assert, COUNTER) | ^

The function fixmap_remap_fdt looks like this and the line BUILD_BUG_ON(dt_virt_base % SZ_2M); seems to generate error.

void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
{
    const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
    int offset;
    void *dt_virt;

    /*
     * skip some comments
     */
    BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
    if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
        return NULL;

    /*
     * skip (some comments)
     */
    BUILD_BUG_ON(dt_virt_base % SZ_2M);      // <=== line generating error

    BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
             __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);

I know this BUILD_BUG_ON is supposed to generate error when some condition is true during build time and this is possible because some conditions can be known at build time. But in this case, this dt_virt_base is some virtual address of fixmap (predefined virtual addresses for special purposes in kernel) and it is aligned to SZ_2M. See the definition in arch/arm64/include/asm/fixmap.h.

enum fixed_addresses {
    FIX_HOLE,

    /*
     * Reserve a virtual window for the FDT that is 2 MB larger than the
     * maximum supported size, and put it at the top of the fixmap region.
     * The additional space ensures that any FDT that does not exceed
     * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
     * 2 MB alignment boundaries. 
     * 
     * Keep this at the top so it remains 2 MB aligned.
     */
#define FIX_FDT_SIZE        (MAX_FDT_SIZE + SZ_2M)
    FIX_FDT_END,
    FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,

    FIX_EARLYCON_MEM_BASE,
    FIX_TEXT_POKE0,

And this indexs (enum type) means number of pages from the fixmap top virtual address. So if we have this index, we can get the virtual address. __fix_to_virt is defined in include/asm-generic/fixmap.h as below.

#define __fix_to_virt(x)    (FIXADDR_TOP - ((x) << PAGE_SHIFT))

So, when I reduce NR_CPUS from 4 to 2, I get this build time compile error. But I can't understand why this is giving me the error. Could anyone tell me what is causing the error?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source