This commit is contained in:
Zhengyi Chen 2024-01-16 23:48:26 +00:00
parent 2673484d77
commit 0e4e4f3a7b
4 changed files with 133 additions and 9 deletions

View file

@ -1,4 +1,12 @@
#include "asm-generic/errno-base.h"
#include "asm/current.h"
#include "asm/page-def.h"
#include "linux/export.h"
#include "linux/fs.h"
#include "linux/gfp_types.h"
#include "linux/rcupdate.h"
#include <asm-generic/cacheflush.h>
#include <asm/cacheflush.h>
#include <linux/irqflags.h>
#include <linux/mm_types.h>
#include <linux/mmap_lock.h>
@ -15,6 +23,23 @@ module_param_named(pid, param_pid, int, 0644);
static unsigned long param_vmaddr;
module_param_named(addr, param_vmaddr, ulong, 0644);
static void *page_addr = NULL;
/* Design:
* 2 userspace threads (each affine to a different CPU to prevent non-aliasing
* caches from incoherence prevention).
* 1. Load kernel module, init chardev which provide page mapping.
* 2. Run userspace program, wherein each thread mmaps the chardev for the same
* mapping.
* Otherwise -- one thread mmaps the chardev, but the kernel itself also
* modifies.
* 3. On write: kernel module examines the content of in-kernel mapping vs.
* userspace mapping, which have same PA but obv. diff VA. They should be
* dissimilar by VIPT.
* Then, the kernel flushes dcache for the userspace to read.
* Finally, it reads again to see whether two mappings agree.
*/
static int __init flush_dcache_init(void)
{
struct task_struct *tsk;
@ -53,18 +78,17 @@ static int __init flush_dcache_init(void)
goto ret_err_no_page;
}
// Begin test. We ABSOLUTELY cannot be interrupted here...
/* Begin test --
* It may complicate things if this got preempted, so no preemption.
*/
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
// [TODO] Alter main memory content from kernel.
pr_info("Before flush: cache line/memory diff: ");
flush_dcache_page(page_of_addr);
#if ARCH == arm64
// dcache_clean_poc()
#endif
// dcache_clean_
pr_info("After flush: ...");
mmap_read_unlock(mm_of_tsk);
local_irq_restore(_eflags);
@ -88,9 +112,73 @@ ret_err_no_page:
static void __exit flush_dcache_exit(void)
{
free_page((ulong) page_addr);
pr_info("[%s] See ya~", __func__);
}
int _flush_dcache_init_devfs(void)
{
}
int _flush_dcache_init_backend(void)
{
page_addr = alloc_page(GFP_USER);
if (!page_addr)
goto ret_err_alloc_failed;
return 0;
ret_err_alloc_failed:
pr_err("[%s] Failed to allocate virtual memory page.", __func__);
return -ENOMEM;
}
static int flush_dcache_open(struct inode *inode, struct file *filp)
{
filp->f_mode |= FMODE_CAN_ODIRECT;
return generic_file_open(inode, filp);
}
static int flush_dcache_mmap(struct file *filp, struct vm_area_struct *vma)
{
/* Check if vma has mm backing -- e.g., non-kthread */
if (!vma->vm_mm)
goto ret_err_no_mm;
/* Check vma size */
ulong vma_size =
PAGE_ALIGN(max(PAGE_SIZE, vma->vm_end - vma->vm_start));
if (vma_size != PAGE_SIZE)
goto ret_err_wrong_size;
/* Insert page */
struct page *page = vmalloc_to_page(page_addr);
vm_insert_page(vma, vma->vm_start, page);
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND);
pr_info("[%s] mmapped vma: 0x%lx-0x%lx",
__func__, vma->vm_start, vma->vm_end);
return 0;
ret_err_no_mm:
pr_err("[%s] vm_area_struct has null vm_mm -- kthread or crashed?",
__func__);
return -EINVAL;
ret_err_wrong_size:
pr_err("[%s] Requested %ld pages -- please request only 1!",
__func__, vma_size);
return -EINVAL;
}
const struct file_operations flush_dcache_fops = {
.owner = THIS_MODULE,
.open = flush_dcache_open,
.mmap = flush_dcache_mmap
};
// const struct vm_operations_struct flush_dcache_vmops = {
// .mremap = NULL,
// };
module_init(flush_dcache_init);
module_exit(flush_dcache_exit);

View file

@ -0,0 +1,16 @@
{
"configurations": [
{
"name": "C-clang-arm64",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "clang-arm64"
}
],
"version": 4
}

View file

@ -0,0 +1,9 @@
{
"C_Cpp.errorSquiggles": "enabled",
"files.associations": {
"*.h": "c",
},
"editor.insertSpaces": false,
"editor.indentSize": "tabSize",
"editor.tabSize": 4,
}

View file

@ -0,0 +1,11 @@
/**
* @file userspace.c
* @author Zhengyi Chen (you@domain.com)
* @brief
* @version 0.1
* @date 2024-01-16
*
* @copyright Copyright (c) 2024
*
*/