Viewing: symbols.c
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2025, Amazon and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* Author: Timothy Day <timday@amazon.com>
*/
#include <linux/kprobes.h>
#include <linux/memcontrol.h>
#include <lustre_compat/linux/mm.h>
#include <lustre_compat/linux/security.h>
#include <lustre_compat/linux/vmalloc.h>
#include <lustre_compat/linux/workqueue.h>
#include <linux/libcfs/libcfs.h>
static void *(*__cfs_kallsyms_lookup_name)(const char *name);
void *cfs_kallsyms_lookup_name(const char *name)
{
return __cfs_kallsyms_lookup_name(name);
}
EXPORT_SYMBOL_GPL(cfs_kallsyms_lookup_name);
#ifdef HAVE_KALLSYMS_LOOKUP_NAME
static int find_kallsyms_lookup_name(void)
{
__cfs_kallsyms_lookup_name = (void *(*)(const char *))kallsyms_lookup_name;
return 0;
}
#else
static int find_kallsyms_lookup_name(void)
{
struct kprobe kp = {
.symbol_name = "kallsyms_lookup_name",
};
int rc;
rc = register_kprobe(&kp);
if (rc < 0)
return rc;
__cfs_kallsyms_lookup_name = (void *)kp.addr;
if (!__cfs_kallsyms_lookup_name)
return -EINVAL;
unregister_kprobe(&kp);
return 0;
}
#endif
static struct workqueue_attrs *(*__alloc_workqueue_attrs)(void);
struct workqueue_attrs *compat_alloc_workqueue_attrs(void)
{
return __alloc_workqueue_attrs();
}
EXPORT_SYMBOL(compat_alloc_workqueue_attrs);
static void (*__free_workqueue_attrs)(struct workqueue_attrs *attrs);
void compat_free_workqueue_attrs(struct workqueue_attrs *attrs)
{
return __free_workqueue_attrs(attrs);
}
EXPORT_SYMBOL(compat_free_workqueue_attrs);
static int (*__apply_workqueue_attrs)(struct workqueue_struct *wq,
const struct workqueue_attrs *attrs);
int compat_apply_workqueue_attrs(struct workqueue_struct *wq,
const struct workqueue_attrs *attrs)
{
return __apply_workqueue_attrs(wq, attrs);
}
EXPORT_SYMBOL(compat_apply_workqueue_attrs);
#ifdef alloc_workqueue_attrs
# define ALLOC_WQ_ATTRS_FUNC "alloc_workqueue_attrs_noprof"
#else
# define ALLOC_WQ_ATTRS_FUNC "alloc_workqueue_attrs"
#endif
#if defined(CONFIG_MEMCG) && !defined(HAVE_FOLIO_MEMCG_LOCK_STATIC) \
&& defined(HAVE_FOLIO_MEMCG_LOCK) && !defined(FOLIO_MEMCG_LOCK_EXPORTED)
static void (*__folio_memcg_lock)(struct folio *folio);
void folio_memcg_lock(struct folio *folio)
{
__folio_memcg_lock(folio);
}
EXPORT_SYMBOL_GPL(folio_memcg_lock);
static void (*__folio_memcg_unlock)(struct folio *folio);
void folio_memcg_unlock(struct folio *folio)
{
__folio_memcg_unlock(folio);
}
EXPORT_SYMBOL_GPL(folio_memcg_unlock);
#endif
#ifdef CONFIG_SECURITY
static int (*__security_file_alloc)(struct file *file);
static void (*__security_file_free)(struct file *file);
int compat_security_file_alloc(struct file *file)
{
return __security_file_alloc(file);
}
EXPORT_SYMBOL(compat_security_file_alloc);
void compat_security_file_free(struct file *file)
{
return __security_file_free(file);
}
EXPORT_SYMBOL(compat_security_file_free);
#endif
#if !defined(HAVE_ACCOUNT_PAGE_DIRTIED_EXPORT) && defined(HAVE_ACCOUNT_PAGE_DIRTIED)
static unsigned int (*__account_page_dirtied)(struct page *page,
struct address_space *mapping);
unsigned int compat_account_page_dirtied(struct page *page,
struct address_space *mapping)
{
return __account_page_dirtied(page, mapping);
}
EXPORT_SYMBOL(compat_account_page_dirtied);
#endif
int lustre_symbols_init(void)
{
int rc;
rc = find_kallsyms_lookup_name();
if (rc < 0)
return rc;
if (!cfs_kallsyms_lookup_name("kallsyms_lookup_name"))
return -EINVAL;
__alloc_workqueue_attrs = cfs_kallsyms_lookup_name(ALLOC_WQ_ATTRS_FUNC);
if (!__alloc_workqueue_attrs)
return -EINVAL;
__free_workqueue_attrs = cfs_kallsyms_lookup_name("free_workqueue_attrs");
if (!__free_workqueue_attrs)
return -EINVAL;
__apply_workqueue_attrs = cfs_kallsyms_lookup_name("apply_workqueue_attrs");
if (!__apply_workqueue_attrs)
return -EINVAL;
#if defined(CONFIG_MEMCG) && !defined(HAVE_FOLIO_MEMCG_LOCK_STATIC) \
&& defined(HAVE_FOLIO_MEMCG_LOCK) && !defined(FOLIO_MEMCG_LOCK_EXPORTED)
__folio_memcg_lock = cfs_kallsyms_lookup_name("folio_memcg_lock");
if (!__folio_memcg_lock)
return -EINVAL;
__folio_memcg_unlock = cfs_kallsyms_lookup_name("folio_memcg_unlock");
if (!__folio_memcg_unlock)
return -EINVAL;
#endif
#if !defined(HAVE_ACCOUNT_PAGE_DIRTIED_EXPORT) && defined(HAVE_ACCOUNT_PAGE_DIRTIED)
__account_page_dirtied = cfs_kallsyms_lookup_name("account_page_dirtied");
if (!__account_page_dirtied)
return -EINVAL;
#endif
#ifdef CONFIG_SECURITY
__security_file_alloc = cfs_kallsyms_lookup_name("security_file_alloc");
if (!__security_file_alloc)
return -EINVAL;
__security_file_free = cfs_kallsyms_lookup_name("security_file_free");
if (!__security_file_free)
return -EINVAL;
#endif
return 0;
}