Skip to content

Commit

Permalink
patches: Add two patches with DAX fixes
Browse files Browse the repository at this point in the history
Signed-off-by: Asahi Lina <[email protected]>
  • Loading branch information
asahilina committed Nov 1, 2024
1 parent 4cd1240 commit cb6c96d
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
39 changes: 39 additions & 0 deletions patches/0019-dax-Allow-block-size-PAGE_SIZE.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
From ce899b86d685b28016cc27c505d1fdca468c9b2e Mon Sep 17 00:00:00 2001
From: Asahi Lina <[email protected]>
Date: Sun, 20 Oct 2024 01:23:41 +0900
Subject: [PATCH 1/2] dax: Allow block size > PAGE_SIZE

For virtio-dax, the file/FS blocksize is irrelevant. FUSE always uses
large DAX blocks (2MiB), which will work with all host page sizes. Since
we are mapping files into the DAX window on the host, the underlying
block size of the filesystem and its block device (if any) are
meaningless.

For real devices with DAX, the only requirement should be that the FS
block size is *at least* as large as PAGE_SIZE, to ensure that at least
whole pages can be mapped out of the device contiguously.

Fixes warning when using virtio-dax on a 4K guest with a 16K host,
backed by tmpfs (which sets blksz == PAGE_SIZE on the host).

Signed-off-by: Asahi Lina <[email protected]>
---
fs/dax.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/dax.c b/fs/dax.c
index becb4a6920c6..2ef3b50e8d7a 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1032,7 +1032,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
int ret = 0;
unsigned int scanned = 0;

- if (WARN_ON_ONCE(inode->i_blkbits != PAGE_SHIFT))
+ if (WARN_ON_ONCE(inode->i_blkbits < PAGE_SHIFT))
return -EIO;

if (mapping_empty(mapping) || wbc->sync_mode != WB_SYNC_ALL)
--
2.47.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
From 9b1ab7cc1eb019d9e8ce1b63954c58eb0fbecd2c Mon Sep 17 00:00:00 2001
From: Asahi Lina <[email protected]>
Date: Mon, 21 Oct 2024 23:21:16 +0900
Subject: [PATCH 2/2] mm: Fix __wp_page_copy_user fallback path for remote mm

If the source page is a PFN mapping, we copy back from userspace.
However, if this fault is a remote access, we cannot use
__copy_from_user_inatomic. Instead, use access_remote_vm() in this case.

Fixes WARN when writing to CoW mappings into a remote process, such as
when using gdb on a binary present on a DAX filesystem.

[ 143.683782] ------------[ cut here ]------------
[ 143.683784] WARNING: CPU: 1 PID: 350 at mm/memory.c:2904 __wp_page_copy_user+0x120/0x2bc
[ 143.683793] CPU: 1 PID: 350 Comm: gdb Not tainted 6.6.52 #1
[ 143.683794] Hardware name: linux,dummy-virt (DT)
[ 143.683795] pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[ 143.683796] pc : __wp_page_copy_user+0x120/0x2bc
[ 143.683798] lr : __wp_page_copy_user+0x254/0x2bc
[ 143.683799] sp : ffff80008272b8b0
[ 143.683799] x29: ffff80008272b8b0 x28: 0000000000000000 x27: ffff000083bad580
[ 143.683801] x26: 0000000000000000 x25: 0000fffff7fd5000 x24: ffff000081db04c0
[ 143.683802] x23: ffff00014f24b000 x22: fffffc00053c92c0 x21: ffff000083502150
[ 143.683803] x20: 0000fffff7fd5000 x19: ffff80008272b9d0 x18: 0000000000000000
[ 143.683804] x17: ffff000081db0500 x16: ffff800080fe52a0 x15: 0000fffff7fd5000
[ 143.683804] x14: 0000000000bb1845 x13: 0000000000000080 x12: ffff80008272b880
[ 143.683805] x11: ffff000081d13600 x10: ffff000081d13608 x9 : ffff000081d1360c
[ 143.683806] x8 : ffff000083a16f00 x7 : 0000000000000010 x6 : ffff00014f24b000
[ 143.683807] x5 : ffff00014f24c000 x4 : 0000000000000000 x3 : ffff000083582000
[ 143.683807] x2 : 0000000000000f80 x1 : 0000fffff7fd5000 x0 : 0000000000001000
[ 143.683808] Call trace:
[ 143.683809] __wp_page_copy_user+0x120/0x2bc
[ 143.683810] wp_page_copy+0x98/0x5c0
[ 143.683813] do_wp_page+0x250/0x530
[ 143.683814] __handle_mm_fault+0x278/0x284
[ 143.683817] handle_mm_fault+0x64/0x1e8
[ 143.683819] faultin_page+0x5c/0x110
[ 143.683820] __get_user_pages+0xc8/0x2f4
[ 143.683821] get_user_pages_remote+0xac/0x30c
[ 143.683823] __access_remote_vm+0xb4/0x368
[ 143.683824] access_remote_vm+0x10/0x1c
[ 143.683826] mem_rw.isra.0+0xc4/0x218
[ 143.683831] mem_write+0x18/0x24
[ 143.683831] vfs_write+0xa0/0x37c
[ 143.683834] ksys_pwrite64+0x7c/0xc0
[ 143.683834] __arm64_sys_pwrite64+0x20/0x2c
[ 143.683835] invoke_syscall+0x48/0x10c
[ 143.683837] el0_svc_common.constprop.0+0x40/0xe0
[ 143.683839] do_el0_svc+0x1c/0x28
[ 143.683841] el0_svc+0x3c/0xdc
[ 143.683846] el0t_64_sync_handler+0x120/0x12c
[ 143.683848] el0t_64_sync+0x194/0x198
[ 143.683849] ---[ end trace 0000000000000000 ]---

Signed-off-by: Asahi Lina <[email protected]>
---
mm/memory.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/mm/memory.c b/mm/memory.c
index ebfc9768f801..277079edd24b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3078,13 +3078,18 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
update_mmu_cache_range(vmf, vma, addr, vmf->pte, 1);
}

+ /* If the mm is a remote mm, copy in the page using access_remote_vm() */
+ if (current->mm != mm) {
+ if (access_remote_vm(mm, (unsigned long)uaddr, kaddr, PAGE_SIZE, 0) != PAGE_SIZE)
+ goto warn;
+ }
/*
* This really shouldn't fail, because the page is there
* in the page tables. But it might just be unreadable,
* in which case we just give up and fill the result with
* zeroes.
*/
- if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) {
+ else if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) {
if (vmf->pte)
goto warn;

--
2.47.0

0 comments on commit cb6c96d

Please sign in to comment.