1

I tried to make a simple kernel module invalidating all tlb entries through user-level ioctl.

Below is my example code [flush_tlb.c]

/*
 * flush_tlb.c
 */
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>

#include "flush_tlb.h"

MODULE_LICENSE("GPL");


static long flush_tlb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    int ret = 0;
    unsigned int size = _IOC_SIZE(cmd);
    void __user *ubuf = (void __user *)arg;
    struct flush_tlb_parv_t flush_tlb_parv;

    // copy an argument from user-level
    if (size != sizeof(struct flush_tlb_parv_t)) {
        ret = -EINVAL;
        goto out;
    }
    if (copy_from_user(&flush_tlb_parv, ubuf, sizeof(flush_tlb_parv))) {
        ret = -EFAULT;
        goto out;
    }

    if (flush_tlb_parv.addr) {
        // Not Implemented
        flush_tlb_all(); 
    } else {
        flush_tlb_all(); 
    }
out:
    return ret;
}

static const struct file_operations flush_tlb_fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = flush_tlb_ioctl,
    .compat_ioctl = flush_tlb_ioctl,
};

static struct miscdevice binder_miscdev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "flush_tlb",
    .fops = &flush_tlb_fops
};

static int __init flush_tlb_init(void)
{
    int ret;

    ret = misc_register(&binder_miscdev);

    return ret;
}
module_init(flush_tlb_init)


static void __exit flush_tlb_exit(void)
{
    misc_deregister(&binder_miscdev);
}
module_exit(flush_tlb_exit)

And here is my [Makefile]

obj-m += flush_tlb.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

It is successfully compiled, but when I insert the module by insmod, it fails with following kernel logs. "flush_tlb: Unknown symbol flush_tlb_all (err 0)"

Also, I checked the /proc/kallsyms that flush_tlb_all exists in the symbol table.

$cat /proc/kallsyms | grep flush_tlb_all
ffffffff81022f90 T xen_flush_tlb_all
ffffffff810274a0 t trace_raw_output_xen_mmu_flush_tlb_all
ffffffff81027af0 t trace_event_raw_event_xen_mmu_flush_tlb_all
ffffffff81028c20 t perf_trace_xen_mmu_flush_tlb_all
ffffffff81072670 t do_flush_tlb_all
ffffffff81072bf0 T flush_tlb_all
ffffffff810792c0 t __flush_tlb_all
ffffffff8107d7cf t __flush_tlb_all
ffffffff81d76570 r __tracepoint_ptr_xen_mmu_flush_tlb_all
ffffffff81d77630 r __tpstrtab_xen_mmu_flush_tlb_all
ffffffff81e231f8 d print_fmt_xen_mmu_flush_tlb_all
ffffffff81e23f20 d trace_event_type_funcs_xen_mmu_flush_tlb_all
ffffffff81e24780 d event_xen_mmu_flush_tlb_all
ffffffff81f04720 d event_class_xen_mmu_flush_tlb_all
ffffffff81f103a0 D __tracepoint_xen_mmu_flush_tlb_all
ffffffff81f6772c t trace_event_define_fields_xen_mmu_flush_tlb_all
ffffffff8208c080 t __event_xen_mmu_flush_tlb_all

How can I fix it? Thanks.

Joonsung Kim
  • 246
  • 1
  • 3
  • 15
  • 1
    It looks like `flush_tlb_all` isn't exported for use in **kernel modules**: there is no `EXPORT_SYMBOL` invocation for it. (The function is defined in [/arch/x86/mm/tlb.c](https://elixir.bootlin.com/linux/v3.9.11/source/arch/x86/mm/tlb.c#L264)). Only the code, compiled into the kernel, may use such functions. – Tsyvarev Aug 29 '18 at 18:00
  • @Tsyvarev What is a relationship between EXPORT_SYMBOL and kallsyms? I thought that entries in the kallsyms mean the symobls exported by "EXPORT_SYMBOL" or "extern" keywords. Are there any difference between EXPORT_SYMBOL and extern? relationship among kallsyms, extern, EXPORT_SYMBOL? – Joonsung Kim Aug 29 '18 at 18:30
  • 1
    See [that question](https://stackoverflow.com/questions/32965535/kernel-symbol-marked-with-t-in-proc-kallsyms-is-not-exported) about relation between `/proc/kallsyms` and symbols, exported for kernel modules. – Tsyvarev Aug 29 '18 at 18:33
  • @Tsyvarev The perfect explanation!!! Thanks :) – Joonsung Kim Aug 29 '18 at 18:35
  • 2
    Possible duplicate of [kernel symbol marked with "T" in /proc/kallsyms is not exported](https://stackoverflow.com/questions/32965535/kernel-symbol-marked-with-t-in-proc-kallsyms-is-not-exported) – Tsyvarev Aug 29 '18 at 19:28

0 Answers0