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