Skip to content

Commit e1735f3

Browse files
authored
Merge pull request #2420 from yingcong-wu/yc-PR/1204-error-on-unsupported-feature
[DevAsan] Report error when using unsupported extension API
2 parents 2c2b222 + b063563 commit e1735f3

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)