2626#include "amdgpu.h"
2727#include "gmc_v8_0.h"
2828#include "amdgpu_ucode.h"
29+ #include "amdgpu_amdkfd.h"
2930
3031#include "gmc/gmc_8_1_d.h"
3132#include "gmc/gmc_8_1_sh_mask.h"
@@ -1182,6 +1183,12 @@ static int gmc_v8_0_sw_init(void *handle)
11821183 adev -> vm_manager .vram_base_offset = 0 ;
11831184 }
11841185
1186+ adev -> gmc .vm_fault_info = kmalloc (sizeof (struct kfd_vm_fault_info ),
1187+ GFP_KERNEL );
1188+ if (!adev -> gmc .vm_fault_info )
1189+ return - ENOMEM ;
1190+ atomic_set (& adev -> gmc .vm_fault_info_updated , 0 );
1191+
11851192 return 0 ;
11861193}
11871194
@@ -1191,6 +1198,7 @@ static int gmc_v8_0_sw_fini(void *handle)
11911198
11921199 amdgpu_gem_force_release (adev );
11931200 amdgpu_vm_manager_fini (adev );
1201+ kfree (adev -> gmc .vm_fault_info );
11941202 gmc_v8_0_gart_fini (adev );
11951203 amdgpu_bo_fini (adev );
11961204 release_firmware (adev -> gmc .fw );
@@ -1426,7 +1434,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
14261434 struct amdgpu_irq_src * source ,
14271435 struct amdgpu_iv_entry * entry )
14281436{
1429- u32 addr , status , mc_client ;
1437+ u32 addr , status , mc_client , vmid ;
14301438
14311439 if (amdgpu_sriov_vf (adev )) {
14321440 dev_err (adev -> dev , "GPU fault detected: %d 0x%08x\n" ,
@@ -1463,6 +1471,29 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
14631471 entry -> pasid );
14641472 }
14651473
1474+ vmid = REG_GET_FIELD (status , VM_CONTEXT1_PROTECTION_FAULT_STATUS ,
1475+ VMID );
1476+ if (amdgpu_amdkfd_is_kfd_vmid (adev , vmid )
1477+ && !atomic_read (& adev -> gmc .vm_fault_info_updated )) {
1478+ struct kfd_vm_fault_info * info = adev -> gmc .vm_fault_info ;
1479+ u32 protections = REG_GET_FIELD (status ,
1480+ VM_CONTEXT1_PROTECTION_FAULT_STATUS ,
1481+ PROTECTIONS );
1482+
1483+ info -> vmid = vmid ;
1484+ info -> mc_id = REG_GET_FIELD (status ,
1485+ VM_CONTEXT1_PROTECTION_FAULT_STATUS ,
1486+ MEMORY_CLIENT_ID );
1487+ info -> status = status ;
1488+ info -> page_addr = addr ;
1489+ info -> prot_valid = protections & 0x7 ? true : false;
1490+ info -> prot_read = protections & 0x8 ? true : false;
1491+ info -> prot_write = protections & 0x10 ? true : false;
1492+ info -> prot_exec = protections & 0x20 ? true : false;
1493+ mb ();
1494+ atomic_set (& adev -> gmc .vm_fault_info_updated , 1 );
1495+ }
1496+
14661497 return 0 ;
14671498}
14681499
0 commit comments