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

sysfs.c (4753B)


      1// SPDX-License-Identifier: GPL-2.0+
      2// Copyright 2017 IBM Corp.
      3#include <linux/sysfs.h>
      4#include "ocxl_internal.h"
      5
      6static inline struct ocxl_afu *to_afu(struct device *device)
      7{
      8	struct ocxl_file_info *info = container_of(device, struct ocxl_file_info, dev);
      9
     10	return info->afu;
     11}
     12
     13static ssize_t global_mmio_size_show(struct device *device,
     14				struct device_attribute *attr,
     15				char *buf)
     16{
     17	struct ocxl_afu *afu = to_afu(device);
     18
     19	return scnprintf(buf, PAGE_SIZE, "%d\n",
     20			afu->config.global_mmio_size);
     21}
     22
     23static ssize_t pp_mmio_size_show(struct device *device,
     24				struct device_attribute *attr,
     25				char *buf)
     26{
     27	struct ocxl_afu *afu = to_afu(device);
     28
     29	return scnprintf(buf, PAGE_SIZE, "%d\n",
     30			afu->config.pp_mmio_stride);
     31}
     32
     33static ssize_t afu_version_show(struct device *device,
     34				struct device_attribute *attr,
     35				char *buf)
     36{
     37	struct ocxl_afu *afu = to_afu(device);
     38
     39	return scnprintf(buf, PAGE_SIZE, "%hhu:%hhu\n",
     40			afu->config.version_major,
     41			afu->config.version_minor);
     42}
     43
     44static ssize_t contexts_show(struct device *device,
     45		struct device_attribute *attr,
     46		char *buf)
     47{
     48	struct ocxl_afu *afu = to_afu(device);
     49
     50	return scnprintf(buf, PAGE_SIZE, "%d/%d\n",
     51			afu->pasid_count, afu->pasid_max);
     52}
     53
     54static ssize_t reload_on_reset_show(struct device *device,
     55				    struct device_attribute *attr,
     56				    char *buf)
     57{
     58	struct ocxl_afu *afu = to_afu(device);
     59	struct ocxl_fn *fn = afu->fn;
     60	struct pci_dev *pci_dev = to_pci_dev(fn->dev.parent);
     61	int val;
     62
     63	if (ocxl_config_get_reset_reload(pci_dev, &val))
     64		return scnprintf(buf, PAGE_SIZE, "unavailable\n");
     65
     66	return scnprintf(buf, PAGE_SIZE, "%d\n", val);
     67}
     68
     69static ssize_t reload_on_reset_store(struct device *device,
     70				     struct device_attribute *attr,
     71				     const char *buf, size_t count)
     72{
     73	struct ocxl_afu *afu = to_afu(device);
     74	struct ocxl_fn *fn = afu->fn;
     75	struct pci_dev *pci_dev = to_pci_dev(fn->dev.parent);
     76	int rc, val;
     77
     78	rc = kstrtoint(buf, 0, &val);
     79	if (rc || (val != 0 && val != 1))
     80		return -EINVAL;
     81
     82	if (ocxl_config_set_reset_reload(pci_dev, val))
     83		return -ENODEV;
     84
     85	return count;
     86}
     87
     88static struct device_attribute afu_attrs[] = {
     89	__ATTR_RO(global_mmio_size),
     90	__ATTR_RO(pp_mmio_size),
     91	__ATTR_RO(afu_version),
     92	__ATTR_RO(contexts),
     93	__ATTR_RW(reload_on_reset),
     94};
     95
     96static ssize_t global_mmio_read(struct file *filp, struct kobject *kobj,
     97				struct bin_attribute *bin_attr, char *buf,
     98				loff_t off, size_t count)
     99{
    100	struct ocxl_afu *afu = to_afu(kobj_to_dev(kobj));
    101
    102	if (count == 0 || off < 0 ||
    103		off >= afu->config.global_mmio_size)
    104		return 0;
    105	memcpy_fromio(buf, afu->global_mmio_ptr + off, count);
    106	return count;
    107}
    108
    109static vm_fault_t global_mmio_fault(struct vm_fault *vmf)
    110{
    111	struct vm_area_struct *vma = vmf->vma;
    112	struct ocxl_afu *afu = vma->vm_private_data;
    113	unsigned long offset;
    114
    115	if (vmf->pgoff >= (afu->config.global_mmio_size >> PAGE_SHIFT))
    116		return VM_FAULT_SIGBUS;
    117
    118	offset = vmf->pgoff;
    119	offset += (afu->global_mmio_start >> PAGE_SHIFT);
    120	return vmf_insert_pfn(vma, vmf->address, offset);
    121}
    122
    123static const struct vm_operations_struct global_mmio_vmops = {
    124	.fault = global_mmio_fault,
    125};
    126
    127static int global_mmio_mmap(struct file *filp, struct kobject *kobj,
    128			struct bin_attribute *bin_attr,
    129			struct vm_area_struct *vma)
    130{
    131	struct ocxl_afu *afu = to_afu(kobj_to_dev(kobj));
    132
    133	if ((vma_pages(vma) + vma->vm_pgoff) >
    134		(afu->config.global_mmio_size >> PAGE_SHIFT))
    135		return -EINVAL;
    136
    137	vma->vm_flags |= VM_IO | VM_PFNMAP;
    138	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    139	vma->vm_ops = &global_mmio_vmops;
    140	vma->vm_private_data = afu;
    141	return 0;
    142}
    143
    144int ocxl_sysfs_register_afu(struct ocxl_file_info *info)
    145{
    146	int i, rc;
    147
    148	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
    149		rc = device_create_file(&info->dev, &afu_attrs[i]);
    150		if (rc)
    151			goto err;
    152	}
    153
    154	sysfs_attr_init(&info->attr_global_mmio.attr);
    155	info->attr_global_mmio.attr.name = "global_mmio_area";
    156	info->attr_global_mmio.attr.mode = 0600;
    157	info->attr_global_mmio.size = info->afu->config.global_mmio_size;
    158	info->attr_global_mmio.read = global_mmio_read;
    159	info->attr_global_mmio.mmap = global_mmio_mmap;
    160	rc = device_create_bin_file(&info->dev, &info->attr_global_mmio);
    161	if (rc) {
    162		dev_err(&info->dev, "Unable to create global mmio attr for afu: %d\n", rc);
    163		goto err;
    164	}
    165
    166	return 0;
    167
    168err:
    169	for (i--; i >= 0; i--)
    170		device_remove_file(&info->dev, &afu_attrs[i]);
    171
    172	return rc;
    173}
    174
    175void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info)
    176{
    177	int i;
    178
    179	/*
    180	 * device_remove_bin_file is safe to call if the file is not added as
    181	 * the files are removed by name, and early exit if not found
    182	 */
    183	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++)
    184		device_remove_file(&info->dev, &afu_attrs[i]);
    185	device_remove_bin_file(&info->dev, &info->attr_global_mmio);
    186}