Init module: flush_dcache
This commit is contained in:
parent
7c33afdfb2
commit
2673484d77
4 changed files with 189 additions and 0 deletions
38
src/aarch64-linux-flush-dcache/.vscode-ctags
Normal file
38
src/aarch64-linux-flush-dcache/.vscode-ctags
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/
|
||||||
|
!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/
|
||||||
|
!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/
|
||||||
|
!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/
|
||||||
|
!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/
|
||||||
|
!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/
|
||||||
|
!_TAG_FIELD_DESCRIPTION input /input file/
|
||||||
|
!_TAG_FIELD_DESCRIPTION name /tag name/
|
||||||
|
!_TAG_FIELD_DESCRIPTION pattern /pattern/
|
||||||
|
!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/
|
||||||
|
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||||
|
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C d,macro /macro definitions/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C e,enumerator /enumerators (values inside an enumeration)/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C f,function /function definitions/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C g,enum /enumeration names/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C h,header /included header files/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C m,member /struct, and union members/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C s,struct /structure names/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C t,typedef /typedefs/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C u,union /union names/
|
||||||
|
!_TAG_KIND_DESCRIPTION!C v,variable /variable definitions/
|
||||||
|
!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
|
||||||
|
!_TAG_OUTPUT_FILESEP slash /slash or backslash/
|
||||||
|
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
|
||||||
|
!_TAG_OUTPUT_VERSION 0.0 /current.age/
|
||||||
|
!_TAG_PARSER_VERSION!C 1.1 /current.age/
|
||||||
|
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
|
||||||
|
!_TAG_PROC_CWD /home/rubberhead/Git/00-UOE/unnamed_ba_thesis/src/aarch64-linux-flush-dcache/ //
|
||||||
|
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
|
||||||
|
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
|
||||||
|
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
|
||||||
|
!_TAG_PROGRAM_VERSION 6.1.0 /v6.1.0/
|
||||||
|
!_TAG_ROLE_DESCRIPTION!C!function foreigndecl /declared in foreign languages/
|
||||||
|
!_TAG_ROLE_DESCRIPTION!C!header local /local header/
|
||||||
|
!_TAG_ROLE_DESCRIPTION!C!header system /system header/
|
||||||
|
!_TAG_ROLE_DESCRIPTION!C!macro undef /undefined/
|
||||||
|
!_TAG_ROLE_DESCRIPTION!C!struct foreigndecl /declared in foreign languages/
|
||||||
44
src/aarch64-linux-flush-dcache/.vscode/c_cpp_properties.json
vendored
Normal file
44
src/aarch64-linux-flush-dcache/.vscode/c_cpp_properties.json
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux-clang-arm64",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/home/rubberhead/Git/linux/include",
|
||||||
|
"/home/rubberhead/Git/linux/include/uapi",
|
||||||
|
"/home/rubberhead/Git/linux/include/generated",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include/uapi",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include/generated",
|
||||||
|
"/usr/lib/gcc/aarch64-linux-gnu/13.2.0/include"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"__GNUC__",
|
||||||
|
"__KERNEL__"
|
||||||
|
],
|
||||||
|
"compilerPath": "/usr/bin/clang",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-nostdinc",
|
||||||
|
"-std=gnu11"
|
||||||
|
],
|
||||||
|
"cStandard": "gnu11",
|
||||||
|
"cppStandard": "${default}",
|
||||||
|
"browse": {
|
||||||
|
"path": [
|
||||||
|
"${workspaceFolder}",
|
||||||
|
"/home/rubberhead/Git/linux/include",
|
||||||
|
"/home/rubberhead/Git/linux/include/uapi",
|
||||||
|
"/home/rubberhead/Git/linux/include/generated",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include/uapi",
|
||||||
|
"/home/rubberhead/Git/linux/arch/arm64/include/generated",
|
||||||
|
"/usr/lib/gcc/aarch64-linux-gnu/13.2.0/include"
|
||||||
|
],
|
||||||
|
"limitSymbolsToIncludedHeaders": true,
|
||||||
|
"databaseFilename": ""
|
||||||
|
},
|
||||||
|
"intelliSenseMode": "linux-clang-arm64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
10
src/aarch64-linux-flush-dcache/.vscode/settings.json
vendored
Normal file
10
src/aarch64-linux-flush-dcache/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"C_Cpp.errorSquiggles": "enabled",
|
||||||
|
"files.associations": {
|
||||||
|
"*.h": "c",
|
||||||
|
},
|
||||||
|
"editor.insertSpaces": false,
|
||||||
|
"editor.indentSize": "tabSize",
|
||||||
|
"editor.tabSize": 8,
|
||||||
|
"clangd.arguments": ["--compile-commands-dir=/home/rubberhead/Git/linux"]
|
||||||
|
}
|
||||||
97
src/aarch64-linux-flush-dcache/mod_entry.c
Normal file
97
src/aarch64-linux-flush-dcache/mod_entry.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include <asm-generic/cacheflush.h>
|
||||||
|
#include <linux/irqflags.h>
|
||||||
|
#include <linux/mm_types.h>
|
||||||
|
#include <linux/mmap_lock.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
/* PID: The task for which page cache is to be flushed. */
|
||||||
|
static int param_pid;
|
||||||
|
module_param_named(pid, param_pid, int, 0644);
|
||||||
|
|
||||||
|
/* addr: The virtual memory address used to index into the page to be flushed. */
|
||||||
|
static unsigned long param_vmaddr;
|
||||||
|
module_param_named(addr, param_vmaddr, ulong, 0644);
|
||||||
|
|
||||||
|
static int __init flush_dcache_init(void)
|
||||||
|
{
|
||||||
|
struct task_struct *tsk;
|
||||||
|
struct mm_struct *mm_of_tsk;
|
||||||
|
struct page *page_of_addr;
|
||||||
|
|
||||||
|
// Get task_struct from PID, then get its mm_struct
|
||||||
|
rcu_read_lock();
|
||||||
|
tsk = find_task_by_pid_ns(param_pid, &init_pid_ns);
|
||||||
|
if (!tsk) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
goto ret_err_no_tsk;
|
||||||
|
}
|
||||||
|
mm_of_tsk = get_task_mm(tsk);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
// No mm_struct -- may be kthread?
|
||||||
|
if (!mm_of_tsk)
|
||||||
|
goto ret_warn_kthread;
|
||||||
|
|
||||||
|
/* Get page from mm_struct --
|
||||||
|
* We need to pin the page i.e., have it marked as FOLL_PIN.
|
||||||
|
* Ref. Documentation/core-api/pin_user_pages.rst:
|
||||||
|
* Because we are writing to the data represented by the page -- we are
|
||||||
|
* flushing cache to dirty page, after all -- we need FOLL_PIN instead
|
||||||
|
* of *get-API. This effectively? prevents page from being evicted in
|
||||||
|
* the short term.
|
||||||
|
*/
|
||||||
|
mmap_read_lock(mm_of_tsk);
|
||||||
|
long pin_pages_retval = pin_user_pages_remote(
|
||||||
|
mm_of_tsk, param_vmaddr, 1,
|
||||||
|
FOLL_WRITE, &page_of_addr, NULL
|
||||||
|
); // We know mmap is locked, stop asking.
|
||||||
|
if (pin_pages_retval != 1) {
|
||||||
|
mmap_read_unlock(mm_of_tsk);
|
||||||
|
goto ret_err_no_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin test. We ABSOLUTELY cannot be interrupted here...
|
||||||
|
unsigned long _eflags;
|
||||||
|
local_irq_save(_eflags);
|
||||||
|
// [TODO]: Use non-temporal instr to write directly to memory.
|
||||||
|
// This will most certainly require asm blocks...
|
||||||
|
// ...Or else, simulate a cache-incoherent DMA?
|
||||||
|
// e.g., run in qemu -> attach gdb on vmlinux -> breakpoint ->
|
||||||
|
// gdb examines physical mem -> gdb makes a silly write ->
|
||||||
|
// continue, check here.
|
||||||
|
// ...Or else, pgprot_noncached
|
||||||
|
pr_info("Before flush: cache line/memory diff: ");
|
||||||
|
flush_dcache_page(page_of_addr);
|
||||||
|
pr_info("After flush: ...");
|
||||||
|
mmap_read_unlock(mm_of_tsk);
|
||||||
|
local_irq_restore(_eflags);
|
||||||
|
|
||||||
|
unpin_user_pages(&page_of_addr, 1);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret_warn_kthread:
|
||||||
|
pr_warn("[%s] Cannot find `tsk->mm` for PID %d. This may be a kthread.\n"
|
||||||
|
"Messing with `active_mm` may be unsafe. Exiting...",
|
||||||
|
__func__, param_pid);
|
||||||
|
return 0;
|
||||||
|
ret_err_no_tsk:
|
||||||
|
pr_err("[%s] Cannot find `task_struct` for PID %d.",
|
||||||
|
__func__, param_pid);
|
||||||
|
return -EINVAL;
|
||||||
|
ret_err_no_page:
|
||||||
|
pr_err("[%s] Cannot pin requested pages. [TODO]", __func__);
|
||||||
|
return pin_pages_retval == 0 ? -EINVAL : (int)pin_pages_retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit flush_dcache_exit(void)
|
||||||
|
{
|
||||||
|
pr_info("[%s] See ya~", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(flush_dcache_init);
|
||||||
|
module_exit(flush_dcache_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
Loading…
Add table
Add a link
Reference in a new issue