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

ehci-sysfs.c (4388B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (C) 2007 by Alan Stern
      4 */
      5
      6/* this file is part of ehci-hcd.c */
      7
      8
      9/* Display the ports dedicated to the companion controller */
     10static ssize_t companion_show(struct device *dev,
     11			      struct device_attribute *attr,
     12			      char *buf)
     13{
     14	struct ehci_hcd		*ehci;
     15	int			nports, index, n;
     16	int			count = PAGE_SIZE;
     17	char			*ptr = buf;
     18
     19	ehci = hcd_to_ehci(dev_get_drvdata(dev));
     20	nports = HCS_N_PORTS(ehci->hcs_params);
     21
     22	for (index = 0; index < nports; ++index) {
     23		if (test_bit(index, &ehci->companion_ports)) {
     24			n = scnprintf(ptr, count, "%d\n", index + 1);
     25			ptr += n;
     26			count -= n;
     27		}
     28	}
     29	return ptr - buf;
     30}
     31
     32/*
     33 * Dedicate or undedicate a port to the companion controller.
     34 * Syntax is "[-]portnum", where a leading '-' sign means
     35 * return control of the port to the EHCI controller.
     36 */
     37static ssize_t companion_store(struct device *dev,
     38			       struct device_attribute *attr,
     39			       const char *buf, size_t count)
     40{
     41	struct ehci_hcd		*ehci;
     42	int			portnum, new_owner;
     43
     44	ehci = hcd_to_ehci(dev_get_drvdata(dev));
     45	new_owner = PORT_OWNER;		/* Owned by companion */
     46	if (sscanf(buf, "%d", &portnum) != 1)
     47		return -EINVAL;
     48	if (portnum < 0) {
     49		portnum = - portnum;
     50		new_owner = 0;		/* Owned by EHCI */
     51	}
     52	if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
     53		return -ENOENT;
     54	portnum--;
     55	if (new_owner)
     56		set_bit(portnum, &ehci->companion_ports);
     57	else
     58		clear_bit(portnum, &ehci->companion_ports);
     59	set_owner(ehci, portnum, new_owner);
     60	return count;
     61}
     62static DEVICE_ATTR_RW(companion);
     63
     64
     65/*
     66 * Display / Set uframe_periodic_max
     67 */
     68static ssize_t uframe_periodic_max_show(struct device *dev,
     69					struct device_attribute *attr,
     70					char *buf)
     71{
     72	struct ehci_hcd		*ehci;
     73	int			n;
     74
     75	ehci = hcd_to_ehci(dev_get_drvdata(dev));
     76	n = scnprintf(buf, PAGE_SIZE, "%d\n", ehci->uframe_periodic_max);
     77	return n;
     78}
     79
     80
     81static ssize_t uframe_periodic_max_store(struct device *dev,
     82					struct device_attribute *attr,
     83					const char *buf, size_t count)
     84{
     85	struct ehci_hcd		*ehci;
     86	unsigned		uframe_periodic_max;
     87	unsigned		uframe;
     88	unsigned long		flags;
     89	ssize_t			ret;
     90
     91	ehci = hcd_to_ehci(dev_get_drvdata(dev));
     92	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
     93		return -EINVAL;
     94
     95	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
     96		ehci_info(ehci, "rejecting invalid request for "
     97				"uframe_periodic_max=%u\n", uframe_periodic_max);
     98		return -EINVAL;
     99	}
    100
    101	ret = -EINVAL;
    102
    103	/*
    104	 * lock, so that our checking does not race with possible periodic
    105	 * bandwidth allocation through submitting new urbs.
    106	 */
    107	spin_lock_irqsave (&ehci->lock, flags);
    108
    109	/*
    110	 * for request to decrease max periodic bandwidth, we have to check
    111	 * to see whether the decrease is possible.
    112	 */
    113	if (uframe_periodic_max < ehci->uframe_periodic_max) {
    114		u8		allocated_max = 0;
    115
    116		for (uframe = 0; uframe < EHCI_BANDWIDTH_SIZE; ++uframe)
    117			allocated_max = max(allocated_max,
    118					ehci->bandwidth[uframe]);
    119
    120		if (allocated_max > uframe_periodic_max) {
    121			ehci_info(ehci,
    122				"cannot decrease uframe_periodic_max because "
    123				"periodic bandwidth is already allocated "
    124				"(%u > %u)\n",
    125				allocated_max, uframe_periodic_max);
    126			goto out_unlock;
    127		}
    128	}
    129
    130	/* increasing is always ok */
    131
    132	ehci_info(ehci, "setting max periodic bandwidth to %u%% "
    133			"(== %u usec/uframe)\n",
    134			100*uframe_periodic_max/125, uframe_periodic_max);
    135
    136	if (uframe_periodic_max != 100)
    137		ehci_warn(ehci, "max periodic bandwidth set is non-standard\n");
    138
    139	ehci->uframe_periodic_max = uframe_periodic_max;
    140	ret = count;
    141
    142out_unlock:
    143	spin_unlock_irqrestore (&ehci->lock, flags);
    144	return ret;
    145}
    146static DEVICE_ATTR_RW(uframe_periodic_max);
    147
    148
    149static inline int create_sysfs_files(struct ehci_hcd *ehci)
    150{
    151	struct device	*controller = ehci_to_hcd(ehci)->self.controller;
    152	int	i = 0;
    153
    154	/* with integrated TT there is no companion! */
    155	if (!ehci_is_TDI(ehci))
    156		i = device_create_file(controller, &dev_attr_companion);
    157	if (i)
    158		goto out;
    159
    160	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
    161out:
    162	return i;
    163}
    164
    165static inline void remove_sysfs_files(struct ehci_hcd *ehci)
    166{
    167	struct device	*controller = ehci_to_hcd(ehci)->self.controller;
    168
    169	/* with integrated TT there is no companion! */
    170	if (!ehci_is_TDI(ehci))
    171		device_remove_file(controller, &dev_attr_companion);
    172
    173	device_remove_file(controller, &dev_attr_uframe_periodic_max);
    174}