// SPDX-License-Identifier: GPL-2.0-only
/*
* Test cases for bitmap API.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitmap.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include "../tools/testing/selftests/kselftest_module.h"
#define EXP1_IN_BITS (sizeof(exp1) * 8)
KSTM_MODULE_GLOBALS();
static char pbl_buffer[PAGE_SIZE] __initdata;
static char print_buf[PAGE_SIZE * 2] __initdata;
static const unsigned long exp1[] __initconst = {
BITMAP_FROM_U64(1),
BITMAP_FROM_U64(2),
BITMAP_FROM_U64(0x0000ffff),
BITMAP_FROM_U64(0xffff0000),
BITMAP_FROM_U64(0x55555555),
BITMAP_FROM_U64(0xaaaaaaaa),
BITMAP_FROM_U64(0x11111111),
BITMAP_FROM_U64(0x22222222),
BITMAP_FROM_U64(0xffffffff),
BITMAP_FROM_U64(0xfffffffe),
BITMAP_FROM_U64(0x3333333311111111ULL),
BITMAP_FROM_U64(0xffffffff77777777ULL),
BITMAP_FROM_U64(0),
BITMAP_FROM_U64(0x00008000),
BITMAP_FROM_U64(0x80000000),
};
static const unsigned long exp2[] __initconst = {
BITMAP_FROM_U64(0x3333333311111111ULL),
BITMAP_FROM_U64(0xffffffff77777777ULL),
};
/* Fibonacci sequence */
static const unsigned long exp2_to_exp3_mask[] __initconst = {
BITMAP_FROM_U64(0x008000020020212eULL),
};
/* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */
static const unsigned long exp3_0_1[] __initconst = {
BITMAP_FROM_U64(0x33b3333311313137ULL),
};
/* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */
static const unsigned long exp3_1_0[] __initconst = {
BITMAP_FROM_U64(0xff7fffff77575751ULL),
};
static bool __init
__check_eq_uint(const char *srcfile, unsigned int line,
const unsigned int exp_uint, unsigned int x)
{
if (exp_uint != x) {
pr_err("[%s:%u] expected %u, got %u\n",
srcfile, line, exp_uint, x);
return false;
}
return true;
}
static bool __init
__check_eq_bitmap(const char *srcfile, unsigned int line,
const unsigned long *exp_bmap, const unsigned long *bmap,
unsigned int nbits)
{
if (!bitmap_equal(exp_bmap, bmap, nbits)) {
pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
srcfile, line,
nbits, exp_bmap, nbits, bmap);
return false;
}
return true;
}
static bool __init
__check_eq_pbl(const char *srcfile, unsigned int line,
const char *expected_pbl,
const unsigned long *bitmap, unsigned int nbits)
{
snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
if (strcmp(expected_pbl, pbl_buffer)) {
pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n",
srcfile, line,
expected_pbl, pbl_buffer);
return false;
}
return true;
}
static bool __init
__check_eq_u32_array(const char *srcfile, unsigned int line,
const u32