cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

iommu-sysfs.c (3153B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * IOMMU sysfs class support
      4 *
      5 * Copyright (C) 2014 Red Hat, Inc.  All rights reserved.
      6 *     Author: Alex Williamson <alex.williamson@redhat.com>
      7 */
      8
      9#include <linux/device.h>
     10#include <linux/iommu.h>
     11#include <linux/init.h>
     12#include <linux/slab.h>
     13
     14/*
     15 * We provide a common class "devices" group which initially has no attributes.
     16 * As devices are added to the IOMMU, we'll add links to the group.
     17 */
     18static struct attribute *devices_attr[] = {
     19	NULL,
     20};
     21
     22static const struct attribute_group devices_attr_group = {
     23	.name = "devices",
     24	.attrs = devices_attr,
     25};
     26
     27static const struct attribute_group *dev_groups[] = {
     28	&devices_attr_group,
     29	NULL,
     30};
     31
     32static void release_device(struct device *dev)
     33{
     34	kfree(dev);
     35}
     36
     37static struct class iommu_class = {
     38	.name = "iommu",
     39	.dev_release = release_device,
     40	.dev_groups = dev_groups,
     41};
     42
     43static int __init iommu_dev_init(void)
     44{
     45	return class_register(&iommu_class);
     46}
     47postcore_initcall(iommu_dev_init);
     48
     49/*
     50 * Init the struct device for the IOMMU. IOMMU specific attributes can
     51 * be provided as an attribute group, allowing a unique namespace per
     52 * IOMMU type.
     53 */
     54int iommu_device_sysfs_add(struct iommu_device *iommu,
     55			   struct device *parent,
     56			   const struct attribute_group **groups,
     57			   const char *fmt, ...)
     58{
     59	va_list vargs;
     60	int ret;
     61
     62	iommu->dev = kzalloc(sizeof(*iommu->dev), GFP_KERNEL);
     63	if (!iommu->dev)
     64		return -ENOMEM;
     65
     66	device_initialize(iommu->dev);
     67
     68	iommu->dev->class = &iommu_class;
     69	iommu->dev->parent = parent;
     70	iommu->dev->groups = groups;
     71
     72	va_start(vargs, fmt);
     73	ret = kobject_set_name_vargs(&iommu->dev->kobj, fmt, vargs);
     74	va_end(vargs);
     75	if (ret)
     76		goto error;
     77
     78	ret = device_add(iommu->dev);
     79	if (ret)
     80		goto error;
     81
     82	dev_set_drvdata(iommu->dev, iommu);
     83
     84	return 0;
     85
     86error:
     87	put_device(iommu->dev);
     88	return ret;
     89}
     90EXPORT_SYMBOL_GPL(iommu_device_sysfs_add);
     91
     92void iommu_device_sysfs_remove(struct iommu_device *iommu)
     93{
     94	dev_set_drvdata(iommu->dev, NULL);
     95	device_unregister(iommu->dev);
     96	iommu->dev = NULL;
     97}
     98EXPORT_SYMBOL_GPL(iommu_device_sysfs_remove);
     99
    100/*
    101 * IOMMU drivers can indicate a device is managed by a given IOMMU using
    102 * this interface.  A link to the device will be created in the "devices"
    103 * directory of the IOMMU device in sysfs and an "iommu" link will be
    104 * created under the linked device, pointing back at the IOMMU device.
    105 */
    106int iommu_device_link(struct iommu_device *iommu, struct device *link)
    107{
    108	int ret;
    109
    110	if (!iommu || IS_ERR(iommu))
    111		return -ENODEV;
    112
    113	ret = sysfs_add_link_to_group(&iommu->dev->kobj, "devices",
    114				      &link->kobj, dev_name(link));
    115	if (ret)
    116		return ret;
    117
    118	ret = sysfs_create_link_nowarn(&link->kobj, &iommu->dev->kobj, "iommu");
    119	if (ret)
    120		sysfs_remove_link_from_group(&iommu->dev->kobj, "devices",
    121					     dev_name(link));
    122
    123	return ret;
    124}
    125EXPORT_SYMBOL_GPL(iommu_device_link);
    126
    127void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
    128{
    129	if (!iommu || IS_ERR(iommu))
    130		return;
    131
    132	sysfs_remove_link(&link->kobj, "iommu");
    133	sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link));
    134}
    135EXPORT_SYMBOL_GPL(iommu_device_unlink);