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

setup-res.c (13406B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Support routines for initializing a PCI subsystem
      4 *
      5 * Extruded from code written by
      6 *      Dave Rusling (david.rusling@reo.mts.dec.com)
      7 *      David Mosberger (davidm@cs.arizona.edu)
      8 *	David Miller (davem@redhat.com)
      9 *
     10 * Fixed for multiple PCI buses, 1999 Andrea Arcangeli <andrea@suse.de>
     11 *
     12 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
     13 *	     Resource sorting
     14 */
     15
     16#include <linux/kernel.h>
     17#include <linux/export.h>
     18#include <linux/pci.h>
     19#include <linux/errno.h>
     20#include <linux/ioport.h>
     21#include <linux/cache.h>
     22#include <linux/slab.h>
     23#include "pci.h"
     24
     25static void pci_std_update_resource(struct pci_dev *dev, int resno)
     26{
     27	struct pci_bus_region region;
     28	bool disable;
     29	u16 cmd;
     30	u32 new, check, mask;
     31	int reg;
     32	struct resource *res = dev->resource + resno;
     33
     34	/* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
     35	if (dev->is_virtfn)
     36		return;
     37
     38	/*
     39	 * Ignore resources for unimplemented BARs and unused resource slots
     40	 * for 64 bit BARs.
     41	 */
     42	if (!res->flags)
     43		return;
     44
     45	if (res->flags & IORESOURCE_UNSET)
     46		return;
     47
     48	/*
     49	 * Ignore non-moveable resources.  This might be legacy resources for
     50	 * which no functional BAR register exists or another important
     51	 * system resource we shouldn't move around.
     52	 */
     53	if (res->flags & IORESOURCE_PCI_FIXED)
     54		return;
     55
     56	pcibios_resource_to_bus(dev->bus, &region, res);
     57	new = region.start;
     58
     59	if (res->flags & IORESOURCE_IO) {
     60		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
     61		new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
     62	} else if (resno == PCI_ROM_RESOURCE) {
     63		mask = PCI_ROM_ADDRESS_MASK;
     64	} else {
     65		mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
     66		new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
     67	}
     68
     69	if (resno < PCI_ROM_RESOURCE) {
     70		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
     71	} else if (resno == PCI_ROM_RESOURCE) {
     72
     73		/*
     74		 * Apparently some Matrox devices have ROM BARs that read
     75		 * as zero when disabled, so don't update ROM BARs unless
     76		 * they're enabled.  See
     77		 * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
     78		 * But we must update ROM BAR for buggy devices where even a
     79		 * disabled ROM can conflict with other BARs.
     80		 */
     81		if (!(res->flags & IORESOURCE_ROM_ENABLE) &&
     82		    !dev->rom_bar_overlap)
     83			return;
     84
     85		reg = dev->rom_base_reg;
     86		if (res->flags & IORESOURCE_ROM_ENABLE)
     87			new |= PCI_ROM_ADDRESS_ENABLE;
     88	} else
     89		return;
     90
     91	/*
     92	 * We can't update a 64-bit BAR atomically, so when possible,
     93	 * disable decoding so that a half-updated BAR won't conflict
     94	 * with another device.
     95	 */
     96	disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
     97	if (disable) {
     98		pci_read_config_word(dev, PCI_COMMAND, &cmd);
     99		pci_write_config_word(dev, PCI_COMMAND,
    100				      cmd & ~PCI_COMMAND_MEMORY);
    101	}
    102
    103	pci_write_config_dword(dev, reg, new);
    104	pci_read_config_dword(dev, reg, &check);
    105
    106	if ((new ^ check) & mask) {
    107		pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
    108			resno, new, check);
    109	}
    110
    111	if (res->flags & IORESOURCE_MEM_64) {
    112		new = region.start >> 16 >> 16;
    113		pci_write_config_dword(dev, reg + 4, new);
    114		pci_read_config_dword(dev, reg + 4, &check);
    115		if (check != new) {
    116			pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
    117				resno, new, check);
    118		}
    119	}
    120
    121	if (disable)
    122		pci_write_config_word(dev, PCI_COMMAND, cmd);
    123}
    124
    125void pci_update_resource(struct pci_dev *dev, int resno)
    126{
    127	if (resno <= PCI_ROM_RESOURCE)
    128		pci_std_update_resource(dev, resno);
    129#ifdef CONFIG_PCI_IOV
    130	else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
    131		pci_iov_update_resource(dev, resno);
    132#endif
    133}
    134
    135int pci_claim_resource(struct pci_dev *dev, int resource)
    136{
    137	struct resource *res = &dev->resource[resource];
    138	struct resource *root, *conflict;
    139
    140	if (res->flags & IORESOURCE_UNSET) {
    141		pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
    142			 resource, res);
    143		return -EINVAL;
    144	}
    145
    146	/*
    147	 * If we have a shadow copy in RAM, the PCI device doesn't respond
    148	 * to the shadow range, so we don't need to claim it, and upstream
    149	 * bridges don't need to route the range to the device.
    150	 */
    151	if (res->flags & IORESOURCE_ROM_SHADOW)
    152		return 0;
    153
    154	root = pci_find_parent_resource(dev, res);
    155	if (!root) {
    156		pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
    157			 resource, res);
    158		res->flags |= IORESOURCE_UNSET;
    159		return -EINVAL;
    160	}
    161
    162	conflict = request_resource_conflict(root, res);
    163	if (conflict) {
    164		pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
    165			 resource, res, conflict->name, conflict);
    166		res->flags |= IORESOURCE_UNSET;
    167		return -EBUSY;
    168	}
    169
    170	return 0;
    171}
    172EXPORT_SYMBOL(pci_claim_resource);
    173
    174void pci_disable_bridge_window(struct pci_dev *dev)
    175{
    176	/* MMIO Base/Limit */
    177	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
    178
    179	/* Prefetchable MMIO Base/Limit */
    180	pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
    181	pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
    182	pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
    183}
    184
    185/*
    186 * Generic function that returns a value indicating that the device's
    187 * original BIOS BAR address was not saved and so is not available for
    188 * reinstatement.
    189 *
    190 * Can be over-ridden by architecture specific code that implements
    191 * reinstatement functionality rather than leaving it disabled when
    192 * normal allocation attempts fail.
    193 */
    194resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
    195{
    196	return 0;
    197}
    198
    199static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
    200		int resno, resource_size_t size)
    201{
    202	struct resource *root, *conflict;
    203	resource_size_t fw_addr, start, end;
    204
    205	fw_addr = pcibios_retrieve_fw_addr(dev, resno);
    206	if (!fw_addr)
    207		return -ENOMEM;
    208
    209	start = res->start;
    210	end = res->end;
    211	res->start = fw_addr;
    212	res->end = res->start + size - 1;
    213	res->flags &= ~IORESOURCE_UNSET;
    214
    215	root = pci_find_parent_resource(dev, res);
    216	if (!root) {
    217		if (res->flags & IORESOURCE_IO)
    218			root = &ioport_resource;
    219		else
    220			root = &iomem_resource;
    221	}
    222
    223	pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
    224		 resno, res);
    225	conflict = request_resource_conflict(root, res);
    226	if (conflict) {
    227		pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
    228			 resno, res, conflict->name, conflict);
    229		res->start = start;
    230		res->end = end;
    231		res->flags |= IORESOURCE_UNSET;
    232		return -EBUSY;
    233	}
    234	return 0;
    235}
    236
    237/*
    238 * We don't have to worry about legacy ISA devices, so nothing to do here.
    239 * This is marked as __weak because multiple architectures define it; it should
    240 * eventually go away.
    241 */
    242resource_size_t __weak pcibios_align_resource(void *data,
    243					      const struct resource *res,
    244					      resource_size_t size,
    245					      resource_size_t align)
    246{
    247       return res->start;
    248}
    249
    250static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
    251		int resno, resource_size_t size, resource_size_t align)
    252{
    253	struct resource *res = dev->resource + resno;
    254	resource_size_t min;
    255	int ret;
    256
    257	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
    258
    259	/*
    260	 * First, try exact prefetching match.  Even if a 64-bit
    261	 * prefetchable bridge window is below 4GB, we can't put a 32-bit
    262	 * prefetchable resource in it because pbus_size_mem() assumes a
    263	 * 64-bit window will contain no 32-bit resources.  If we assign
    264	 * things differently than they were sized, not everything will fit.
    265	 */
    266	ret = pci_bus_alloc_resource(bus, res, size, align, min,
    267				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
    268				     pcibios_align_resource, dev);
    269	if (ret == 0)
    270		return 0;
    271
    272	/*
    273	 * If the prefetchable window is only 32 bits wide, we can put
    274	 * 64-bit prefetchable resources in it.
    275	 */
    276	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
    277	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
    278		ret = pci_bus_alloc_resource(bus, res, size, align, min,
    279					     IORESOURCE_PREFETCH,
    280					     pcibios_align_resource, dev);
    281		if (ret == 0)
    282			return 0;
    283	}
    284
    285	/*
    286	 * If we didn't find a better match, we can put any memory resource
    287	 * in a non-prefetchable window.  If this resource is 32 bits and
    288	 * non-prefetchable, the first call already tried the only possibility
    289	 * so we don't need to try again.
    290	 */
    291	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
    292		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
    293					     pcibios_align_resource, dev);
    294
    295	return ret;
    296}
    297
    298static int _pci_assign_resource(struct pci_dev *dev, int resno,
    299				resource_size_t size, resource_size_t min_align)
    300{
    301	struct pci_bus *bus;
    302	int ret;
    303
    304	bus = dev->bus;
    305	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
    306		if (!bus->parent || !bus->self->transparent)
    307			break;
    308		bus = bus->parent;
    309	}
    310
    311	return ret;
    312}
    313
    314int pci_assign_resource(struct pci_dev *dev, int resno)
    315{
    316	struct resource *res = dev->resource + resno;
    317	resource_size_t align, size;
    318	int ret;
    319
    320	if (res->flags & IORESOURCE_PCI_FIXED)
    321		return 0;
    322
    323	res->flags |= IORESOURCE_UNSET;
    324	align = pci_resource_alignment(dev, res);
    325	if (!align) {
    326		pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
    327			 resno, res);
    328		return -EINVAL;
    329	}
    330
    331	size = resource_size(res);
    332	ret = _pci_assign_resource(dev, resno, size, align);
    333
    334	/*
    335	 * If we failed to assign anything, let's try the address
    336	 * where firmware left it.  That at least has a chance of
    337	 * working, which is better than just leaving it disabled.
    338	 */
    339	if (ret < 0) {
    340		pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
    341		ret = pci_revert_fw_address(res, dev, resno, size);
    342	}
    343
    344	if (ret < 0) {
    345		pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
    346		return ret;
    347	}
    348
    349	res->flags &= ~IORESOURCE_UNSET;
    350	res->flags &= ~IORESOURCE_STARTALIGN;
    351	pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
    352	if (resno < PCI_BRIDGE_RESOURCES)
    353		pci_update_resource(dev, resno);
    354
    355	return 0;
    356}
    357EXPORT_SYMBOL(pci_assign_resource);
    358
    359int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
    360			resource_size_t min_align)
    361{
    362	struct resource *res = dev->resource + resno;
    363	unsigned long flags;
    364	resource_size_t new_size;
    365	int ret;
    366
    367	if (res->flags & IORESOURCE_PCI_FIXED)
    368		return 0;
    369
    370	flags = res->flags;
    371	res->flags |= IORESOURCE_UNSET;
    372	if (!res->parent) {
    373		pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
    374			 resno, res);
    375		return -EINVAL;
    376	}
    377
    378	/* already aligned with min_align */
    379	new_size = resource_size(res) + addsize;
    380	ret = _pci_assign_resource(dev, resno, new_size, min_align);
    381	if (ret) {
    382		res->flags = flags;
    383		pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
    384			 resno, res, (unsigned long long) addsize);
    385		return ret;
    386	}
    387
    388	res->flags &= ~IORESOURCE_UNSET;
    389	res->flags &= ~IORESOURCE_STARTALIGN;
    390	pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
    391		 resno, res, (unsigned long long) addsize);
    392	if (resno < PCI_BRIDGE_RESOURCES)
    393		pci_update_resource(dev, resno);
    394
    395	return 0;
    396}
    397
    398void pci_release_resource(struct pci_dev *dev, int resno)
    399{
    400	struct resource *res = dev->resource + resno;
    401
    402	pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
    403
    404	if (!res->parent)
    405		return;
    406
    407	release_resource(res);
    408	res->end = resource_size(res) - 1;
    409	res->start = 0;
    410	res->flags |= IORESOURCE_UNSET;
    411}
    412EXPORT_SYMBOL(pci_release_resource);
    413
    414int pci_resize_resource(struct pci_dev *dev, int resno, int size)
    415{
    416	struct resource *res = dev->resource + resno;
    417	struct pci_host_bridge *host;
    418	int old, ret;
    419	u32 sizes;
    420	u16 cmd;
    421
    422	/* Check if we must preserve the firmware's resource assignment */
    423	host = pci_find_host_bridge(dev->bus);
    424	if (host->preserve_config)
    425		return -ENOTSUPP;
    426
    427	/* Make sure the resource isn't assigned before resizing it. */
    428	if (!(res->flags & IORESOURCE_UNSET))
    429		return -EBUSY;
    430
    431	pci_read_config_word(dev, PCI_COMMAND, &cmd);
    432	if (cmd & PCI_COMMAND_MEMORY)
    433		return -EBUSY;
    434
    435	sizes = pci_rebar_get_possible_sizes(dev, resno);
    436	if (!sizes)
    437		return -ENOTSUPP;
    438
    439	if (!(sizes & BIT(size)))
    440		return -EINVAL;
    441
    442	old = pci_rebar_get_current_size(dev, resno);
    443	if (old < 0)
    444		return old;
    445
    446	ret = pci_rebar_set_size(dev, resno, size);
    447	if (ret)
    448		return ret;
    449
    450	res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
    451
    452	/* Check if the new config works by trying to assign everything. */
    453	if (dev->bus->self) {
    454		ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
    455		if (ret)
    456			goto error_resize;
    457	}
    458	return 0;
    459
    460error_resize:
    461	pci_rebar_set_size(dev, resno, old);
    462	res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
    463	return ret;
    464}
    465EXPORT_SYMBOL(pci_resize_resource);
    466
    467int pci_enable_resources(struct pci_dev *dev, int mask)
    468{
    469	u16 cmd, old_cmd;
    470	int i;
    471	struct resource *r;
    472
    473	pci_read_config_word(dev, PCI_COMMAND, &cmd);
    474	old_cmd = cmd;
    475
    476	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
    477		if (!(mask & (1 << i)))
    478			continue;
    479
    480		r = &dev->resource[i];
    481
    482		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
    483			continue;
    484		if ((i == PCI_ROM_RESOURCE) &&
    485				(!(r->flags & IORESOURCE_ROM_ENABLE)))
    486			continue;
    487
    488		if (r->flags & IORESOURCE_UNSET) {
    489			pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
    490				i, r);
    491			return -EINVAL;
    492		}
    493
    494		if (!r->parent) {
    495			pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
    496				i, r);
    497			return -EINVAL;
    498		}
    499
    500		if (r->flags & IORESOURCE_IO)
    501			cmd |= PCI_COMMAND_IO;
    502		if (r->flags & IORESOURCE_MEM)
    503			cmd |= PCI_COMMAND_MEMORY;
    504	}
    505
    506	if (cmd != old_cmd) {
    507		pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
    508		pci_write_config_word(dev, PCI_COMMAND, cmd);
    509	}
    510	return 0;
    511}