Open wzssyqa opened 3 months ago
无脑盲backport,能编译过,能不能跑还不知道。
SYSCALL ID : 258
#define __NR_riscv_hwprobe 258
SYSCALL 参数 :
long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
size_t cpusetsize, cpu_set_t *cpus,
unsigned int flags);
使用方式 :
long syscall(long number, ...);
具体的可参考文档链接 : https://docs.kernel.org/arch/riscv/hwprobe.html
fence.i
, 这个"模糊" 是指在架构里面没有明确规定的特权指令,类似 csrr, csrw 等这种指令,这种指令具体能否在 用户态 U 权限下执行,取决于具体的硬件实现。这里仅仅是个人根据文档对这个部分的理解,并不一定准确。对于 backport 部分,这部分并不是一个关心的问题,因为目前上游支持也是返回一个常量。总体情况 , backport 的内容比较激进,除了 backport hwprobe syscall 需要的内容,还把很多与 cpufeature 相关的内容进行了 backport
目前找到的存在的问题
目前backport 了一版改动相较于 原来老师的bakcport 的 较小的版本,牵涉到的文件有
arc/riscv/include/asm/hwcap.h
arch/riscv/include/asm/hwprobe.h
arch/riscv/include/asm/sbi.h
arch/riscv/include/uapi/asm/hwprobe.h
arch/riscvkernel/cpu.c
arch/riscv/kernel/cpufeature.c
arch/riscv/kernel/sys_riscv.c
arch/riscv/kernel/vdso/hwprobe.c
目前可以通过编译,但是未进行测试,目前想到的测试方法有如下
通过用户态的syscall ,把hwporbe 相关的所有功能进行测试获取信息,并进行记录
写内核态的模块,直接调用 hwprobe 提供的对应的内核开发的接口,获取信息,记录和用户态是否一致
像 mvendorid, marchid 这种寄存器的值,可以以 opensbi的输出为标准线,check 内核态的接口调用是否正常,用户态syscall 是否正常
主要是测试了backport 修改的所有的 api 函数
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/hwprobe.h>
#include <asm/hwcap.h>
#include <linux/printk.h>
#include <linux/random.h>
#include <asm/sbi.h>
#include <linux/smp.h>
typedef void (*test_func_t)(int* err, int* success);
struct test_single_kit {
const char* name;
test_func_t test_handler;
};
#define CHECK_TEST_FUNC_T_PARAMETER() do { if(err == NULL || success == NULL) { pr_err("error paramter for test"); return; } } while(0)
static void test_riscv_hwprobe_key_is_valid(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
bool ret;
//test for valid
for(int i=0;i<=RISCV_HWPROBE_MAX_KEY;i++)
{
ret = riscv_hwprobe_key_is_valid(i);
if(ret == true)
(*success)++;
else
{
(*err)++;
pr_err("error %d ret %d\n", i, ret);
}
}
//test for invalid
for(int i=0;i<=7000;i++)
{
__s64 random;
random = (__s64)get_random_u64();
if(random >=0 && random <= RISCV_HWPROBE_MAX_KEY)
continue;
ret = riscv_hwprobe_key_is_valid((__s64)random);
if(ret == false)
(*success)++;
else
{
(*err)++;
pr_err("error occur when test hwprobe_key_is_valid %d \n",random);
}
}
}
static void test_hwprobe_key_is_bitmask(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
bool ret;
// test for valid
for(int i=0;i<=RISCV_HWPROBE_MAX_KEY;i++)
{
if(i == RISCV_HWPROBE_KEY_BASE_BEHAVIOR || i == RISCV_HWPROBE_KEY_IMA_EXT_0 || i == RISCV_HWPROBE_KEY_CPUPERF_0)
{
ret = hwprobe_key_is_bitmask(i);
if(ret == true)
(*success)++;
else
{
(*err)++;
pr_err("occur error when test_hwprobe_key_is_bitmask %d\n", i);
}
}
}
// test for invalid
for(int i=0;i<=5000;i++)
{
if(i == RISCV_HWPROBE_KEY_BASE_BEHAVIOR || i == RISCV_HWPROBE_KEY_IMA_EXT_0 || i == RISCV_HWPROBE_KEY_CPUPERF_0)
continue;
ret = hwprobe_key_is_bitmask(i);
if(ret == false)
(*success)++;
else
{
(*err)++;
pr_err("occur error when test_hwprobe_key_is_bitmask %d\n", i);
}
}
}
static void test_riscv_hwprobe_pair_cmp(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
bool ret;
struct riscv_hwprobe cmp1;
struct riscv_hwprobe cmp2;
//test for the same
//test for the key valid and invalid
for(int i=0;i<=RISCV_HWPROBE_MAX_KEY + 5000;i++)
{
cmp1.key = i;
cmp2.key = i;
//special key <=> bitmask
if(i == RISCV_HWPROBE_KEY_BASE_BEHAVIOR || i == RISCV_HWPROBE_KEY_IMA_EXT_0 || i == RISCV_HWPROBE_KEY_CPUPERF_0)
{
//test for the same bit map
__s64 random = (__s64)get_random_u64();
cmp1.value = random;
cmp2.value = random;
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == true)
(*success)++;
else
(*err)++;
//test for cmp1 bitmap >= cmp2 bitmap
int bit_1 = (int)(get_random_u8() % 64);
int bit_2 = (int)(get_random_u8() % 64);
int bit_3 = (int)(get_random_u8() % 64);
int bit_4 = (int)(get_random_u8() % 64);
int bit_5 = (int)(get_random_u8() % 64);
int bit_6 = (int)(get_random_u8() % 64);
cmp1.value &= (~(1<<bit_1));
cmp2.value &= (~(1<<bit_1));
cmp1.value |= (1<<bit_1);
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == true)
(*success)++;
else
(*err)++;
cmp1.value &= (~((1<<bit_2) | (1<<bit_3)));
cmp2.value &= (~((1<<bit_2) | (1<<bit_3)));
cmp1.value |= ((1<<bit_2) | (1<<bit_3));
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == true)
(*success)++;
else
(*err)++;
cmp1.value &= (~((1<<bit_4) | (1<<bit_5) | (1<<bit_6)));
cmp2.value &= (~((1<<bit_4) | (1<<bit_5) | (1<<bit_6)));
cmp1.value |= ((1<<bit_4) | (1<<bit_5) | (1<<bit_6));
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == true)
(*success)++;
else
(*err)++;
}
else
{
__s64 random = (__s64)get_random_u64();
cmp1.value = random;
cmp2.value = random;
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == true)
(*success)++;
else
(*err)++;
}
}
//test for not the same
for(int i=0;i<=RISCV_HWPROBE_MAX_KEY + 5000;i++)
{
cmp1.key = i;
cmp2.key = i + 1 + (__s64)((__u64)get_random_u16());
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == false)
(*success)++;
else
(*err)++;
cmp1.key = i;
cmp2.key = i;
if(i == RISCV_HWPROBE_KEY_BASE_BEHAVIOR || i == RISCV_HWPROBE_KEY_IMA_EXT_0 || i == RISCV_HWPROBE_KEY_CPUPERF_0)
{
//test for cmp1 bitmap >= cmp2 bitmap
int bit_1 = (int)(get_random_u8() % 64);
int bit_2 = (int)(get_random_u8() % 64);
int bit_3 = (int)(get_random_u8() % 64);
cmp1.value = (__s64)(get_random_u64());
cmp2.value = cmp1.value;
cmp1.value &= (~(1<<bit_1));
cmp2.value &= (~(1<<bit_1));
cmp2.value |= (1<<bit_1);
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == false)
(*success)++;
else
(*err)++;
cmp1.value &= (~((1<<bit_2) | (1<<bit_3)));
cmp2.value &= (~((1<<bit_2) | (1<<bit_3)));
cmp2.value |= ((1<<bit_2) | (1<<bit_3));
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == false)
(*success)++;
else
(*err)++;
}
else
{
cmp1.value = i;
cmp2.value = i + 1 + (__s64)((__u64)get_random_u16());
ret = riscv_hwprobe_pair_cmp(&cmp1, &cmp2);
if(ret == false)
(*success)++;
else
(*err)++;
}
}
}
static void test_riscv_isa_extension_base(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
#undef CHECK_EXTENSION
#define CHECK_EXTENSION(x) do { if(base_isa & (1 << RISCV_ISA_EXT_##x)) { (*success)++; pr_info("support RISCV_ISA_" #x "\n"); } else { (*err)++; pr_info("base extension RISCV_ISA_" #x " not support!\n"); } } while(0)
unsigned long base_isa = riscv_isa_extension_base(NULL);
CHECK_EXTENSION(a);
CHECK_EXTENSION(c);
CHECK_EXTENSION(d);
CHECK_EXTENSION(f);
CHECK_EXTENSION(h);
CHECK_EXTENSION(i);
CHECK_EXTENSION(m);
CHECK_EXTENSION(q);
CHECK_EXTENSION(v);
}
// static void test_riscv_get_elf_hwcap(int* err, int* success)
// {
// CHECK_TEST_FUNC_T_PARAMETER();
// #undef CHECK_EXTENSION
// #define CHECK_EXTENSION(x) do { if(elf_isa_cap & (1 << RISCV_ISA_EXT_##x)) { (*success)++; pr_info("elf extension RISCV_ISA_" #x " support\n"); } else { (*err)++; pr_info("elf extension RISCV_ISA_" #x " not support!\n"); } } while(0)
// unsigned long elf_isa_cap = riscv_get_elf_hwcap();
// CHECK_EXTENSION(a);
// CHECK_EXTENSION(c);
// CHECK_EXTENSION(d);
// CHECK_EXTENSION(f);
// CHECK_EXTENSION(h);
// CHECK_EXTENSION(i);
// CHECK_EXTENSION(m);
// CHECK_EXTENSION(q);
// CHECK_EXTENSION(v);
// }
static void test_riscv_isa_available(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
#undef CHECK_EXTENSION
#define CHECK_EXTENSION(x) do { (*success)++; if(riscv_isa_extension_available(NULL, x)) { pr_info("extension RISCV_ISA_" #x " support\n"); } else { pr_info("extension RISCV_ISA_" #x " not support\n"); } } while(0)
CHECK_EXTENSION(a);
CHECK_EXTENSION(c);
CHECK_EXTENSION(d);
CHECK_EXTENSION(f);
CHECK_EXTENSION(h);
CHECK_EXTENSION(i);
CHECK_EXTENSION(m);
CHECK_EXTENSION(q);
CHECK_EXTENSION(v);
CHECK_EXTENSION(SSCOFPMF);
CHECK_EXTENSION(SSTC);
CHECK_EXTENSION(SVINVAL);
CHECK_EXTENSION(SVPBMT);
CHECK_EXTENSION(ZBB);
CHECK_EXTENSION(ZICBOM);
CHECK_EXTENSION(ZIHINTPAUSE);
CHECK_EXTENSION(SVNAPOT);
CHECK_EXTENSION(ZICBOZ);
CHECK_EXTENSION(SMAIA);
CHECK_EXTENSION(SSAIA);
CHECK_EXTENSION(ZBA);
CHECK_EXTENSION(ZBS);
CHECK_EXTENSION(ZICNTR);
CHECK_EXTENSION(ZICSR);
CHECK_EXTENSION(ZIFENCEI);
CHECK_EXTENSION(ZIHPM);
CHECK_EXTENSION(SMSTATEEN);
CHECK_EXTENSION(ZICOND);
CHECK_EXTENSION(ZBC);
CHECK_EXTENSION(ZBKB);
CHECK_EXTENSION(ZBKC);
CHECK_EXTENSION(ZBKX);
CHECK_EXTENSION(ZKND);
CHECK_EXTENSION(ZKNE);
CHECK_EXTENSION(ZKNH);
CHECK_EXTENSION(ZKR);
CHECK_EXTENSION(ZKSED);
CHECK_EXTENSION(ZKSH);
CHECK_EXTENSION(ZKT);
CHECK_EXTENSION(ZVBB);
CHECK_EXTENSION(ZVBC);
CHECK_EXTENSION(ZVKB);
CHECK_EXTENSION(ZVKG);
CHECK_EXTENSION(ZVKNED);
CHECK_EXTENSION(ZVKNHA);
CHECK_EXTENSION(ZVKNHB);
CHECK_EXTENSION(ZVKSED);
CHECK_EXTENSION(ZVKSH);
CHECK_EXTENSION(ZVKT);
CHECK_EXTENSION(ZFH);
CHECK_EXTENSION(ZFHMIN);
CHECK_EXTENSION(ZIHINTNTL);
CHECK_EXTENSION(ZVFH);
CHECK_EXTENSION(ZVFHMIN);
CHECK_EXTENSION(ZFA);
CHECK_EXTENSION(ZTSO);
CHECK_EXTENSION(ZACAS);
CHECK_EXTENSION(XANDESPMU);
CHECK_EXTENSION(XLINUXENVCFG);
}
static void test_riscv_has_extension_likely(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
bool extension_likly = false;
bool extension_unlikly = false;
bool isa_extension = false;
#define HAS_EXTENSION_CHECK(x) do { extension_likly = riscv_has_extension_likely(RISCV_ISA_EXT_##x); } while(0)
#define ISA_EXTENSION_CHECK(x) do { isa_extension = riscv_isa_extension_available(NULL, x); } while(0)
#define HAS_EXTENSION_CHECK_F(x) do { extension_unlikly = riscv_has_extension_unlikely(RISCV_ISA_EXT_##x); } while(0)
#undef CHECK_EXTENSION
#define CHECK_EXTENSION(x) do { HAS_EXTENSION_CHECK(x); ISA_EXTENSION_CHECK(x); HAS_EXTENSION_CHECK_F(x); if(extension_likly == isa_extension && extension_likly == extension_unlikly) { (*success)++; } else { (*err)++; pr_info("EXTENSION " #x " NOT ASSISTTENT\n");} } while(0)
CHECK_EXTENSION(a);
CHECK_EXTENSION(c);
CHECK_EXTENSION(d);
CHECK_EXTENSION(f);
CHECK_EXTENSION(h);
CHECK_EXTENSION(i);
CHECK_EXTENSION(m);
CHECK_EXTENSION(q);
CHECK_EXTENSION(v);
CHECK_EXTENSION(SSCOFPMF);
CHECK_EXTENSION(SSTC);
CHECK_EXTENSION(SVINVAL);
CHECK_EXTENSION(SVPBMT);
CHECK_EXTENSION(ZBB);
CHECK_EXTENSION(ZICBOM);
CHECK_EXTENSION(ZIHINTPAUSE);
CHECK_EXTENSION(SVNAPOT);
CHECK_EXTENSION(ZICBOZ);
CHECK_EXTENSION(SMAIA);
CHECK_EXTENSION(SSAIA);
CHECK_EXTENSION(ZBA);
CHECK_EXTENSION(ZBS);
CHECK_EXTENSION(ZICNTR);
CHECK_EXTENSION(ZICSR);
CHECK_EXTENSION(ZIFENCEI);
CHECK_EXTENSION(ZIHPM);
CHECK_EXTENSION(SMSTATEEN);
CHECK_EXTENSION(ZICOND);
CHECK_EXTENSION(ZBC);
CHECK_EXTENSION(ZBKB);
CHECK_EXTENSION(ZBKC);
CHECK_EXTENSION(ZBKX);
CHECK_EXTENSION(ZKND);
CHECK_EXTENSION(ZKNE);
CHECK_EXTENSION(ZKNH);
CHECK_EXTENSION(ZKR);
CHECK_EXTENSION(ZKSED);
CHECK_EXTENSION(ZKSH);
CHECK_EXTENSION(ZKT);
CHECK_EXTENSION(ZVBB);
CHECK_EXTENSION(ZVBC);
CHECK_EXTENSION(ZVKB);
CHECK_EXTENSION(ZVKG);
CHECK_EXTENSION(ZVKNED);
CHECK_EXTENSION(ZVKNHA);
CHECK_EXTENSION(ZVKNHB);
CHECK_EXTENSION(ZVKSED);
CHECK_EXTENSION(ZVKSH);
CHECK_EXTENSION(ZVKT);
CHECK_EXTENSION(ZFH);
CHECK_EXTENSION(ZFHMIN);
CHECK_EXTENSION(ZIHINTNTL);
CHECK_EXTENSION(ZVFH);
CHECK_EXTENSION(ZVFHMIN);
CHECK_EXTENSION(ZFA);
CHECK_EXTENSION(ZTSO);
CHECK_EXTENSION(ZACAS);
CHECK_EXTENSION(XANDESPMU);
CHECK_EXTENSION(XLINUXENVCFG);
}
static void test_riscv_get_mvendor_id(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
unsigned int cpu = get_cpu();
unsigned long sbi_mvendor_id = sbi_get_mvendorid();
unsigned long cached_mvendor_id = riscv_cached_mvendorid(cpu);
if(sbi_mvendor_id == cached_mvendor_id)
(*success)++;
else
{
(*err)++;
pr_info("sbi_mvendor_id: %llx, cached_mvendor_id\n", sbi_mvendor_id, cached_mvendor_id);
put_cpu();
return;
}
put_cpu();
pr_info("mvendorid: %llx\n", sbi_mvendor_id);
}
static void test_riscv_get_march_id(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
unsigned int cpu = get_cpu();
unsigned long sbi_march_id = sbi_get_marchid();
unsigned long cached_march_id = riscv_cached_marchid(cpu);
if(sbi_march_id == cached_march_id)
(*success)++;
else
{
(*err)++;
pr_info("sbi_march_id: %llx, cached_march_id: %llx\n", sbi_march_id, cached_march_id);
put_cpu();
return;
}
put_cpu();
pr_info("marchid: %llx\n", sbi_march_id);
}
static void test_sbi_get_mimpid(int* err, int* success)
{
CHECK_TEST_FUNC_T_PARAMETER();
unsigned int cpu = get_cpu();
unsigned long sbi_mimp_id = sbi_get_mimpid();
unsigned long cached_mimp_id = riscv_cached_mimpid(cpu);
if(sbi_mimp_id != cached_mimp_id)
{
(*err)++;
pr_info("sbi_mimp_id: %llx, cached_mimp_id: %llx\n", sbi_mimp_id, cached_mimp_id);
put_cpu();
return;
}
else
(*success)++;
put_cpu();
pr_info("mimp_id: %llx\n", sbi_mimp_id);
}
static struct test_single_kit test_kits[] = {
{ "HWPROBE_API_KVALID", test_riscv_hwprobe_key_is_valid },
{ "HWPROBE_API_KBTMSK", test_hwprobe_key_is_bitmask },
{ "HWPROBE_API_PIRCMP", test_riscv_hwprobe_pair_cmp },
{ "HWCAP_API_ISABASET", test_riscv_isa_extension_base },
// { "HWCAP_API_GTELFCAP", test_riscv_get_elf_hwcap },
{ "HWCAP_API_ISAENABL", test_riscv_isa_available },
{ "HWCAP_API_EXTLIKLY", test_riscv_has_extension_likely },
{ "HWPROBE_MVENDIDTST", test_riscv_get_mvendor_id },
{ "HWPROBE_MARCHIDTST", test_riscv_get_march_id },
{ "HWPROBE_MIMLPIDTST", test_sbi_get_mimpid },
};
static int __init test_hwprobe_module_init(void)
{
int total_success = 0;
int total_err = 0;
int total_num = 0;
int size = sizeof(test_kits) / sizeof(test_kits[0]);
for(int i=0; i<size ;i++)
{
int tmp_success = 0;
int tmp_err = 0;
pr_info("=============TEST FOR %s =============\n", test_kits[i].name);
test_kits[i].test_handler(&tmp_err, &tmp_success);
pr_info("test success %d/%d\n", tmp_success, tmp_success + tmp_err);
pr_info("test failed %d/%d\n", tmp_err, tmp_success + tmp_err);
total_success += tmp_success;
total_err += tmp_err;
total_num += (tmp_success + tmp_err);
pr_info("=============TEST FOR %s END =========\n", test_kits[i].name);
}
pr_info("=============TEST FOR ALL =============\n");
pr_info("total test success %d/%d\n", total_success, total_num);
pr_info("total test failed %d/%d\n", total_err, total_num);
pr_info("=============TEST FOR ALL END =========\n");
return 0;
}
static void __exit test_hwprobe_module_exit(void)
{
pr_info("exit!!!!!!!!!!!!!\n");
return;
}
module_init(test_hwprobe_module_init);
module_exit(test_hwprobe_module_exit);
MODULE_LICENSE("GPL");
测试结果
[ 89.336992] =============TEST FOR HWPROBE_API_KVALID =============
[ 89.339827] test success 7008/7008
[ 89.339869] test failed 0/7008
[ 89.339895] =============TEST FOR HWPROBE_API_KVALID END =========
[ 89.339918] =============TEST FOR HWPROBE_API_KBTMSK =============
[ 89.339988] test success 5001/5001
[ 89.340000] test failed 0/5001
[ 89.340010] =============TEST FOR HWPROBE_API_KBTMSK END =========
[ 89.340020] =============TEST FOR HWPROBE_API_PIRCMP =============
[ 89.343923] test success 15033/15033
[ 89.343942] test failed 0/15033
[ 89.343953] =============TEST FOR HWPROBE_API_PIRCMP END =========
[ 89.343963] =============TEST FOR HWCAP_API_ISABASET =============
[ 89.344018] support RISCV_ISA_a
[ 89.344040] support RISCV_ISA_c
[ 89.344061] support RISCV_ISA_d
[ 89.344082] support RISCV_ISA_f
[ 89.344102] support RISCV_ISA_h
[ 89.344123] support RISCV_ISA_i
[ 89.344145] support RISCV_ISA_m
[ 89.344167] base extension RISCV_ISA_q not support!
[ 89.344186] base extension RISCV_ISA_v not support!
[ 89.344206] test success 7/9
[ 89.344217] test failed 2/9
[ 89.344227] =============TEST FOR HWCAP_API_ISABASET END =========
[ 89.344237] =============TEST FOR HWCAP_API_ISAENABL =============
[ 89.344273] extension RISCV_ISA_a support
[ 89.344307] extension RISCV_ISA_c support
[ 89.344332] extension RISCV_ISA_d support
[ 89.344355] extension RISCV_ISA_f support
[ 89.344379] extension RISCV_ISA_h support
[ 89.344403] extension RISCV_ISA_i support
[ 89.344426] extension RISCV_ISA_m support
[ 89.344450] extension RISCV_ISA_q not support
[ 89.344472] extension RISCV_ISA_v not support
[ 89.344493] extension RISCV_ISA_SSCOFPMF not support
[ 89.344514] extension RISCV_ISA_SSTC support
[ 89.344537] extension RISCV_ISA_SVINVAL not support
[ 89.344558] extension RISCV_ISA_SVPBMT not support
[ 89.344581] extension RISCV_ISA_ZBB support
[ 89.344613] extension RISCV_ISA_ZICBOM support
[ 89.344717] extension RISCV_ISA_ZIHINTPAUSE support
[ 89.344743] extension RISCV_ISA_SVNAPOT not support
[ 89.344764] extension RISCV_ISA_ZICBOZ support
[ 89.344796] extension RISCV_ISA_SMAIA not support
[ 89.344817] extension RISCV_ISA_SSAIA not support
[ 89.344839] extension RISCV_ISA_ZBA support
[ 89.344862] extension RISCV_ISA_ZBS support
[ 89.344886] extension RISCV_ISA_ZICNTR support
[ 89.344909] extension RISCV_ISA_ZICSR support
[ 89.344933] extension RISCV_ISA_ZIFENCEI support
[ 89.344956] extension RISCV_ISA_ZIHPM support
[ 89.344979] extension RISCV_ISA_SMSTATEEN not support
[ 89.345000] extension RISCV_ISA_ZICOND not support
[ 89.345021] extension RISCV_ISA_ZBC support
[ 89.345045] extension RISCV_ISA_ZBKB not support
[ 89.345065] extension RISCV_ISA_ZBKC not support
[ 89.345086] extension RISCV_ISA_ZBKX not support
[ 89.345106] extension RISCV_ISA_ZKND not support
[ 89.345127] extension RISCV_ISA_ZKNE not support
[ 89.345148] extension RISCV_ISA_ZKNH not support
[ 89.345168] extension RISCV_ISA_ZKR not support
[ 89.345189] extension RISCV_ISA_ZKSED not support
[ 89.345209] extension RISCV_ISA_ZKSH not support
[ 89.345231] extension RISCV_ISA_ZKT not support
[ 89.345252] extension RISCV_ISA_ZVBB not support
[ 89.345272] extension RISCV_ISA_ZVBC not support
[ 89.345293] extension RISCV_ISA_ZVKB not support
[ 89.345314] extension RISCV_ISA_ZVKG not support
[ 89.345334] extension RISCV_ISA_ZVKNED not support
[ 89.345362] extension RISCV_ISA_ZVKNHA not support
[ 89.345383] extension RISCV_ISA_ZVKNHB not support
[ 89.345403] extension RISCV_ISA_ZVKSED not support
[ 89.345424] extension RISCV_ISA_ZVKSH not support
[ 89.345445] extension RISCV_ISA_ZVKT not support
[ 89.345465] extension RISCV_ISA_ZFH not support
[ 89.345486] extension RISCV_ISA_ZFHMIN not support
[ 89.345507] extension RISCV_ISA_ZIHINTNTL not support
[ 89.345528] extension RISCV_ISA_ZVFH not support
[ 89.345549] extension RISCV_ISA_ZVFHMIN not support
[ 89.345570] extension RISCV_ISA_ZFA support
[ 89.345593] extension RISCV_ISA_ZTSO not support
[ 89.345614] extension RISCV_ISA_ZACAS not support
[ 89.345634] extension RISCV_ISA_XANDESPMU not support
[ 89.345655] extension RISCV_ISA_XLINUXENVCFG support
[ 89.345681] test success 59/59
[ 89.345692] test failed 0/59
[ 89.345703] =============TEST FOR HWCAP_API_ISAENABL END =========
[ 89.345712] =============TEST FOR HWCAP_API_EXTLIKLY =============
[ 89.347091] test success 59/59
[ 89.347111] test failed 0/59
[ 89.347123] =============TEST FOR HWCAP_API_EXTLIKLY END =========
[ 89.347133] =============TEST FOR HWPROBE_MVENDIDTST =============
[ 89.347190] mvendorid: 0
[ 89.347211] test success 1/1
[ 89.347222] test failed 0/1
[ 89.347231] =============TEST FOR HWPROBE_MVENDIDTST END =========
[ 89.347241] =============TEST FOR HWPROBE_MARCHIDTST =============
[ 89.347288] marchid: 0
[ 89.347307] test success 1/1
[ 89.347317] test failed 0/1
[ 89.347327] =============TEST FOR HWPROBE_MARCHIDTST END =========
[ 89.347337] =============TEST FOR HWPROBE_MIMLPIDTST =============
[ 89.347383] mimp_id: 0
[ 89.347401] test success 1/1
[ 89.347412] test failed 0/1
[ 89.347421] =============TEST FOR HWPROBE_MIMLPIDTST END =========
[ 89.347435] =============TEST FOR ALL =============
[ 89.347448] total test success 27170/27172
[ 89.347463] total test failed 2/27172
[ 89.347478] =============TEST FOR ALL END =========
额外说明
这里有两个 failed 是因为源码里面 对于 base extension v 和 p 不支持的话,就默认成错误来处理
主要是测试了用户态在 BACKPORT 后的 syscall 的功能
#include <asm/hwprobe.h>
#include <asm/unistd.h>
#include <unistd.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
size_t cpusetsize, cpu_set_t *cpus,
unsigned int flags)
{
long ret = syscall(__NR_riscv_hwprobe, pairs, pair_count, cpusetsize, cpus, flags);
return ret;
}
static struct riscv_hwprobe ask_hwprobe[] = {
{.key = RISCV_HWPROBE_KEY_MVENDORID, .value = 233},
{.key = RISCV_HWPROBE_KEY_MARCHID, .value = 233},
{.key = RISCV_HWPROBE_KEY_MIMPID, .value = 233},
{.key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value =233},
{.key = RISCV_HWPROBE_KEY_IMA_EXT_0, .value = 233},
{.key = RISCV_HWPROBE_KEY_CPUPERF_0, .value = 233},
#ifdef BACKPORT
{.key = RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE, .value = 233},
#endif
};
int main(int argc, char* argv[])
{
int size = sizeof(ask_hwprobe) / sizeof(ask_hwprobe[0]);
int ret = sys_riscv_hwprobe(ask_hwprobe, size, 0, NULL, 0);
if(ret != 0)
{
printf("hwprobe syscall error!\n");
return -1;
}
printf("mvendor id: %llx\n", ask_hwprobe[0].value);
printf("march id: %llx\n", ask_hwprobe[1].value);
printf("mimp id: %llx\n", ask_hwprobe[2].value);
printf("ARCH BASE BEHAVIOR: \n");
if(RISCV_HWPROBE_BASE_BEHAVIOR_IMA & ask_hwprobe[3].value)
{
printf("RISCV_HWPROBE_BASE_BEHAVIOR_IMA\n");
}
else
{
printf("ERROR BEHAVIOR\n");
}
#define CHECK(type,what) do { \
if(ask_hwprobe[4].value & RISCV_HWPROBE_##type##_##what) \
{\
printf("RISC-V " #type " Extension " #what " Support!\n");\
}\
else \
{\
printf("RISC-V " #type " Extension " #what " Not Support!\n");\
}\
} while(0)
#define BASE_CHECK(x) CHECK(IMA,x)
#define EXTENSION_CHECK(x) CHECK(EXT,x)
BASE_CHECK(FD);
BASE_CHECK(C);
BASE_CHECK(V);
EXTENSION_CHECK(ZBA);
EXTENSION_CHECK(ZBB);
EXTENSION_CHECK(ZBS);
#ifdef BACKPORT
EXTENSION_CHECK(ZICBOZ);
EXTENSION_CHECK(ZBC);
EXTENSION_CHECK(ZBKB);
EXTENSION_CHECK(ZBKC);
EXTENSION_CHECK(ZBKX);
EXTENSION_CHECK(ZKND);
EXTENSION_CHECK(ZKNE);
EXTENSION_CHECK(ZKNH);
EXTENSION_CHECK(ZKSED);
EXTENSION_CHECK(ZKSH);
EXTENSION_CHECK(ZKT);
EXTENSION_CHECK(ZVBB);
EXTENSION_CHECK(ZVBC);
EXTENSION_CHECK(ZVKB);
EXTENSION_CHECK(ZVKG);
EXTENSION_CHECK(ZVKNED);
EXTENSION_CHECK(ZVKNHA);
EXTENSION_CHECK(ZVKNHB);
EXTENSION_CHECK(ZVKSED);
EXTENSION_CHECK(ZVKSH);
EXTENSION_CHECK(ZVKT);
EXTENSION_CHECK(ZFH);
EXTENSION_CHECK(ZFHMIN);
EXTENSION_CHECK(ZIHINTNTL);
EXTENSION_CHECK(ZVFH);
EXTENSION_CHECK(ZVFHMIN);
EXTENSION_CHECK(ZFA);
EXTENSION_CHECK(ZTSO);
EXTENSION_CHECK(ZACAS);
EXTENSION_CHECK(ZICOND);
EXTENSION_CHECK(ZIHINTPAUSE);
#endif
#define PERFORMANCE_CHECK(x) do { \
if(ask_hwprobe[5].value & RISCV_HWPROBE_MISALIGNED_##x) \
{ \
printf("MISALIGNED ACCESS MEMORY PERFORMANCE: " #x " \n");\
}\
} while(0)
PERFORMANCE_CHECK(UNKNOWN);
PERFORMANCE_CHECK(EMULATED);
PERFORMANCE_CHECK(SLOW);
PERFORMANCE_CHECK(FAST);
PERFORMANCE_CHECK(UNSUPPORTED);
#ifdef BACKPORT
PERFORMANCE_CHECK(MASK);
#endif
#ifdef BACKPORT
printf("ZICBOZ_BLOCK_SIZE : %llx\n", ask_hwprobe[6].value);
#endif
return 0;
}
测试结果
mvendor id: 0
march id: 0
mimp id: 0
ARCH BASE BEHAVIOR:
RISCV_HWPROBE_BASE_BEHAVIOR_IMA
RISC-V IMA Extension FD Support!
RISC-V IMA Extension C Support!
RISC-V IMA Extension V Not Support!
RISC-V EXT Extension ZBA Support!
RISC-V EXT Extension ZBB Support!
RISC-V EXT Extension ZBS Support!
RISC-V EXT Extension ZICBOZ Support!
RISC-V EXT Extension ZBC Support!
RISC-V EXT Extension ZBKB Not Support!
RISC-V EXT Extension ZBKC Not Support!
RISC-V EXT Extension ZBKX Not Support!
RISC-V EXT Extension ZKND Not Support!
RISC-V EXT Extension ZKNE Not Support!
RISC-V EXT Extension ZKNH Not Support!
RISC-V EXT Extension ZKSED Not Support!
RISC-V EXT Extension ZKSH Not Support!
RISC-V EXT Extension ZKT Not Support!
RISC-V EXT Extension ZVBB Not Support!
RISC-V EXT Extension ZVBC Not Support!
RISC-V EXT Extension ZVKB Not Support!
RISC-V EXT Extension ZVKG Not Support!
RISC-V EXT Extension ZVKNED Not Support!
RISC-V EXT Extension ZVKNHA Not Support!
RISC-V EXT Extension ZVKNHB Not Support!
RISC-V EXT Extension ZVKSED Not Support!
RISC-V EXT Extension ZVKSH Not Support!
RISC-V EXT Extension ZVKT Not Support!
RISC-V EXT Extension ZFH Not Support!
RISC-V EXT Extension ZFHMIN Not Support!
RISC-V EXT Extension ZIHINTNTL Not Support!
RISC-V EXT Extension ZVFH Not Support!
RISC-V EXT Extension ZVFHMIN Not Support!
RISC-V EXT Extension ZFA Support!
RISC-V EXT Extension ZTSO Not Support!
RISC-V EXT Extension ZACAS Not Support!
RISC-V EXT Extension ZICOND Not Support!
RISC-V EXT Extension ZIHINTPAUSE Support!
MISALIGNED ACCESS MEMORY PERFORMANCE: EMULATED
MISALIGNED ACCESS MEMORY PERFORMANCE: SLOW
MISALIGNED ACCESS MEMORY PERFORMANCE: FAST
MISALIGNED ACCESS MEMORY PERFORMANCE: MASK
ZICBOZ_BLOCK_SIZE : 40
To work with glibc-hwcaps, we need full support
riscv_hwprobe
syscall.Kernel 6.10 has more macro etc support.
Let's port it to 6.6.