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[0]; 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 char *stp_policy_node_name(struct stp_policy_node *policy_node) 61 { 62 return policy_node->group.cg_item.ci_name ? : "<none>"; 63 } 64 65 static 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 72 static inline struct stp_policy_node * 73 to_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 81 void *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 } 87 EXPORT_SYMBOL_GPL(to_pdrv_policy_node); 88 89 static ssize_t 90 stp_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 101 static ssize_t 102 stp_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 130 unlock: 131 mutex_unlock(&stp_policy_subsys.su_mutex); 132 133 return ret; 134 } 135 136 static ssize_t 137 stp_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 148 static ssize_t 149 stp_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 176 unlock: 177 mutex_unlock(&stp_policy_subsys.su_mutex); 178 179 return ret; 180 } 181 182 static 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 189 static struct configfs_item_operations stp_policy_node_item_ops = { 190 .release = stp_policy_node_release, 191 }; 192 193 CONFIGFS_ATTR(stp_policy_node_, masters); 194 CONFIGFS_ATTR(stp_policy_node_, channels); 195 196 static struct configfs_attribute *stp_policy_node_attrs[] = { 197 &stp_policy_node_attr_masters, 198 &stp_policy_node_attr_channels, 199 NULL, 200 }; 201 202 static const struct config_item_type stp_policy_type; 203 static const struct config_item_type stp_policy_node_type; 204 205 const struct config_item_type * 206 get_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 227 static struct config_group * 228 stp_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 272 static void 273 stp_policy_node_drop(struct config_group *group, struct config_item *item) 274 { 275 config_item_put(item); 276 } 277 278 static 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 283 static 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 */ 293 static 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 307 CONFIGFS_ATTR_RO(stp_policy_, device); 308 309 static 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 323 CONFIGFS_ATTR_RO(stp_policy_, protocol); 324 325 static struct configfs_attribute *stp_policy_attrs[] = { 326 &stp_policy_attr_device, 327 &stp_policy_attr_protocol, 328 NULL, 329 }; 330 331 void 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 356 static 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 372 static struct configfs_item_operations stp_policy_item_ops = { 373 .release = stp_policy_release, 374 }; 375 376 static struct configfs_group_operations stp_policy_group_ops = { 377 .make_group = stp_policy_node_make, 378 }; 379 380 static 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 387 static struct config_group * 388 stp_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 459 unlock_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 474 static struct configfs_group_operations stp_policy_root_group_ops = { 475 .make_group = stp_policy_make, 476 }; 477 478 static 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 483 static 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 */ 495 static 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 506 next: 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 532 out: 533 return ret; 534 } 535 536 537 struct stp_policy_node * 538 stp_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 557 void 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 565 int __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 572 void __exit stp_configfs_exit(void) 573 { 574 configfs_unregister_subsystem(&stp_policy_subsys); 575 } 576