aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Bakita <jbakita@cs.unc.edu>2025-10-01 11:54:47 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2025-10-01 11:54:47 -0400
commitb4a937788cead345f8f00419bd250d1d92b0290f (patch)
tree231d2d817c89550f744ba1e993700566c1612557
parent217aaa952fb812bfdce62402cfab959910ea7265 (diff)
Fix build warnings and errors on Linux 6.14ecrts25-ae
- Remove repetitive declarations of two `bus_type` structs. - Fix mmu.c to use an always-64-bit member for `parent_addr`. - Remove call to `page_mapcount_reset()` that isn't needed. - Correct `nvdebug_pd_page` documentation. - Disable missing prototype and missing declaration warnings. - Fix an improper type, and a missing type conversion. Tested build on Linux 6.14.0 (x86_64), 5.4.0 (x86_64), and 4.9.337 (aarch64).
-rw-r--r--Makefile3
-rw-r--r--mmu.c27
-rw-r--r--nvdebug.h2
-rw-r--r--nvdebug_entry.c2
-rw-r--r--stubs.h1
5 files changed, 16 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 9d6d374..e7b160c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
1obj-m += nvdebug.o 1obj-m += nvdebug.o
2nvdebug-objs = runlist_procfs.o device_info_procfs.o runlist.o mmu.o \ 2nvdebug-objs = runlist_procfs.o device_info_procfs.o runlist.o mmu.o \
3 nvdebug_entry.o bus.o nvdebug_linux.o copy_topology_procfs.o 3 nvdebug_entry.o bus.o nvdebug_linux.o copy_topology_procfs.o
4KBUILD_CFLAGS += -DGIT_HASH=\"$(shell git --git-dir=$(PWD)/.git rev-parse --short HEAD)\" 4KBUILD_CFLAGS += -DGIT_HASH=\"$(shell git --git-dir=$(PWD)/.git rev-parse --short HEAD)\" \
5 -Wno-missing-prototypes -Wno-missing-declarations
5# -mfentry above if not building due to mcount missing 6# -mfentry above if not building due to mcount missing
6 7
7all: 8all:
diff --git a/mmu.c b/mmu.c
index e2b9a91..bab2ea0 100644
--- a/mmu.c
+++ b/mmu.c
@@ -229,19 +229,20 @@ int translate_page_directory(struct nvdebug_state *g,
229// explictly permitted (see linux/mm_types.h). This struct is thus used by 229// explictly permitted (see linux/mm_types.h). This struct is thus used by
230// casting a pointer of struct page to a pointer of struct nvdebug_pd_page, 230// casting a pointer of struct page to a pointer of struct nvdebug_pd_page,
231// then accessing the associated fields. This pointer may also be freely cast 231// then accessing the associated fields. This pointer may also be freely cast
232// back to a sturct page pointer. 232// back to a struct page pointer.
233// We have 24 (32-bit) or 44 (64-bit) bytes available in the page struct 233// We have 20 (32-bit) or 40 (64-bit) bytes available in the page struct
234// (according to the documentation on struct page). Our comments indicate what 234// (according to the documentation on struct page). We use 20 (32-bit) or 28
235// available parts of struct page we repurpose for our own needs. 235// (64-bit) bytes. Our comments indicate what available parts of struct page we
236// repurpose for our own needs.
236struct nvdebug_pd_page { 237struct nvdebug_pd_page {
237 unsigned long __flags; // From struct page; do not touch! 238 unsigned long __flags; // From struct page; do not touch!
238 // Overlaps struct page.lru 239 // Overlaps struct page.lru
239 struct list_head list; // 4/8 bytes 240 struct list_head list; // 4/8 bytes
240 // Overlaps struct page.mapping (and page.share on 32-bit) 241 // Overlaps struct page.lru (and page.mapping on 32-bit)
241 uintptr_t parent_addr; // 8 bytes 242 uint64_t parent_addr; // 8 bytes
242 // Overlaps struct page.share (page.private on 32-bit) 243 // Overlaps struct page.mapping (page.share on 32-bit)
243 enum PD_TARGET parent_aperture; // 4 bytes 244 enum PD_TARGET parent_aperture; // 4 bytes
244 // Overlaps page.private (page.page_type on 32-bit) 245 // Overlaps page.mapping and page.share (page.private on 32-bit)
245 dma_addr_t dma_addr; // 4/8 bytes 246 dma_addr_t dma_addr; // 4/8 bytes
246}; 247};
247 248
@@ -262,12 +263,12 @@ int gc_page_directory(struct nvdebug_state *g, bool force) {
262 // (This is depth-first because map_page_directory() always allocates and 263 // (This is depth-first because map_page_directory() always allocates and
263 // pushes page directory allocations before page table allocations.) 264 // pushes page directory allocations before page table allocations.)
264 list_for_each_entry_safe_reverse(page, _page, &g->pd_allocs, list) { 265 list_for_each_entry_safe_reverse(page, _page, &g->pd_allocs, list) {
265 printk_debug(KERN_DEBUG "[nvdebug] %s: Checking if page directory/table at %llx (SYS_MEM_?) with parent at %lx (%s) is unused...\n", __func__, page->dma_addr, page->parent_addr, pd_target_to_text(page->parent_aperture)); 266 printk_debug(KERN_DEBUG "[nvdebug] %s: Checking if page directory/table at %llx (SYS_MEM_?) with parent at %llx (%s) is unused...\n", __func__, page->dma_addr, page->parent_addr, pd_target_to_text(page->parent_aperture));
266 // Try to determine if we're still in-use. We consider ourselves 267 // Try to determine if we're still in-use. We consider ourselves
267 // potentially in-use if our parent still points to us. 268 // potentially in-use if our parent still points to us.
268 parent_kva = pd_deref(g, page->parent_addr, page->parent_aperture); 269 parent_kva = pd_deref(g, page->parent_addr, page->parent_aperture);
269 if (IS_ERR(parent_kva)) { 270 if (IS_ERR(parent_kva)) {
270 printk(KERN_ERR "[nvdebug] %s: Error resolving %#lx in GPU %s to a kernel-accessible address. Error %ld.\n", __func__, page->parent_addr, pd_target_to_text(page->parent_aperture), PTR_ERR(parent_kva)); 271 printk(KERN_ERR "[nvdebug] %s: Error resolving %#llx in GPU %s to a kernel-accessible address. Error %ld.\n", __func__, page->parent_addr, pd_target_to_text(page->parent_aperture), PTR_ERR(parent_kva));
271 return -ENOTRECOVERABLE; 272 return -ENOTRECOVERABLE;
272 } 273 }
273 // A NULL kva indicates parent no longer exists 274 // A NULL kva indicates parent no longer exists
@@ -277,14 +278,12 @@ int gc_page_directory(struct nvdebug_state *g, bool force) {
277 continue; 278 continue;
278 // Free this page table/directory and delete our parent's pointer to us 279 // Free this page table/directory and delete our parent's pointer to us
279 if (parent_entry.addr_w == (page->dma_addr >> 12)) { 280 if (parent_entry.addr_w == (page->dma_addr >> 12)) {
280 printk(KERN_WARNING "[nvdebug] %s: Deleting page table/directory at %llx (SYS_MEM_?) with parent at %lx (%s) that may still be in-use!\n", __func__, page->dma_addr, page->parent_addr, pd_target_to_text(page->parent_aperture)); 281 printk(KERN_WARNING "[nvdebug] %s: Deleting page table/directory at %llx (SYS_MEM_?) with parent at %llx (%s) that may still be in-use!\n", __func__, page->dma_addr, page->parent_addr, pd_target_to_text(page->parent_aperture));
281 writeq(0, parent_kva); 282 writeq(0, parent_kva);
282 } 283 }
283 // Unmap, zero, free, and remove from tracking (these all return void) 284 // Unmap, zero, free, and remove from tracking (these all return void)
284 dma_unmap_page(g->dev, page->dma_addr, PAGE_SIZE, DMA_TO_DEVICE); 285 dma_unmap_page(g->dev, page->dma_addr, PAGE_SIZE, DMA_TO_DEVICE);
285 memset(page_to_virt((struct page*)page), 0, PAGE_SIZE); 286 memset(page_to_virt((struct page*)page), 0, PAGE_SIZE);
286 // Necessary to reset mapcount as we (ab)use its state for other things
287 page_mapcount_reset((struct page*)page);
288 // Same reset needed for mapping 287 // Same reset needed for mapping
289 ((struct page*)page)->mapping = NULL; 288 ((struct page*)page)->mapping = NULL;
290 // Remove this page from our list of allocated pages 289 // Remove this page from our list of allocated pages
@@ -607,7 +606,7 @@ int translate_v1_page_directory(struct nvdebug_state *g,
607 // Convert VID_MEM/SYS_MEM address to Kernel-accessible Virtual Address (KVA) 606 // Convert VID_MEM/SYS_MEM address to Kernel-accessible Virtual Address (KVA)
608 pte_kva = pd_deref(g, pte_phys, V12PD_TARGET(pde.alt_target)); 607 pte_kva = pd_deref(g, pte_phys, V12PD_TARGET(pde.alt_target));
609 if (IS_ERR_OR_NULL(pde_kva)) { 608 if (IS_ERR_OR_NULL(pde_kva)) {
610 printk(KERN_ERR "[nvdebug] %s: Unable to resolve %#lx in GPU %s to a kernel-accessible address. Error %ld.\n", __func__, pte_phys, pd_target_to_text(pde.alt_target), PTR_ERR(pte_kva)); 609 printk(KERN_ERR "[nvdebug] %s: Unable to resolve %#lx in GPU %s to a kernel-accessible address. Error %ld.\n", __func__, pte_phys, pd_target_to_text(V12PD_TARGET(pde.alt_target)), PTR_ERR(pte_kva));
611 return PTR_ERR(pte_kva); 610 return PTR_ERR(pte_kva);
612 } 611 }
613 // Read page table entry 612 // Read page table entry
diff --git a/nvdebug.h b/nvdebug.h
index 3ac8db4..ecfb051 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -1620,7 +1620,7 @@ static inline const char *compute_preempt_type_to_text(enum COMPUTE_PREEMPT_TYPE
1620 return "INVALID"; 1620 return "INVALID";
1621 } 1621 }
1622} 1622}
1623static inline const char *graphics_preempt_type_to_text(enum COMPUTE_PREEMPT_TYPE t) { 1623static inline const char *graphics_preempt_type_to_text(enum GRAPHICS_PREEMPT_TYPE t) {
1624 switch (t) { 1624 switch (t) {
1625 case PREEMPT_WFI: 1625 case PREEMPT_WFI:
1626 return "WFI"; 1626 return "WFI";
diff --git a/nvdebug_entry.c b/nvdebug_entry.c
index c0cfa63..8293fdc 100644
--- a/nvdebug_entry.c
+++ b/nvdebug_entry.c
@@ -48,8 +48,6 @@ extern struct file_operations copy_topology_file_ops;
48 48
49struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES]; 49struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES];
50unsigned int g_nvdebug_devices = 0; 50unsigned int g_nvdebug_devices = 0;
51// Bus types are global symbols in the kernel
52extern struct bus_type platform_bus_type;
53 51
54// Starting in Kernel 5.6, proc_ops is required instead of file_operations. 52// Starting in Kernel 5.6, proc_ops is required instead of file_operations.
55// As file_operations is larger than proc_ops, we can overwrite the memory 53// As file_operations is larger than proc_ops, we can overwrite the memory
diff --git a/stubs.h b/stubs.h
index b909587..da14bed 100644
--- a/stubs.h
+++ b/stubs.h
@@ -29,7 +29,6 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
29// Functions from drivers/pci/search.h 29// Functions from drivers/pci/search.h
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/pci.h> 31#include <linux/pci.h>
32extern struct bus_type pci_bus_type;
33 32
34#if LINUX_VERSION_CODE < KERNEL_VERSION(5,3,0) 33#if LINUX_VERSION_CODE < KERNEL_VERSION(5,3,0)
35static int match_pci_dev_by_id(struct device *dev, void *data) 34static int match_pci_dev_by_id(struct device *dev, void *data)