diff -puNr vmmon-only.orig/linux/driver.c vmmon-only/linux/driver.c --- vmmon-only.orig/linux/driver.c 2008-05-10 06:25:56.000000000 +0200 +++ vmmon-only/linux/driver.c 2008-07-27 17:09:29.000000000 +0200 @@ -98,6 +98,15 @@ static int LinuxDriverAPMstate = APM_STA #define VMWare_SetVTracer(VTrace_Set) #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +#define VMW_NOPAGE_2624 + +#define VMMON_MAP_OFFSET_SHIFT 0 +#define VMMON_MAP_OFFSET_MASK 0x00000FFF +#define VMMON_MAP_OFFSET(base) \ + (((base) >> VMMON_MAP_OFFSET_SHIFT) & VMMON_MAP_OFFSET_MASK) +#endif + struct VMXLinuxState linuxState; @@ -122,7 +131,10 @@ static long LinuxDriver_CompatIoctl(stru static int LinuxDriver_Close(struct inode *inode, struct file *filp); static unsigned int LinuxDriverPoll(struct file *file, poll_table *wait); -#if defined(VMW_NOPAGE_261) +#if defined(VMW_NOPAGE_2624) +static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault); +static int LinuxDriverLockedFault(struct vm_area_struct *vma, struct vm_fault *fault); +#elif defined(VMW_NOPAGE_261) static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, unsigned long address, int *type); static struct page *LinuxDriverLockedNoPage(struct vm_area_struct *vma, @@ -143,11 +155,19 @@ static int LinuxDriverMmap(struct file * static void LinuxDriverPollTimeout(unsigned long clientData); static struct vm_operations_struct vmuser_mops = { +#ifdef VMW_NOPAGE_2624 + .fault = LinuxDriverFault +#else .nopage = LinuxDriverNoPage +#endif }; struct vm_operations_struct vmuser_locked_mops = { +#ifdef VMW_NOPAGE_2624 + .fault = LinuxDriverLockedFault +#else .nopage = LinuxDriverLockedNoPage +#endif }; static struct file_operations vmuser_fops; @@ -987,7 +1007,10 @@ LinuxDriverIPIHandler(void *info) *----------------------------------------------------------------------------- */ -#ifdef VMW_NOPAGE_261 +#if defined(VMW_NOPAGE_2624) +static int LinuxDriverFault(struct vm_area_struct *vma, //IN + struct vm_fault *fault) //IN/OUT +#elif defined(VMW_NOPAGE_261) static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, //IN unsigned long address, //IN int *type) //OUT: Fault type @@ -1004,12 +1027,24 @@ static unsigned long LinuxDriverNoPage(s VMLinux *vmLinux = (VMLinux *) vma->vm_file->private_data; unsigned long pg; +#ifdef VMW_NOPAGE_2624 + pg = fault->pgoff; + pg = VMMON_MAP_OFFSET(pg); +#else pg = (address - vma->vm_start) >> PAGE_SHIFT; +#endif if (pg >= vmLinux->size4Gb) { +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return 0; +#endif } get_page(virt_to_page(vmLinux->pages4Gb[pg])); -#ifdef KERNEL_2_4_0 +#ifdef VMW_NOPAGE_2624 + fault->page = virt_to_page(vmLinux->pages4Gb[pg]); + return 0; +#elif defined(KERNEL_2_4_0) #ifdef VMW_NOPAGE_261 *type = VM_FAULT_MINOR; #endif @@ -1037,7 +1072,10 @@ static unsigned long LinuxDriverNoPage(s *----------------------------------------------------------------------------- */ -#ifdef VMW_NOPAGE_261 +#if defined(VMW_NOPAGE_2624) +static int LinuxDriverLockedFault(struct vm_area_struct *vma, //IN + struct vm_fault *fault) //IN/OUT +#elif defined(VMW_NOPAGE_261) static struct page *LinuxDriverLockedNoPage(struct vm_area_struct *vma, //IN unsigned long address, //IN int *type) //OUT: Fault type @@ -1057,33 +1095,60 @@ static unsigned long LinuxDriverLockedNo struct VMHostEntry* vmhe; struct page* result; +#ifdef VMW_NOPAGE_2624 + pg = fault->pgoff; +#else pg = ((address - vma->vm_start) >> PAGE_SHIFT) + compat_vm_pgoff(vma); +#endif if (pg >= vmLinux->sizeLocked) { printk(KERN_DEBUG "vmmon: Something went wrong: entry %08lX out of range (>=%08X) for mapping on filp %p\n", pg, vmLinux->sizeLocked, vmLinux); +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return NOPAGE_SIGBUS; +#endif } if (!vmLinux->vm || !vmLinux->vm->vmhost) { printk(KERN_DEBUG "vmmon: Something went wrong: no vm or vmhost for mapping on filp %p\n", vmLinux); +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return NOPAGE_SIGBUS; +#endif } pgt = vmLinux->pagesLocked->ent[pg / VMHOST_MAPPING_PT]; if (!pgt) { printk(KERN_DEBUG "vmmon: Something went wrong: missing entry %08lX from mapping on filp %p\n", pg, vmLinux); +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return NOPAGE_SIGBUS; +#endif } vmhe = kmap(pgt); result = vmhe->ent[pg % VMHOST_MAPPING_PT]; kunmap(pgt); if (!result) { printk(KERN_DEBUG "vmmon: Something went wrong: attempt to access non-existing entry %08lX in mapping on filp %p\n", pg, vmLinux); +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return NOPAGE_SIGBUS; +#endif } if (!PhysTrack_Test(vmLinux->vm->vmhost->AWEPages, page_to_pfn(result))) { printk(KERN_DEBUG "vmmon: MPN %08lX not tracked! Someone released it before removing it from VA first!\n", pg); +#ifdef VMW_NOPAGE_2624 + return VM_FAULT_SIGBUS; +#else return NOPAGE_SIGBUS; +#endif } get_page(result); -#ifdef KERNEL_2_4_0 +#ifdef VMW_NOPAGE_2624 + fault->page = result; + return 0; +#elif defined(KERNEL_2_4_0) #ifdef VMW_NOPAGE_261 *type = VM_FAULT_MINOR; #endif