Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe/oa: Allow only certain property changes from config

Whereas all properties can be specified during OA stream open, when the OA
stream is reconfigured only the config_id and syncs can be specified.

v2: Use separate function table for reconfig case (Jonathan)
Change bool function args to enum (Matt B)
v3: s/xe_oa_set_property_funcs/xe_oa_set_property_funcs_open/ (Jonathan)

Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Suggested-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241022200352.1192560-8-ashutosh.dixit@intel.com

+46 -14
+46 -14
drivers/gpu/drm/xe/xe_oa.c
··· 47 47 XE_OA_SUBMIT_ADD_DEPS, 48 48 }; 49 49 50 + enum xe_oa_user_extn_from { 51 + XE_OA_USER_EXTN_FROM_OPEN, 52 + XE_OA_USER_EXTN_FROM_CONFIG, 53 + }; 54 + 50 55 struct xe_oa_reg { 51 56 struct xe_reg addr; 52 57 u32 value; ··· 1260 1255 return 0; 1261 1256 } 1262 1257 1258 + static int xe_oa_set_prop_ret_inval(struct xe_oa *oa, u64 value, 1259 + struct xe_oa_open_param *param) 1260 + { 1261 + return -EINVAL; 1262 + } 1263 + 1263 1264 typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value, 1264 1265 struct xe_oa_open_param *param); 1265 - static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = { 1266 + static const xe_oa_set_property_fn xe_oa_set_property_funcs_open[] = { 1266 1267 [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id, 1267 1268 [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa, 1268 1269 [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set, ··· 1282 1271 [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user, 1283 1272 }; 1284 1273 1285 - static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension, 1286 - struct xe_oa_open_param *param) 1274 + static const xe_oa_set_property_fn xe_oa_set_property_funcs_config[] = { 1275 + [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_ret_inval, 1276 + [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_ret_inval, 1277 + [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set, 1278 + [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_ret_inval, 1279 + [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_ret_inval, 1280 + [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_ret_inval, 1281 + [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_ret_inval, 1282 + [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_ret_inval, 1283 + [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_prop_ret_inval, 1284 + [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs, 1285 + [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user, 1286 + }; 1287 + 1288 + static int xe_oa_user_ext_set_property(struct xe_oa *oa, enum xe_oa_user_extn_from from, 1289 + u64 extension, struct xe_oa_open_param *param) 1287 1290 { 1288 1291 u64 __user *address = u64_to_user_ptr(extension); 1289 1292 struct drm_xe_ext_set_property ext; ··· 1308 1283 if (XE_IOCTL_DBG(oa->xe, err)) 1309 1284 return -EFAULT; 1310 1285 1311 - if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs)) || 1286 + BUILD_BUG_ON(ARRAY_SIZE(xe_oa_set_property_funcs_open) != 1287 + ARRAY_SIZE(xe_oa_set_property_funcs_config)); 1288 + 1289 + if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs_open)) || 1312 1290 XE_IOCTL_DBG(oa->xe, ext.pad)) 1313 1291 return -EINVAL; 1314 1292 1315 - idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs)); 1316 - return xe_oa_set_property_funcs[idx](oa, ext.value, param); 1293 + idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs_open)); 1294 + 1295 + if (from == XE_OA_USER_EXTN_FROM_CONFIG) 1296 + return xe_oa_set_property_funcs_config[idx](oa, ext.value, param); 1297 + else 1298 + return xe_oa_set_property_funcs_open[idx](oa, ext.value, param); 1317 1299 } 1318 1300 1319 - typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, u64 extension, 1320 - struct xe_oa_open_param *param); 1301 + typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, enum xe_oa_user_extn_from from, 1302 + u64 extension, struct xe_oa_open_param *param); 1321 1303 static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = { 1322 1304 [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property, 1323 1305 }; 1324 1306 1325 1307 #define MAX_USER_EXTENSIONS 16 1326 - static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number, 1327 - struct xe_oa_open_param *param) 1308 + static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from from, u64 extension, 1309 + int ext_number, struct xe_oa_open_param *param) 1328 1310 { 1329 1311 u64 __user *address = u64_to_user_ptr(extension); 1330 1312 struct drm_xe_user_extension ext; ··· 1350 1318 return -EINVAL; 1351 1319 1352 1320 idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs)); 1353 - err = xe_oa_user_extension_funcs[idx](oa, extension, param); 1321 + err = xe_oa_user_extension_funcs[idx](oa, from, extension, param); 1354 1322 if (XE_IOCTL_DBG(oa->xe, err)) 1355 1323 return err; 1356 1324 1357 1325 if (ext.next_extension) 1358 - return xe_oa_user_extensions(oa, ext.next_extension, ++ext_number, param); 1326 + return xe_oa_user_extensions(oa, from, ext.next_extension, ++ext_number, param); 1359 1327 1360 1328 return 0; 1361 1329 } ··· 1501 1469 struct xe_oa_config *config; 1502 1470 int err; 1503 1471 1504 - err = xe_oa_user_extensions(stream->oa, arg, 0, &param); 1472 + err = xe_oa_user_extensions(stream->oa, XE_OA_USER_EXTN_FROM_CONFIG, arg, 0, &param); 1505 1473 if (err) 1506 1474 return err; 1507 1475 ··· 2055 2023 } 2056 2024 2057 2025 param.xef = xef; 2058 - ret = xe_oa_user_extensions(oa, data, 0, &param); 2026 + ret = xe_oa_user_extensions(oa, XE_OA_USER_EXTN_FROM_OPEN, data, 0, &param); 2059 2027 if (ret) 2060 2028 return ret; 2061 2029