1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * System Trace Module (STM) master/channel allocation policy management 4 * Copyright (c) 2014, Intel Corporation. 5 * 6 * A master/channel allocation policy allows mapping string identifiers to 7 * master and channel ranges, where allocation can be done. 8 */ 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <linux/types.h> 13 #include <linux/module.h> 14 #include <linux/device.h> 15 #include <linux/configfs.h> 16 #include <linux/slab.h> 17 #include <linux/stm.h> 18 #include "stm.h" 19 20 /* 21 * STP Master/Channel allocation policy configfs layout. 22 */ 23 24 struct stp_policy { 25 struct config_group group; 26 struct stm_device *stm; 27 }; 28 29 struct stp_policy_node { 30 struct config_group group; 31 struct stp_policy *policy; 32 unsigned int first_master; 33 unsigned int last_master; 34 unsigned int first_channel; 35 unsigned int last_channel; 36 /* this is the one that's exposed to the attributes */ 37 unsigned char priv[]; 38 }; 39 40 void *stp_policy_node_priv(struct stp_policy_node *pn) 41 { 42 if (!pn) 43 return NULL; 44 45 return pn->priv; 46 } 47 48 static struct configfs_subsystem stp_policy_subsys; 49 50 void stp_policy_node_get_ranges(struct stp_policy_node *policy_node, 51 unsigned int *mstart, unsigned int *mend, 52 unsigned int *cstart, unsigned int *cend) 53 { 54 *mstart = policy_node->first_master; 55 *mend = policy_node->last_master; 56 *cstart = policy_node->first_channel; 57 *cend = policy_node->last_channel; 58 } 59 60 static inline struct stp_policy *to_stp_policy(struct config_item *item) 61 { 62 return item ? 63 container_of(to_config_group(item), struct stp_policy, group) : 64 NULL; 65 } 66 67 static inline struct stp_policy_node * 68 to_stp_policy_node(struct config_item *item) 69 { 70 return item ? 71 container_of(to_config_group(item), struct stp_policy_node, 72 group) : 73 NULL; 74 } 75 76 void *to_pdrv_policy_node(struct config_item *item) 77 { 78 struct stp_policy_node *node = to_stp_policy_node(item); 79 80 return stp_policy_node_priv(node); 81 } 82 EXPORT_SYMBOL_GPL(to_pdrv_policy_node); 83 84 static ssize_t 85 stp_policy_node_masters_show(struct config_item *item, char *page) 86 { 87 struct stp_policy_node *policy_node = to_stp_policy_node(item); 88 ssize_t count; 89 90 count = sprintf(page, "%u %u\n", policy_node->first_master, 91 policy_node->last_master); 92 93 return count; 94 } 95 96 static ssize_t 97 stp_policy_node_masters_store(struct config_item *item, const char *page, 98 size_t count) 99 { 100 struct stp_policy_node *policy_node = to_stp_policy_node(item); 101 unsigned int first, last; 102 struct stm_device *stm; 103 char *p = (char *)page; 104 ssize_t ret = -ENODEV; 105 106 if (sscanf(p, "%u %u", &first, &last) != 2) 107 return -EINVAL; 108 109 mutex_lock(&stp_policy_subsys.su_mutex); 110 stm = policy_node->policy->stm; 111 if (!stm) 112 goto unlock; 113 114 /* must be within [sw_start..sw_end], which is an inclusive range */ 115 if (first > last || first < stm->data->sw_start || 116 last > stm->data->sw_end) { 117 ret = -ERANGE; 118 goto unlock; 119 } 120 121 ret = count; 122 policy_node->first_master = first; 123 policy_node->last_master = last; 124 125 unlock: 126 mutex_unlock(&stp_policy_subsys.su_mutex); 127 128 return ret; 129 } 130 131 static ssize_t 132 stp_policy_node_channels_show(struct config_item *item, char *page) 133 { 134 struct stp_policy_node *policy_node = to_stp_policy_node(item); 135 ssize_t count; 136 137 count = sprintf(page, "%u %u\n", policy_node->first_channel, 138 policy_node->last_channel); 139 140 return count; 141 } 142 143 static ssize_t 144 stp_policy_node_channels_store(struct config_item *item, const char *page, 145 size_t count) 146 { 147 struct stp_policy_node *policy_node = to_stp_policy_node(item); 148 unsigned int first, last; 149 struct stm_device *stm; 150 char *p = (char *)page; 151 ssize_t ret = -ENODEV; 152 153 if (sscanf(p, "%u %u", &first, &last) != 2) 154 return -EINVAL; 155 156 mutex_lock(&stp_policy_subsys.su_mutex); 157 stm = policy_node->policy->stm; 158 if (!stm) 159 goto unlock; 160 161 if (first > INT_MAX || last > INT_MAX || first > last || 162 last >= stm->data->sw_nchannels) { 163 ret = -ERANGE; 164 goto unlock; 165 } 166 167 ret = count; 168 policy_node->first_channel = first; 169 policy_node->last_channel = last; 170 171 unlock: 172 mutex_unlock(&stp_policy_subsys.su_mutex); 173 174 return ret; 175 } 176 177 static void stp_policy_node_release(struct config_item *item) 178 { 179 struct stp_policy_node *node = to_stp_policy_node(item); 180 181 kfree(node); 182 } 183 184 static struct configfs_item_operations stp_policy_node_item_ops = { 185 .release = stp_policy_node_release, 186 }; 187 188 CONFIGFS_ATTR(stp_policy_node_, masters); 189 CONFIGFS_ATTR(stp_policy_node_, channels); 190 191 static struct configfs_attribute *stp_policy_node_attrs[] = { 192 &stp_policy_node_attr_masters, 193 &stp_policy_node_attr_channels, 194 NULL, 195 }; 196 197 static const struct config_item_type stp_policy_type; 198 static const struct config_item_type stp_policy_node_type; 199 200 const struct config_item_type * 201 get_policy_node_type(struct configfs_attribute **attrs) 202 { 203 struct config_item_type *type; 204 struct configfs_attribute **merged; 205 206 type = kmemdup(&stp_policy_node_type, sizeof(stp_policy_node_type), 207 GFP_KERNEL); 208 if (!type) 209 return NULL; 210 211 merged = memcat_p(stp_policy_node_attrs, attrs); 212 if (!merged) { 213 kfree(type); 214 return NULL; 215 } 216 217 type->ct_attrs = merged; 218 219 return type; 220 } 221 222 static struct config_group * 223 stp_policy_node_make(struct config_group *group, const char *name) 224 { 225 const struct config_item_type *type = &stp_policy_node_type; 226 struct stp_policy_node *policy_node, *parent_node; 227 const struct stm_protocol_driver *pdrv; 228 struct stp_policy *policy; 229 230 if (group->cg_item.ci_type == &stp_policy_type) { 231 policy = container_of(group, struct stp_policy, group); 232 } else { 233 parent_node = container_of(group, struct stp_policy_node, 234 group); 235 policy = parent_node->policy; 236 } 237 238 if (!policy->stm) 239 return ERR_PTR(-ENODEV); 240 241 pdrv = policy->stm->pdrv; 242 policy_node = 243 kzalloc(offsetof(struct stp_policy_node, priv[pdrv->priv_sz]), 244 GFP_KERNEL); 245 if (!policy_node) 246 return ERR_PTR(-ENOMEM); 247 248 if (pdrv->policy_node_init) 249 pdrv->policy_node_init((void *)policy_node->priv); 250 251 if (policy->stm->pdrv_node_type) 252 type = policy->stm->pdrv_node_type; 253 254 config_group_init_type_name(&policy_node->group, name, type); 255 256 policy_node->policy = policy; 257 258 /* default values for the attributes */ 259 policy_node->first_master = policy->stm->data->sw_start; 260 policy_node->last_master = policy->stm->data->sw_end; 261 policy_node->first_channel = 0; 262 policy_node->last_channel = policy->stm->data->sw_nchannels - 1; 263 264 return &policy_node->group; 265 } 266 267 static void 268 stp_policy_node_drop(struct config_group *group, struct config_item *item) 269 { 270 config_item_put(item); 271 } 272 273 static struct configfs_group_operations stp_policy_node_group_ops = { 274 .make_group = stp_policy_node_make, 275 .drop_item = stp_policy_node_drop, 276 }; 277 278 static const struct config_item_type stp_policy_node_type = { 279 .ct_item_ops = &stp_policy_node_item_ops, 280 .ct_group_ops = &stp_policy_node_group_ops, 281 .ct_attrs = stp_policy_node_attrs, 282 .ct_owner = THIS_MODULE, 283 }; 284 285 /* 286 * Root group: policies. 287 */ 288 static ssize_t stp_policy_device_show(struct config_item *item, 289 char *page) 290 { 291 struct stp_policy *policy = to_stp_policy(item); 292 ssize_t count; 293 294 count = sprintf(page, "%s\n", 295 (policy && policy->stm) ? 296 policy->stm->data->name : 297 "<none>"); 298 299 return count; 300 } 301 302 CONFIGFS_ATTR_RO(stp_policy_, device); 303 304 static ssize_t stp_policy_protocol_show(struct config_item *item, 305 char *page) 306 { 307 struct stp_policy *policy = to_stp_policy(item); 308 ssize_t count; 309 310 count = sprintf(page, "%s\n", 311 (policy && policy->stm) ? 312 policy->stm->pdrv->name : 313 "<none>"); 314 315 return count; 316 } 317 318 CONFIGFS_ATTR_RO(stp_policy_, protocol); 319 320 static struct configfs_attribute *stp_policy_attrs[] = { 321 &stp_policy_attr_device, 322 &stp_policy_attr_protocol, 323 NULL, 324 }; 325 326 void stp_policy_unbind(struct stp_policy *policy) 327 { 328 struct stm_device *stm = policy->stm; 329 330 /* 331 * stp_policy_release() will not call here if the policy is already 332 * unbound; other users should not either, as no link exists between 333 * this policy and anything else in that case 334 */ 335 if (WARN_ON_ONCE(!policy->stm)) 336 return; 337 338 lockdep_assert_held(&stm->policy_mutex); 339 340 stm->policy = NULL; 341 policy->stm = NULL; 342 343 /* 344 * Drop the reference on the protocol driver and lose the link. 345 */ 346 stm_put_protocol(stm->pdrv); 347 stm->pdrv = NULL; 348 stm_put_device(stm); 349 } 350 351 static void stp_policy_release(struct config_item *item) 352 { 353 struct stp_policy *policy = to_stp_policy(item); 354 struct stm_device *stm = policy->stm; 355 356 /* a policy *can* be unbound and still exist in configfs tree */ 357 if (!stm) 358 return; 359 360 mutex_lock(&stm->policy_mutex); 361 stp_policy_unbind(policy); 362 mutex_unlock(&stm->policy_mutex); 363 364 kfree(policy); 365 } 366 367 static struct configfs_item_operations stp_policy_item_ops = { 368 .release = stp_policy_release, 369 }; 370 371 static struct configfs_group_operations stp_policy_group_ops = { 372 .make_group = stp_policy_node_make, 373 }; 374 375 static const struct config_item_type stp_policy_type = { 376 .ct_item_ops = &stp_policy_item_ops, 377 .ct_group_ops = &stp_policy_group_ops, 378 .ct_attrs = stp_policy_attrs, 379 .ct_owner = THIS_MODULE, 380 }; 381 382 static struct config_group * 383 stp_policy_make(struct config_group *group, const char *name) 384 { 385 const struct config_item_type *pdrv_node_type; 386 const struct stm_protocol_driver *pdrv; 387 char *devname, *proto, *p; 388 struct config_group *ret; 389 struct stm_device *stm; 390 int err; 391 392 devname = kasprintf(GFP_KERNEL, "%s", name); 393 if (!devname) 394 return ERR_PTR(-ENOMEM); 395 396 /* 397 * node must look like <device_name>.<policy_name>, where 398 * <device_name> is the name of an existing stm device; may 399 * contain dots; 400 * <policy_name> is an arbitrary string; may not contain dots 401 * <device_name>:<protocol_name>.<policy_name> 402 */ 403 p = strrchr(devname, '.'); 404 if (!p) { 405 kfree(devname); 406 return ERR_PTR(-EINVAL); 407 } 408 409 *p = '\0'; 410 411 /* 412 * look for ":<protocol_name>": 413 * + no protocol suffix: fall back to whatever is available; 414 * + unknown protocol: fail the whole thing 415 */ 416 proto = strrchr(devname, ':'); 417 if (proto) 418 *proto++ = '\0'; 419 420 stm = stm_find_device(devname); 421 if (!stm) { 422 kfree(devname); 423 return ERR_PTR(-ENODEV); 424 } 425 426 err = stm_lookup_protocol(proto, &pdrv, &pdrv_node_type); 427 kfree(devname); 428 429 if (err) { 430 stm_put_device(stm); 431 return ERR_PTR(-ENODEV); 432 } 433 434 mutex_lock(&stm->policy_mutex); 435 if (stm->policy) { 436 ret = ERR_PTR(-EBUSY); 437 goto unlock_policy; 438 } 439 440 stm->policy = kzalloc(sizeof(*stm->policy), GFP_KERNEL); 441 if (!stm->policy) { 442 ret = ERR_PTR(-ENOMEM); 443 goto unlock_policy; 444 } 445 446 config_group_init_type_name(&stm->policy->group, name, 447 &stp_policy_type); 448 449 stm->pdrv = pdrv; 450 stm->pdrv_node_type = pdrv_node_type; 451 stm->policy->stm = stm; 452 ret = &stm->policy->group; 453 454 unlock_policy: 455 mutex_unlock(&stm->policy_mutex); 456 457 if (IS_ERR(ret)) { 458 /* 459 * pdrv and stm->pdrv at this point can be quite different, 460 * and only one of them needs to be 'put' 461 */ 462 stm_put_protocol(pdrv); 463 stm_put_device(stm); 464 } 465 466 return ret; 467 } 468 469 static struct configfs_group_operations stp_policy_root_group_ops = { 470 .make_group = stp_policy_make, 471 }; 472 473 static const struct config_item_type stp_policy_root_type = { 474 .ct_group_ops = &stp_policy_root_group_ops, 475 .ct_owner = THIS_MODULE, 476 }; 477 478 static struct configfs_subsystem stp_policy_subsys = { 479 .su_group = { 480 .cg_item = { 481 .ci_namebuf = "stp-policy", 482 .ci_type = &stp_policy_root_type, 483 }, 484 }, 485 }; 486 487 /* 488 * Lock the policy mutex from the outside 489 */ 490 static struct stp_policy_node * 491 __stp_policy_node_lookup(struct stp_policy *policy, char *s) 492 { 493 struct stp_policy_node *policy_node, *ret = NULL; 494 struct list_head *head = &policy->group.cg_children; 495 struct config_item *item; 496 char *start, *end = s; 497 498 if (list_empty(head)) 499 return NULL; 500 501 next: 502 for (;;) { 503 start = strsep(&end, "/"); 504 if (!start) 505 break; 506 507 if (!*start) 508 continue; 509 510 list_for_each_entry(item, head, ci_entry) { 511 policy_node = to_stp_policy_node(item); 512 513 if (!strcmp(start, 514 policy_node->group.cg_item.ci_name)) { 515 ret = policy_node; 516 517 if (!end) 518 goto out; 519 520 head = &policy_node->group.cg_children; 521 goto next; 522 } 523 } 524 break; 525 } 526 527 out: 528 return ret; 529 } 530 531 532 struct stp_policy_node * 533 stp_policy_node_lookup(struct stm_device *stm, char *s) 534 { 535 struct stp_policy_node *policy_node = NULL; 536 537 mutex_lock(&stp_policy_subsys.su_mutex); 538 539 mutex_lock(&stm->policy_mutex); 540 if (stm->policy) 541 policy_node = __stp_policy_node_lookup(stm->policy, s); 542 mutex_unlock(&stm->policy_mutex); 543 544 if (policy_node) 545 config_item_get(&policy_node->group.cg_item); 546 else 547 mutex_unlock(&stp_policy_subsys.su_mutex); 548 549 return policy_node; 550 } 551 552 void stp_policy_node_put(struct stp_policy_node *policy_node) 553 { 554 lockdep_assert_held(&stp_policy_subsys.su_mutex); 555 556 mutex_unlock(&stp_policy_subsys.su_mutex); 557 config_item_put(&policy_node->group.cg_item); 558 } 559 560 int __init stp_configfs_init(void) 561 { 562 config_group_init(&stp_policy_subsys.su_group); 563 mutex_init(&stp_policy_subsys.su_mutex); 564 return configfs_register_subsystem(&stp_policy_subsys); 565 } 566 567 void __exit stp_configfs_exit(void) 568 { 569 configfs_unregister_subsystem(&stp_policy_subsys); 570 } 571