[vbox-dev] Keeping up with Linus?
Larry Finger
Larry.Finger at lwfinger.net
Sun May 4 11:16:48 PDT 2008
Larry Finger wrote:
> w41ter at gmail.com wrote:
>> The code in question is:
>> static struct vm_operations_struct sf_vma_ops = {
>> .nopage = sf_reg_nopage
>> };
>>
>> I can find the problem but I don't know enough to fix it :-/
>> Does this look hard to fix, or not so much?
>
> That one is harder as it changes how one calculates the offset. If I get
> bored, I'll try to figure it out.
I guess I got bored, but the following patch compiles, the module loads,
_AND_ survived minimal testing.
Larry
---
Index: vbox/src/VBox/Additions/linux/sharedfolders/regops.c
===================================================================
--- vbox.orig/src/VBox/Additions/linux/sharedfolders/regops.c
+++ vbox/src/VBox/Additions/linux/sharedfolders/regops.c
@@ -314,14 +314,19 @@ sf_reg_release (struct inode *inode, str
return 0;
}
-static struct page *
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+static int sf_reg_fault( struct vm_area_struct *vma, struct vm_fault *vmf)
+#else
#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 0)
+static struct page *
sf_reg_nopage (struct vm_area_struct *vma, unsigned long vaddr, int unused)
#define SET_TYPE(t)
#else
+static struct page *
sf_reg_nopage (struct vm_area_struct *vma, unsigned long vaddr, int *type)
#define SET_TYPE(t) *type = (t)
-#endif
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 0) */
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25) */
{
struct page *page;
char *buf;
@@ -334,35 +339,56 @@ sf_reg_nopage (struct vm_area_struct *vm
struct sf_reg_info *sf_r = file->private_data;
TRACE ();
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ if (vmf->pgoff > vma->vm_end)
+ return VM_FAULT_SIGBUS;
+#else
if (vaddr > vma->vm_end) {
SET_TYPE (VM_FAULT_SIGBUS);
return NOPAGE_SIGBUS;
}
+#endif
page = alloc_page (GFP_HIGHUSER);
if (!page) {
LogRelFunc(("failed to allocate page\n"));
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ return VM_FAULT_OOM;
+#else
SET_TYPE (VM_FAULT_OOM);
return NOPAGE_OOM;
+#endif
}
buf = kmap (page);
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ off = (vmf->pgoff << PAGE_SHIFT);
+#else
off = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
+#endif
err = sf_reg_read_aux (__func__, sf_g, sf_r, buf, &nread, off);
if (err) {
kunmap (page);
put_page (page);
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ return VM_FAULT_SIGBUS;
+#else
SET_TYPE (VM_FAULT_SIGBUS);
return NOPAGE_SIGBUS;
+#endif
}
BUG_ON (nread > PAGE_SIZE);
if (!nread) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ clear_user_page (page_address (page), vmf->pgoff, page);
+#else
#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 0)
clear_user_page (page_address (page), vaddr);
#else
clear_user_page (page_address (page), vaddr, page);
#endif
+#endif
}
else {
memset (buf + nread, 0, PAGE_SIZE - nread);
@@ -370,14 +396,24 @@ sf_reg_nopage (struct vm_area_struct *vm
flush_dcache_page (page);
kunmap (page);
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 25)
SET_TYPE (VM_FAULT_MAJOR);
return page;
+#else
+ vmf->page = page;
+ return 0;
+#endif
}
static struct vm_operations_struct sf_vma_ops = {
+#if LINUX_VERSION_CODE > KERNEL_VERSION (2, 6, 25)
+ .fault = sf_reg_fault
+#else
.nopage = sf_reg_nopage
+#endif
};
+
static int
sf_reg_mmap (struct file *file, struct vm_area_struct *vma)
{
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 2.6.26
Url: http://www.virtualbox.org/pipermail/vbox-dev/attachments/20080504/c72a8631/attachment-0001.pl
More information about the vbox-dev
mailing list