diff --git a/docs/changes.txt b/docs/changes.txt index 35651c18c..fc66d5b9d 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -50,6 +50,7 @@ - Backend Info: Added local memory size to output - Backend: with kernel build options, switch from -I to -D INCLUDE_PATH, in order to support Apple Metal runtime - CUDA Backend: moved functions to ext_cuda.c/ext_nvrtc.c and includes to ext_cuda.h/ext_nvrtc.h +- Hardware Monitor: Add support for GPU device utilization readings using iokit on Apple Silicon (OpenCL and Metal) - Hash Info: show more information (Updated Hash-Format. Added Autodetect, Self-Test, Potfile and Plaintext encoding) - HIP Backend: moved functions to ext_hip.c/ext_hiprtc.c and includes to ext_hip.h/ext_hiprtc.h - Kernels: Refactored standard kernel declaration to use a structure holding u32/u64 attributes to reduce the number of attributes diff --git a/include/ext_iokit.h b/include/ext_iokit.h index 089c30240..b45327924 100644 --- a/include/ext_iokit.h +++ b/include/ext_iokit.h @@ -111,7 +111,7 @@ typedef struct hm_iokit_lib typedef hm_iokit_lib_t IOKIT_PTR; #if defined(__APPLE__) -UInt32 hm_IOKIT_strtoul (char *str, int size, int base); +UInt32 hm_IOKIT_strtoul (const char *str, int size, int base); void hm_IOKIT_ultostr (char *str, UInt32 val); kern_return_t hm_IOKIT_SMCOpen (void *hashcat_ctx, io_connect_t *conn); kern_return_t hm_IOKIT_SMCClose (io_connect_t conn); @@ -121,6 +121,7 @@ int hm_IOKIT_SMCGetSensorGraphicHot (void *hashcat_ctx); int hm_IOKIT_SMCGetTemperature (void *hashcat_ctx, char *key, double *temp); bool hm_IOKIT_SMCGetFanRPM (char *key, io_connect_t conn, float *ret); int hm_IOKIT_get_fan_speed_current (void *hashcat_ctx, char *fan_speed_buf); +int hm_IOKIT_get_utilization_current (void *hashcat_ctx, int *utilization); bool iokit_init (void *hashcat_ctx); bool iokit_close (void *hashcat_ctx); #endif // __APPLE__ diff --git a/src/backend.c b/src/backend.c index 269e11a03..186dd9dfb 100644 --- a/src/backend.c +++ b/src/backend.c @@ -6746,10 +6746,7 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) #if defined (__APPLE__) if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) { - if (device_param->skipped == false) - { - need_iokit = true; - } + need_iokit = true; } #endif @@ -6777,6 +6774,16 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) need_nvapi = true; #endif } + + #if defined (__APPLE__) + if (strncmp (device_param->device_name, "Apple M", 7) == 0) + { + if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) + { + need_iokit = true; + } + } + #endif } if (device_param->opencl_device_type & CL_DEVICE_TYPE_CPU) diff --git a/src/ext_iokit.c b/src/ext_iokit.c index 1b1ef35ca..e638ba7c7 100644 --- a/src/ext_iokit.c +++ b/src/ext_iokit.c @@ -13,7 +13,7 @@ #if defined (__APPLE__) #include -UInt32 hm_IOKIT_strtoul (char *str, int size, int base) +UInt32 hm_IOKIT_strtoul (const char *str, int size, int base) { int i; @@ -223,6 +223,66 @@ bool hm_IOKIT_SMCGetFanRPM (char *key, io_connect_t conn, float *ret) return false; } +int hm_IOKIT_get_utilization_current (void *hashcat_ctx, int *utilization) +{ + bool rc = false; + + io_iterator_t iterator; + + CFMutableDictionaryRef matching = IOServiceMatching ("IOAccelerator"); + + if (IOServiceGetMatchingServices (kIOMasterPortDefault, matching, &iterator) != kIOReturnSuccess) + { + event_log_error (hashcat_ctx, "IOServiceGetMatchingServices(): failure"); + + return rc; + } + + io_registry_entry_t regEntry; + + while ((regEntry = IOIteratorNext (iterator))) + { + // Put this services object into a dictionary object. + CFMutableDictionaryRef serviceDictionary; + + if (IORegistryEntryCreateCFProperties (regEntry, &serviceDictionary, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) + { + // Service dictionary creation failed. + IOObjectRelease (regEntry); + + continue; + } + + CFMutableDictionaryRef perf_properties = (CFMutableDictionaryRef) CFDictionaryGetValue (serviceDictionary, CFSTR ("PerformanceStatistics")); + + if (perf_properties) + { + static ssize_t gpuCoreUtil = 0; + + const void *gpuCoreUtilization = CFDictionaryGetValue (perf_properties, CFSTR ("Device Utilization %")); + + if (gpuCoreUtilization != NULL) + { + CFNumberGetValue (gpuCoreUtilization, kCFNumberSInt64Type, &gpuCoreUtil); + + *utilization = gpuCoreUtil; + + rc = true; + } + } + + CFRelease (serviceDictionary); + + IOObjectRelease (regEntry); + + if (rc == true) break; + } + + IOObjectRelease (iterator); + + return rc; +} + int hm_IOKIT_get_fan_speed_current (void *hashcat_ctx, char *fan_speed_buf) { hwmon_ctx_t *hwmon_ctx = ((hashcat_ctx_t *) hashcat_ctx)->hwmon_ctx; diff --git a/src/hwmon.c b/src/hwmon.c index f08746d45..9879ab3ac 100644 --- a/src/hwmon.c +++ b/src/hwmon.c @@ -764,6 +764,31 @@ int hm_get_utilization_with_devices_idx (hashcat_ctx_t *hashcat_ctx, const int b } } + #if defined(__APPLE__) + if (backend_ctx->devices_param[backend_device_idx].is_metal == true || backend_ctx->devices_param[backend_device_idx].is_opencl == true) + { + if (backend_ctx->devices_param[backend_device_idx].opencl_platform_vendor_id == VENDOR_ID_APPLE) + { + if (backend_ctx->devices_param[backend_device_idx].opencl_device_type & CL_DEVICE_TYPE_GPU) + { + if (hwmon_ctx->hm_iokit) + { + int utilization = 0; + + if (hm_IOKIT_get_utilization_current (hashcat_ctx, &utilization) == -1) + { + hwmon_ctx->hm_device[backend_device_idx].utilization_get_supported = false; + + return -1; + } + + return utilization; + } + } + } + } + #endif + if ((backend_ctx->devices_param[backend_device_idx].is_opencl == true) || (backend_ctx->devices_param[backend_device_idx].is_hip == true)) { if (backend_ctx->devices_param[backend_device_idx].opencl_device_type & CL_DEVICE_TYPE_GPU) @@ -1565,6 +1590,24 @@ int hwmon_ctx_init (hashcat_ctx_t *hashcat_ctx) // nothing to do } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + const u32 device_id = device_param->device_id; + + if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (hwmon_ctx->hm_iokit)) + { + hm_adapters_iokit[device_id].buslanes_get_supported = false; + hm_adapters_iokit[device_id].corespeed_get_supported = false; + hm_adapters_iokit[device_id].fanspeed_get_supported = true; + hm_adapters_iokit[device_id].fanpolicy_get_supported = false; + hm_adapters_iokit[device_id].memoryspeed_get_supported = false; + hm_adapters_iokit[device_id].temperature_get_supported = true; + hm_adapters_iokit[device_id].utilization_get_supported = true; + } + } + #endif + if ((device_param->is_opencl == true) || (device_param->is_hip == true)) { const u32 device_id = device_param->device_id; @@ -1577,7 +1620,7 @@ int hwmon_ctx_init (hashcat_ctx_t *hashcat_ctx) hm_adapters_iokit[device_id].fanpolicy_get_supported = false; hm_adapters_iokit[device_id].memoryspeed_get_supported = false; hm_adapters_iokit[device_id].temperature_get_supported = true; - hm_adapters_iokit[device_id].utilization_get_supported = false; + hm_adapters_iokit[device_id].utilization_get_supported = true; } if ((device_param->opencl_device_type & CL_DEVICE_TYPE_GPU) == 0) continue; @@ -1647,7 +1690,6 @@ int hwmon_ctx_init (hashcat_ctx_t *hashcat_ctx) } #endif - if (hwmon_ctx->hm_adl == NULL && hwmon_ctx->hm_nvml == NULL && hwmon_ctx->hm_sysfs_amdgpu == NULL && hwmon_ctx->hm_sysfs_cpu == NULL && hwmon_ctx->hm_iokit == NULL) { FREE_ADAPTERS; @@ -1715,6 +1757,24 @@ int hwmon_ctx_init (hashcat_ctx_t *hashcat_ctx) } } + if (device_param->is_metal == true) + { + if (hwmon_ctx->hm_iokit) + { + hwmon_ctx->hm_device[backend_devices_idx].iokit = hm_adapters_iokit[device_id].iokit; + hwmon_ctx->hm_device[backend_devices_idx].buslanes_get_supported |= hm_adapters_iokit[device_id].buslanes_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].corespeed_get_supported |= hm_adapters_iokit[device_id].corespeed_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].fanspeed_get_supported |= hm_adapters_iokit[device_id].fanspeed_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].fanpolicy_get_supported |= hm_adapters_iokit[device_id].fanpolicy_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].memoryspeed_get_supported |= hm_adapters_iokit[device_id].memoryspeed_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].temperature_get_supported |= hm_adapters_iokit[device_id].temperature_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].threshold_shutdown_get_supported |= hm_adapters_iokit[device_id].threshold_shutdown_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].threshold_slowdown_get_supported |= hm_adapters_iokit[device_id].threshold_slowdown_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].throttle_get_supported |= hm_adapters_iokit[device_id].throttle_get_supported; + hwmon_ctx->hm_device[backend_devices_idx].utilization_get_supported |= hm_adapters_iokit[device_id].utilization_get_supported; + } + } + if ((device_param->is_opencl == true) || (device_param->is_hip == true)) { if (device_param->opencl_device_type & CL_DEVICE_TYPE_CPU)