Fix for multiple sarea bug + agp built into kernel segfault
parent
f3ae6786f8
commit
9199075a6a
|
@ -558,6 +558,9 @@ extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
|
|||
extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
@ -569,6 +572,9 @@ extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
|
|||
extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
|
@ -287,23 +287,40 @@ drm_agp_head_t *drm_agp_init(void)
|
|||
return NULL;
|
||||
memset((void *)head, 0, sizeof(*head));
|
||||
(*drm_agp.copy_info)(&head->agp_info);
|
||||
if (head->agp_info.chipset == NOT_SUPPORTED) {
|
||||
drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
|
||||
return NULL;
|
||||
}
|
||||
head->memory = NULL;
|
||||
switch (head->agp_info.chipset) {
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default:
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
case INTEL_I840: head->chipset = "Intel i840"; break;
|
||||
#endif
|
||||
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
case VIA_MVP4: head->chipset = "VIA MVP4"; break;
|
||||
case VIA_APOLLO_SUPER: head->chipset = "VIA Apollo Super";
|
||||
break;
|
||||
#endif
|
||||
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro";
|
||||
break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default: head->chipset = "Unknown"; break;
|
||||
}
|
||||
DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
|
||||
head->agp_info.version.major,
|
||||
|
|
|
@ -558,6 +558,9 @@ extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
|
|||
extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
@ -569,6 +572,9 @@ extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
|
|||
extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
52
linux/vm.c
52
linux/vm.c
|
@ -44,6 +44,12 @@ struct vm_operations_struct drm_vm_shm_ops = {
|
|||
close: drm_vm_close,
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_shm_lock_ops = {
|
||||
nopage: drm_vm_shm_nopage_lock,
|
||||
open: drm_vm_open,
|
||||
close: drm_vm_close,
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_dma_ops = {
|
||||
nopage: drm_vm_dma_nopage,
|
||||
open: drm_vm_open,
|
||||
|
@ -76,6 +82,40 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
|
|||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
|
||||
#else
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_pte;
|
||||
#endif
|
||||
unsigned long physical;
|
||||
unsigned long offset;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!map) return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
physical = (unsigned long)map->handle + offset;
|
||||
atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
|
||||
|
||||
DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return physical;
|
||||
#else
|
||||
return mem_map + MAP_NR(physical);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
@ -298,7 +338,17 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
if (map->flags & _DRM_CONTAINS_LOCK)
|
||||
vma->vm_ops = &drm_vm_shm_lock_ops;
|
||||
else {
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
vma->vm_private_data = (void *)map;
|
||||
#else
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't let this area swap. Change when
|
||||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
|
|
Loading…
Reference in New Issue