Skip to content

Commit b063563

Browse files
yingcong-wukbenzie
authored andcommitted
[DevAsan] Report error when using unsupported extension API
Some extensions are not currently supported by device address sanitizer. We may add support for those later, but for now, we will report errors when using unsupported API to let users know instead of failing for other random errors and puzzling the users.
1 parent 2c2b222 commit b063563

File tree

2 files changed

+286
-0
lines changed

2 files changed

+286
-0
lines changed

source/loader/layers/sanitizer/asan/asan_ddi.cpp

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,52 @@ __urdlllocal ur_result_t UR_APICALL urKernelSetArgPointer(
15541554
return result;
15551555
}
15561556

1557+
///////////////////////////////////////////////////////////////////////////////
1558+
/// @brief Intercept function for urDeviceGetInfo
1559+
__urdlllocal ur_result_t UR_APICALL urDeviceGetInfo(
1560+
ur_device_handle_t hDevice, ///< [in] handle of the device instance
1561+
ur_device_info_t propName, ///< [in] type of the info to retrieve
1562+
size_t propSize, ///< [in] the number of bytes pointed to by pPropValue.
1563+
void *
1564+
pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding
1565+
///< the info.
1566+
///< If propSize is not equal to or greater than the real number of bytes
1567+
///< needed to return the info
1568+
///< then the ::UR_RESULT_ERROR_INVALID_SIZE error is returned and
1569+
///< pPropValue is not used.
1570+
size_t *
1571+
pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName.
1572+
) {
1573+
auto pfnGetInfo = getContext()->urDdiTable.Device.pfnGetInfo;
1574+
1575+
if (nullptr == pfnGetInfo) {
1576+
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
1577+
}
1578+
1579+
// For unsupported features for device address sanitizer, we override the result.
1580+
static std::unordered_set<ur_device_info_t> UnsupportedFeatures = {
1581+
// Virtual Memory
1582+
UR_DEVICE_INFO_VIRTUAL_MEMORY_SUPPORT,
1583+
1584+
// Command Buffer
1585+
UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP,
1586+
UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP,
1587+
};
1588+
if (UnsupportedFeatures.find(propName) != UnsupportedFeatures.end()) {
1589+
UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet);
1590+
1591+
// handle non-bool return type queries
1592+
if (propName == UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP) {
1593+
ur_device_command_buffer_update_capability_flags_t flag = 0;
1594+
return ReturnValue(flag);
1595+
}
1596+
1597+
return ReturnValue(false);
1598+
}
1599+
1600+
return pfnGetInfo(hDevice, propName, propSize, pPropValue, pPropSizeRet);
1601+
}
1602+
15571603
///////////////////////////////////////////////////////////////////////////////
15581604
/// @brief Exported function for filling application's Global table
15591605
/// with current process' addresses
@@ -1843,6 +1889,168 @@ __urdlllocal ur_result_t UR_APICALL urGetUSMProcAddrTable(
18431889
return result;
18441890
}
18451891

1892+
///////////////////////////////////////////////////////////////////////////////
1893+
/// @brief Exported function for filling application's Device table
1894+
/// with current process' addresses
1895+
///
1896+
/// @returns
1897+
/// - ::UR_RESULT_SUCCESS
1898+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
1899+
/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
1900+
__urdlllocal ur_result_t UR_APICALL urGetDeviceProcAddrTable(
1901+
ur_api_version_t version, ///< [in] API version requested
1902+
ur_device_dditable_t
1903+
*pDdiTable ///< [in,out] pointer to table of DDI function pointers
1904+
) {
1905+
if (nullptr == pDdiTable) {
1906+
return UR_RESULT_ERROR_INVALID_NULL_POINTER;
1907+
}
1908+
1909+
if (UR_MAJOR_VERSION(ur_sanitizer_layer::getContext()->version) !=
1910+
UR_MAJOR_VERSION(version) ||
1911+
UR_MINOR_VERSION(ur_sanitizer_layer::getContext()->version) >
1912+
UR_MINOR_VERSION(version)) {
1913+
return UR_RESULT_ERROR_UNSUPPORTED_VERSION;
1914+
}
1915+
1916+
ur_result_t result = UR_RESULT_SUCCESS;
1917+
1918+
pDdiTable->pfnGetInfo = ur_sanitizer_layer::asan::urDeviceGetInfo;
1919+
1920+
return result;
1921+
}
1922+
1923+
template <class A, class B> struct NotSupportedApi;
1924+
1925+
template <class MsgType, class R, class... A>
1926+
struct NotSupportedApi<MsgType, R (*)(A...)> {
1927+
R static ReportError(A...) {
1928+
getContext()->logger.error(MsgType::value);
1929+
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
1930+
}
1931+
};
1932+
1933+
struct DevAsanNotSupportCommandBufferMsg {
1934+
static constexpr const char *value =
1935+
"CommandBuffer extension is not supported by UR_LAYER_ASAN";
1936+
};
1937+
1938+
struct DevAsanNotSupportVirtualMemoryMsg {
1939+
static constexpr const char *value =
1940+
"VirtualMemory extension is not supported by UR_LAYER_ASAN";
1941+
};
1942+
1943+
template <class T>
1944+
using CommandBufferNotSupported =
1945+
NotSupportedApi<DevAsanNotSupportCommandBufferMsg, T>;
1946+
1947+
template <class T>
1948+
using VirtualMemoryNotSupported =
1949+
NotSupportedApi<DevAsanNotSupportVirtualMemoryMsg, T>;
1950+
1951+
///////////////////////////////////////////////////////////////////////////////
1952+
/// @brief Exported function for filling application's CommandBufferExp table
1953+
/// with current process' addresses
1954+
///
1955+
/// @returns
1956+
/// - ::UR_RESULT_SUCCESS
1957+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
1958+
/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
1959+
__urdlllocal ur_result_t UR_APICALL urGetCommandBufferExpProcAddrTable(
1960+
ur_api_version_t version, ///< [in] API version requested
1961+
ur_command_buffer_exp_dditable_t
1962+
*pDdiTable ///< [in,out] pointer to table of DDI function pointers
1963+
) {
1964+
if (nullptr == pDdiTable) {
1965+
return UR_RESULT_ERROR_INVALID_NULL_POINTER;
1966+
}
1967+
1968+
if (UR_MAJOR_VERSION(ur_sanitizer_layer::getContext()->version) !=
1969+
UR_MAJOR_VERSION(version) ||
1970+
UR_MINOR_VERSION(ur_sanitizer_layer::getContext()->version) >
1971+
UR_MINOR_VERSION(version)) {
1972+
return UR_RESULT_ERROR_UNSUPPORTED_VERSION;
1973+
}
1974+
1975+
ur_result_t result = UR_RESULT_SUCCESS;
1976+
1977+
#define SET_UNSUPPORTED(FuncPtr) \
1978+
do { \
1979+
FuncPtr = CommandBufferNotSupported<decltype(FuncPtr)>::ReportError; \
1980+
} while (0)
1981+
1982+
SET_UNSUPPORTED(pDdiTable->pfnCreateExp);
1983+
SET_UNSUPPORTED(pDdiTable->pfnRetainExp);
1984+
SET_UNSUPPORTED(pDdiTable->pfnReleaseExp);
1985+
SET_UNSUPPORTED(pDdiTable->pfnFinalizeExp);
1986+
SET_UNSUPPORTED(pDdiTable->pfnAppendKernelLaunchExp);
1987+
SET_UNSUPPORTED(pDdiTable->pfnAppendUSMFillExp);
1988+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferCopyExp);
1989+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferWriteExp);
1990+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferReadExp);
1991+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferCopyRectExp);
1992+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferWriteRectExp);
1993+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferReadRectExp);
1994+
SET_UNSUPPORTED(pDdiTable->pfnAppendMemBufferFillExp);
1995+
SET_UNSUPPORTED(pDdiTable->pfnAppendUSMPrefetchExp);
1996+
SET_UNSUPPORTED(pDdiTable->pfnAppendUSMAdviseExp);
1997+
SET_UNSUPPORTED(pDdiTable->pfnEnqueueExp);
1998+
SET_UNSUPPORTED(pDdiTable->pfnRetainCommandExp);
1999+
SET_UNSUPPORTED(pDdiTable->pfnReleaseCommandExp);
2000+
SET_UNSUPPORTED(pDdiTable->pfnUpdateKernelLaunchExp);
2001+
SET_UNSUPPORTED(pDdiTable->pfnUpdateSignalEventExp);
2002+
SET_UNSUPPORTED(pDdiTable->pfnUpdateWaitEventsExp);
2003+
SET_UNSUPPORTED(pDdiTable->pfnGetInfoExp);
2004+
SET_UNSUPPORTED(pDdiTable->pfnCommandGetInfoExp);
2005+
2006+
#undef SET_UNSUPPORTED
2007+
2008+
return result;
2009+
}
2010+
2011+
///////////////////////////////////////////////////////////////////////////////
2012+
/// @brief Exported function for filling application's VirtualMem table
2013+
/// with current process' addresses
2014+
///
2015+
/// @returns
2016+
/// - ::UR_RESULT_SUCCESS
2017+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
2018+
/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
2019+
__urdlllocal ur_result_t UR_APICALL urGetVirtualMemProcAddrTable(
2020+
ur_api_version_t version, ///< [in] API version requested
2021+
ur_virtual_mem_dditable_t
2022+
*pDdiTable ///< [in,out] pointer to table of DDI function pointers
2023+
) {
2024+
if (nullptr == pDdiTable) {
2025+
return UR_RESULT_ERROR_INVALID_NULL_POINTER;
2026+
}
2027+
2028+
if (UR_MAJOR_VERSION(ur_sanitizer_layer::getContext()->version) !=
2029+
UR_MAJOR_VERSION(version) ||
2030+
UR_MINOR_VERSION(ur_sanitizer_layer::getContext()->version) >
2031+
UR_MINOR_VERSION(version)) {
2032+
return UR_RESULT_ERROR_UNSUPPORTED_VERSION;
2033+
}
2034+
2035+
ur_result_t result = UR_RESULT_SUCCESS;
2036+
2037+
#define SET_UNSUPPORTED(FuncPtr) \
2038+
do { \
2039+
FuncPtr = VirtualMemoryNotSupported<decltype(FuncPtr)>::ReportError; \
2040+
} while (0)
2041+
2042+
SET_UNSUPPORTED(pDdiTable->pfnGranularityGetInfo);
2043+
SET_UNSUPPORTED(pDdiTable->pfnReserve);
2044+
SET_UNSUPPORTED(pDdiTable->pfnFree);
2045+
SET_UNSUPPORTED(pDdiTable->pfnMap);
2046+
SET_UNSUPPORTED(pDdiTable->pfnUnmap);
2047+
SET_UNSUPPORTED(pDdiTable->pfnSetAccess);
2048+
SET_UNSUPPORTED(pDdiTable->pfnGetInfo);
2049+
2050+
#undef SET_UNSUPPORTED
2051+
2052+
return result;
2053+
}
18462054
} // namespace asan
18472055

18482056
ur_result_t context_t::init(ur_dditable_t *dditable,
@@ -1911,6 +2119,21 @@ ur_result_t context_t::init(ur_dditable_t *dditable,
19112119
UR_API_VERSION_CURRENT, &dditable->USM);
19122120
}
19132121

2122+
if (UR_RESULT_SUCCESS == result) {
2123+
result = ur_sanitizer_layer::asan::urGetDeviceProcAddrTable(
2124+
UR_API_VERSION_CURRENT, &dditable->Device);
2125+
}
2126+
2127+
if (UR_RESULT_SUCCESS == result) {
2128+
result = ur_sanitizer_layer::asan::urGetCommandBufferExpProcAddrTable(
2129+
UR_API_VERSION_CURRENT, &dditable->CommandBufferExp);
2130+
}
2131+
2132+
if (UR_RESULT_SUCCESS == result) {
2133+
result = ur_sanitizer_layer::asan::urGetVirtualMemProcAddrTable(
2134+
UR_API_VERSION_CURRENT, &dditable->VirtualMem);
2135+
}
2136+
19142137
return result;
19152138
}
19162139

test/layers/sanitizer/asan.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,66 @@ TEST(DeviceAsan, Initialization) {
5656
status = urLoaderConfigRelease(loaderConfig);
5757
ASSERT_EQ(status, UR_RESULT_SUCCESS);
5858
}
59+
60+
TEST(DeviceAsan, UnsupportedFeature) {
61+
ur_result_t status;
62+
63+
ur_loader_config_handle_t loaderConfig;
64+
status = urLoaderConfigCreate(&loaderConfig);
65+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
66+
status = urLoaderConfigEnableLayer(loaderConfig, "UR_LAYER_ASAN");
67+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
68+
69+
status = urLoaderInit(0, loaderConfig);
70+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
71+
72+
ur_adapter_handle_t adapter;
73+
status = urAdapterGet(1, &adapter, nullptr);
74+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
75+
76+
ur_platform_handle_t platform;
77+
status = urPlatformGet(&adapter, 1, 1, &platform, nullptr);
78+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
79+
80+
ur_device_handle_t device;
81+
status = urDeviceGet(platform, UR_DEVICE_TYPE_DEFAULT, 1, &device, nullptr);
82+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
83+
84+
ur_context_handle_t context;
85+
status = urContextCreate(1, &device, nullptr, &context);
86+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
87+
88+
// Check for explict unsupported features
89+
ur_bool_t isSupported;
90+
status = urDeviceGetInfo(device, UR_DEVICE_INFO_VIRTUAL_MEMORY_SUPPORT,
91+
sizeof(isSupported), &isSupported, nullptr);
92+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
93+
ASSERT_EQ(isSupported, 0);
94+
95+
status = urDeviceGetInfo(device, UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP,
96+
sizeof(isSupported), &isSupported, nullptr);
97+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
98+
ASSERT_EQ(isSupported, 0);
99+
100+
ur_device_command_buffer_update_capability_flags_t update_flag;
101+
status = urDeviceGetInfo(
102+
device, UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP,
103+
sizeof(update_flag), &update_flag, nullptr);
104+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
105+
ASSERT_EQ(update_flag, 0);
106+
107+
status = urContextRelease(context);
108+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
109+
110+
status = urDeviceRelease(device);
111+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
112+
113+
status = urAdapterRelease(adapter);
114+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
115+
116+
status = urLoaderTearDown();
117+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
118+
119+
status = urLoaderConfigRelease(loaderConfig);
120+
ASSERT_EQ(status, UR_RESULT_SUCCESS);
121+
}

0 commit comments

Comments
 (0)