Como instalar o driver proprietário AMD Catalyst(FGLRX) no Debian 8(Jessie) com kernel 4.10


Como instalar o driver proprietário AMD Catalyst(FGLRX) no Debian 8(Jessie) com kernel 4.10

Considerações


Este post é uma atualização para os posts:
Até o kernel 4.7 o driver proprietário AMD Catalyst(FGLRX) não apresenta problemas
A partir do kernel 4.8 é necessário aplicar os patches que serão apresentados neste post, para a instalação do driver AMD Catalyst(FGLRX) versão 15.12 do repositório backports do Debian 8(Jessie)

Informações:

Instalação do driver


O referido driver encontra-se disponível no repositório:
deb http://ftp.debian.org/debian jessie-backports main contrib non-free
deb-src http://ftp.debian.org/debian jessie-backports main contrib non-free
Dependências:
sudo apt-get install build-essential linux-headers-`uname -r` dkms
Para instalar o driver:
sudo apt-get -t jessei-backports install fglrx-control fglrx-driver fglrx-modules-dkms fglrx-source

Patches


Patch para o kernel


Este patch resolve o erro: FATAL: modpost: GPL-incompatible module fglrx.ko uses GPL-only symbol 'cpu_tlbstate'

Faça o download do patch ou crie um arquivo com o conteúdo:
diff -uNr linux-4.9.3/arch/x86/mm/init.c linux-4.9.3-patched/arch/x86/mm/init.c
--- linux-4.9.3/arch/x86/mm/init.c 2017-01-12 08:41:42.000000000 -0200
+++ linux-4.9.3-patched/arch/x86/mm/init.c 2017-01-13 10:50:37.450527421 -0200
@@ -751,7 +751,7 @@
 #endif
  .cr4 = ~0UL, /* fail hard if we screw up cr4 shadow initialization */
 };
-EXPORT_SYMBOL_GPL(cpu_tlbstate);
+EXPORT_SYMBOL(cpu_tlbstate);
 
 void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache)
 {
diff -uNr linux-4.9.3/drivers/pci/pci.c linux-4.9.3-patched/drivers/pci/pci.c
--- linux-4.9.3/drivers/pci/pci.c 2017-01-12 08:41:42.000000000 -0200
+++ linux-4.9.3-patched/drivers/pci/pci.c 2017-01-13 10:49:22.881387973 -0200
@@ -4983,7 +4983,7 @@
  if (bridge)
   bridge->ignore_hotplug = 1;
 }
-EXPORT_SYMBOL_GPL(pci_ignore_hotplug);
+EXPORT_SYMBOL(pci_ignore_hotplug);
 
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};

Para aplicar o patch:
cd /pasta-onde-esta-o-source-do-kernel/linux-x.x.x/
sudo patch -p1 < /alguma_pasta/kernel-GPL-only-symbol.patch
Após aplicar o patch é necessário recompilar o kernel

Patch para o módulo fglrx-15.12


Faça o download do patch ou crie um arquivo com o conteúdo:
diff -uNr fglrx-modules-dkms_15.12-2~bpo8+3_amd64/usr/src/fglrx-15.12/firegl_public.c fglrx-15.12/firegl_public.c
--- fglrx-modules-dkms_15.12-2~bpo8+3_amd64/usr/src/fglrx-15.12/firegl_public.c 2016-09-10 07:42:23.000000000 -0300
+++ fglrx-15.12/firegl_public.c 2017-03-31 18:57:41.282964520 -0300
@@ -3229,7 +3229,16 @@
 
     down_read(¤t->mm->mmap_sem);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
-    ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 1, 0, (struct page **)page_list, NULL);
+    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0) && LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 1, (struct page **)page_list, NULL);
+    #else
+        #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+            ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 1, 0, (struct page **)page_list, NULL);
+        #endif
+    #endif
+    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
+        ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 1, (struct page **)page_list, NULL, 0);
+    #endif
 #else
     ret = get_user_pages(current, current->mm, vaddr, page_cnt, 1, 0, (struct page **)page_list, NULL);
 #endif
@@ -3250,8 +3259,18 @@
     int ret;
 
     down_read(¤t->mm->mmap_sem);
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
-    ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 0, 0, (struct page **)page_list, NULL);
+    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0) && LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 0, (struct page **)page_list, NULL);
+    #else
+        #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+            ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 0, 0, (struct page **)page_list, NULL);
+        #endif
+    #endif
+    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
+        ret = get_user_pages_remote(current, current->mm, vaddr, page_cnt, 0, (struct page **)page_list, NULL, 0);
+    #endif
 #else
     ret = get_user_pages(current, current->mm, vaddr, page_cnt, 0, 0, (struct page **)page_list, NULL);
 #endif
@@ -3626,7 +3645,11 @@
     unsigned long pte_linear;
     mem_map_t* pMmPage;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-    unsigned long address = (unsigned long) (vmf->virtual_address);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        unsigned long address = (unsigned long) (vmf->virtual_address);
+    #else
+        unsigned long address = (unsigned long) (vmf->address);
+    #endif
 #endif
 
     /*
@@ -3701,7 +3724,13 @@
     unsigned long kaddr;
     mem_map_t* pMmPage;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-    unsigned long address = (unsigned long) (vmf->virtual_address);
+
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        unsigned long address = (unsigned long) (vmf->virtual_address);
+    #else
+        unsigned long address = (unsigned long) (vmf->address);
+    #endif
+
 #endif
 
     if (address > vma->vm_end)
@@ -3746,7 +3775,11 @@
     unsigned long kaddr;
     mem_map_t* pMmPage;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-    unsigned long address = (unsigned long) (vmf->virtual_address);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        unsigned long address = (unsigned long) (vmf->virtual_address);
+    #else
+        unsigned long address = (unsigned long) (vmf->address);
+    #endif
 #endif
 
     if (address > vma->vm_end)
@@ -3809,7 +3842,11 @@
     struct firegl_pcie_mem* pciemem;
     unsigned long* pagelist;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-    unsigned long address = (unsigned long) (vmf->virtual_address);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        unsigned long address = (unsigned long) (vmf->virtual_address);
+    #else
+        unsigned long address = (unsigned long) (vmf->address);
+    #endif
 #endif
     
     drm_device_t *dev = (drm_device_t *)firegl_get_dev_from_vm(vma);
@@ -3871,7 +3908,11 @@
     unsigned long offset;
     struct page *page;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-    unsigned long address = (unsigned long) (vmf->virtual_address);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
+        unsigned long address = (unsigned long) (vmf->virtual_address);
+    #else
+        unsigned long address = (unsigned long) (vmf->address);
+    #endif
 #endif
 
     if (address > vma->vm_end)
@@ -4165,13 +4206,21 @@
 
 #else
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
 #define TRACE_FAULT(_f, _v,_a)                                          \
    int  ret;                                                            \
    KCL_DEBUG_TRACEIN(FN_DRM_NOPAGE, (unsigned long)_a->virtual_address, NULL); \
    ret = _f(_v,_a);                                                     \
    KCL_DEBUG_TRACEOUT(FN_DRM_NOPAGE, ret, NULL);                                \
    return ret;
-
+#else
+#define TRACE_FAULT(_f, _v,_a)                                          \
+   int  ret;                                                            \
+   KCL_DEBUG_TRACEIN(FN_DRM_NOPAGE, (unsigned long)_a->address, NULL); \
+   ret = _f(_v,_a);                                                     \
+   KCL_DEBUG_TRACEOUT(FN_DRM_NOPAGE, ret, NULL);                                \
+   return ret;
+#endif
 static int ip_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
     TRACE_FAULT(do_vm_fault, vma, vmf);
diff -uNr fglrx-modules-dkms_15.12-2~bpo8+3_amd64/usr/src/fglrx-15.12/kcl_acpi.c fglrx-15.12/kcl_acpi.c
--- fglrx-modules-dkms_15.12-2~bpo8+3_amd64/usr/src/fglrx-15.12/kcl_acpi.c 2015-12-18 16:47:41.000000000 -0200
+++ fglrx-15.12/kcl_acpi.c 2017-03-31 18:57:41.280964545 -0300
@@ -359,7 +359,7 @@
 {
     struct acpi_table_header *hdr;
     acpi_size tbl_size ;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3)    
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3) &&  LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)  
     if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
 #else
     tbl_size = 0x7fffffff;
@@ -1029,7 +1029,7 @@
         return KCL_ACPI_ERROR; 
     }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3)    
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3) &&  LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)   
     if (!ACPI_SUCCESS(acpi_get_table_with_size(id, 0, &hdr, &tbl_size)))
 #else
tbl_size = 0x7fffffff;
Para aplicar o patch:
cd /usr/src/fglrx-15.12/
sudo patch -p1 < /alguma_pasta/fglrx-15.12-kernel-4.8_to_4.10.patch
Após aplicar o patch execute o comando para compilar o módulo e instalar:
sudo dkms autoinstall -k $(uname -r)
logoblog