From 09a44e6259b334b98fee75ef5de8104ce416eb2f Mon Sep 17 00:00:00 2001 From: Shan Kang Date: Tue, 28 May 2024 15:52:26 +0800 Subject: [PATCH 1/3] Added a fastmsrns test case Signed-off-by: Shan Kang --- BM/fred/fred_test_driver.c | 108 ++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 7 deletions(-) diff --git a/BM/fred/fred_test_driver.c b/BM/fred/fred_test_driver.c index 4c90b9e..dcc57a1 100644 --- a/BM/fred/fred_test_driver.c +++ b/BM/fred/fred_test_driver.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include MODULE_AUTHOR("Shan Kang "); MODULE_VERSION("1.0"); @@ -38,6 +41,88 @@ static const struct file_operations fops = { .release = fred_test_release, }; +static inline u64 fred_test_rdmsr(u32 msr) +{ + u32 a, d; + + __asm__ __volatile__("rdmsr" : "=a"(a), "=d"(d) : "c"(msr) : "memory"); + + return a | ((u64) d << 32); +} + + +static inline void fred_test_wrmsr(u32 msr, u64 value) +{ + u32 a = value; + u32 d = value >> 32; + + __asm__ __volatile__("wrmsr" :: "a"(a), "d"(d), "c"(msr) : "memory"); +} + +static inline void fred_test_wrmsrns(u32 msr, u64 value) +{ + u32 a = value; + u32 d = value >> 32; + + __asm__ __volatile__(".byte 0x0f,0x01,0xc6" :: "a"(a), "d"(d), "c"(msr)); +} + +u64 read_performance_counter(void) +{ + u64 value; + + rdpmcl(0x40000002, value); + + printk(KERN_INFO "REF_TSC Value: %llu\n", value); + + return value; +} + +static void check_wrmsr_cycles(long loop) +{ + u64 start, end, gs_base, elapsed, i; + //if (static_cpu_has(X86_FEATURE_WRMSRNS)) + //{ + local_irq_disable(); + preempt_disable(); + gs_base = fred_test_rdmsr(MSR_GS_BASE); + //start = rdtsc(); + wrmsrl(0x38f, 0); // clear global_ctrl + wrmsrl(0x30b, 0); // clear fixed counter 2 value (REF_TSC) + wrmsrl(0x38f, BIT_ULL(32+2)); // enable fixed counter in global_ctrl + wrmsrl(0x38d, 0x300); // enable fixed counter 2 + start = read_performance_counter(); + for (i = 0; i < loop; i++) + fred_test_wrmsrns(MSR_GS_BASE, gs_base); + //end = rdtsc(); + end = read_performance_counter(); + wrmsrl(0x38d, 0); // disable fixed counter 2 + wrmsrl(0x38f, 0); // clear global_ctrl + preempt_enable(); + local_irq_enable(); + elapsed = (end - start) / loop; + pr_info("Elapsed time: wrmsrns used %llu cycles\n", elapsed); + //} + + local_irq_disable(); + preempt_disable(); + gs_base = fred_test_rdmsr(MSR_GS_BASE); + wrmsrl(0x38f, 0); // clear global_ctrl + wrmsrl(0x30b, 0); // clear fixed counter 2 value (REF_TSC) + wrmsrl(0x38f, BIT_ULL(32+2)); // enable fixed counter in global_ctrl + wrmsrl(0x38d, 0x300); // enable fixed counter 2 + //start = rdtsc(); + start = read_performance_counter(); + for (i = 0; i < loop; i++) + fred_test_wrmsr(MSR_GS_BASE, gs_base); + //end = rdtsc(); + end = read_performance_counter(); + preempt_enable(); + local_irq_enable(); + elapsed = (end - start) / loop; + pr_info("Elapsed time: wrmsr used %llu cycles\n", elapsed); +} + static int fred_enable(void) { u64 cr4; @@ -112,27 +197,35 @@ static ssize_t fred_test_write(struct file *filp, const char *buf, size_t count, /* Here we read from buf to our_buf */ if (copy_from_user(our_buf, buf, count)) pr_err("Data Write : Err!\n"); - + else + pr_err("Data Write : %s! count=%ld\n", our_buf, count); /* we write NULL to end the string */ our_buf[count] = '\0'; if (strncmp(our_buf, "fred_enable ", strlen("fred_enable ")) == 0) { ret = kstrtol(our_buf + strlen("fred_enable "), 10, &opt); - if (!ret) { - pr_err("kstrtol failed\n"); + if (ret) { + pr_err("kstrtol failed ret=%d\n", ret); return 0; } - //opt = simple_strtol(our_buf + strlen("fred_enable "), NULL, 10); pr_info("fred_enable expected %ld\n", opt); fred_bit = fred_enable(); if (fred_bit == (u64)opt) pr_info("fred_enable test PASS\n"); else pr_info("fred_enable test FAIL\n"); - } else if (strncmp(our_buf, "double_fault", strlen("double_fault")) == 0) { pr_info("double_fault test begin\n"); invoke_double_fault(); + } else if (strncmp(our_buf, "fast_msr ", strlen("fast_msr ")) == 0) { + pr_info("fast_msr test begin\n"); + ret = kstrtol(our_buf + strlen("fast_msr "), 10, &opt); + if (ret) { + pr_err("kstrtol failed ret=%d\n", ret); + return 0; + } + pr_info("fast_msr loop %ld\n", opt); + check_wrmsr_cycles(opt); } else { pr_info("Not supported case\n"); } @@ -163,7 +256,8 @@ static int __init fred_test_driver_init(void) goto r_class; } /* Creating struct class */ - dev_class = class_create(THIS_MODULE, "fred_test_class"); + //dev_class = class_create(THIS_MODULE, "fred_test_class"); + dev_class = class_create("fred_test_class"); if (IS_ERR(dev_class)) { pr_err("Cannot create the struct class\n"); goto r_class; @@ -196,4 +290,4 @@ static void __exit fred_test_driver_exit(void) module_init(fred_test_driver_init); module_exit(fred_test_driver_exit); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL"); \ No newline at end of file From 9256193b3d993d758ebc5d87b3f7628fa1f698c0 Mon Sep 17 00:00:00 2001 From: Shan Kang Date: Tue, 28 May 2024 22:04:34 +0800 Subject: [PATCH 2/3] Fix some code style in fred test Signed-off-by: Shan Kang --- BM/fred/fred_test_driver.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/BM/fred/fred_test_driver.c b/BM/fred/fred_test_driver.c index dcc57a1..0ca2111 100644 --- a/BM/fred/fred_test_driver.c +++ b/BM/fred/fred_test_driver.c @@ -25,8 +25,8 @@ static int __init fred_test_driver_init(void); static void __exit fred_test_driver_exit(void); static int fred_test_open(struct inode *inode, struct file *file); static int fred_test_release(struct inode *inode, struct file *file); -static ssize_t fred_test_read(struct file *filp, char __user *buf, size_t count, loff_t *off); -static ssize_t fred_test_write(struct file *filp, const char *buf, size_t count, loff_t *off); +static ssize_t fred_test_read(struct file *file, char __user *buf, size_t count, loff_t *off); +static ssize_t fred_test_write(struct file *file, const char *buf, size_t count, loff_t *off); static long fred_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg); /* @@ -47,10 +47,9 @@ static inline u64 fred_test_rdmsr(u32 msr) __asm__ __volatile__("rdmsr" : "=a"(a), "=d"(d) : "c"(msr) : "memory"); - return a | ((u64) d << 32); + return a | ((u64)d << 32); } - static inline void fred_test_wrmsr(u32 msr, u64 value) { u32 a = value; @@ -73,7 +72,7 @@ u64 read_performance_counter(void) rdpmcl(0x40000002, value); - printk(KERN_INFO "REF_TSC Value: %llu\n", value); + pr_info("REF_TSC Value: %llu\n", value); return value; } @@ -89,7 +88,7 @@ static void check_wrmsr_cycles(long loop) //start = rdtsc(); wrmsrl(0x38f, 0); // clear global_ctrl wrmsrl(0x30b, 0); // clear fixed counter 2 value (REF_TSC) - wrmsrl(0x38f, BIT_ULL(32+2)); // enable fixed counter in global_ctrl + wrmsrl(0x38f, BIT_ULL(32 + 2)); // enable fixed counter in global_ctrl wrmsrl(0x38d, 0x300); // enable fixed counter 2 start = read_performance_counter(); for (i = 0; i < loop; i++) @@ -109,7 +108,7 @@ static void check_wrmsr_cycles(long loop) gs_base = fred_test_rdmsr(MSR_GS_BASE); wrmsrl(0x38f, 0); // clear global_ctrl wrmsrl(0x30b, 0); // clear fixed counter 2 value (REF_TSC) - wrmsrl(0x38f, BIT_ULL(32+2)); // enable fixed counter in global_ctrl + wrmsrl(0x38f, BIT_ULL(32 + 2)); // enable fixed counter in global_ctrl wrmsrl(0x38d, 0x300); // enable fixed counter 2 //start = rdtsc(); start = read_performance_counter(); @@ -120,7 +119,7 @@ static void check_wrmsr_cycles(long loop) preempt_enable(); local_irq_enable(); elapsed = (end - start) / loop; - pr_info("Elapsed time: wrmsr used %llu cycles\n", elapsed); + pr_info("Elapsed time: wrmsr used %llu cycles\n", elapsed); } static int fred_enable(void) @@ -174,7 +173,7 @@ static int fred_test_release(struct inode *inode, struct file *file) return 0; } -static ssize_t fred_test_read(struct file *filp, char __user *buf, size_t count, loff_t *off) +static ssize_t fred_test_read(struct file *file, char __user *buf, size_t count, loff_t *off) { int len; /* For example - when content of our_buf is "100" - */ @@ -184,7 +183,7 @@ static ssize_t fred_test_read(struct file *filp, char __user *buf, size_t count, return len; } -static ssize_t fred_test_write(struct file *filp, const char *buf, size_t count, loff_t *off) +static ssize_t fred_test_write(struct file *file, const char *buf, size_t count, loff_t *off) { long opt; u64 fred_bit; @@ -290,4 +289,4 @@ static void __exit fred_test_driver_exit(void) module_init(fred_test_driver_init); module_exit(fred_test_driver_exit); -MODULE_LICENSE("GPL"); \ No newline at end of file +MODULE_LICENSE("GPL"); From a2bb92cec6103045352472a27f60166d9b2f7d99 Mon Sep 17 00:00:00 2001 From: Shan Kang Date: Tue, 28 May 2024 22:09:19 +0800 Subject: [PATCH 3/3] Trailing Whitespace in fred test Signed-off-by: Shan Kang --- BM/fred/fred_test_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BM/fred/fred_test_driver.c b/BM/fred/fred_test_driver.c index 0ca2111..7305683 100644 --- a/BM/fred/fred_test_driver.c +++ b/BM/fred/fred_test_driver.c @@ -106,7 +106,7 @@ static void check_wrmsr_cycles(long loop) local_irq_disable(); preempt_disable(); gs_base = fred_test_rdmsr(MSR_GS_BASE); - wrmsrl(0x38f, 0); // clear global_ctrl + wrmsrl(0x38f, 0); // clear global_ctrl wrmsrl(0x30b, 0); // clear fixed counter 2 value (REF_TSC) wrmsrl(0x38f, BIT_ULL(32 + 2)); // enable fixed counter in global_ctrl wrmsrl(0x38d, 0x300); // enable fixed counter 2