VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   57 Tags
3b20eb23724d4 (Thomas Gleixner       2019-05-29 16:57:35 -0700   1) // SPDX-License-Identifier: GPL-2.0-only
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   2) /*
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   3)  * Copyright (c) 2009, Intel Corporation.
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   4)  *
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   5)  * Author: Weidong Han <weidong.han@intel.com>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   6)  */
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   7) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100   8) #include <linux/pci.h>
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100   9) #include <linux/acpi.h>
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  10) #include <linux/pci-acpi.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  11) #include <xen/xen.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  12) #include <xen/interface/physdev.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  13) #include <xen/interface/xen.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  14) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  15) #include <asm/xen/hypervisor.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  16) #include <asm/xen/hypercall.h>
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  17) #include "../pci/pci.h"
b7ef4a6dd35d1 (Ben Hutchings         2013-12-31 20:46:27 +0100  18) #ifdef CONFIG_PCI_MMCONFIG
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400  19) #include <asm/pci_x86.h>
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  20) 
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  21) static int xen_mcfg_late(void);
b7ef4a6dd35d1 (Ben Hutchings         2013-12-31 20:46:27 +0100  22) #endif
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  23) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  24) static bool __read_mostly pci_seg_supported = true;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  25) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  26) static int xen_add_device(struct device *dev)
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  27) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  28) 	int r;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  29) 	struct pci_dev *pci_dev = to_pci_dev(dev);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  30) #ifdef CONFIG_PCI_IOV
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  31) 	struct pci_dev *physfn = pci_dev->physfn;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  32) #endif
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  33) #ifdef CONFIG_PCI_MMCONFIG
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  34) 	static bool pci_mcfg_reserved = false;
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  35) 	/*
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  36) 	 * Reserve MCFG areas in Xen on first invocation due to this being
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  37) 	 * potentially called from inside of acpi_init immediately after
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  38) 	 * MCFG table has been finally parsed.
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  39) 	 */
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  40) 	if (!pci_mcfg_reserved) {
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  41) 		xen_mcfg_late();
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  42) 		pci_mcfg_reserved = true;
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  43) 	}
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100  44) #endif
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  45) 	if (pci_seg_supported) {
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  46) 		struct {
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  47) 			struct physdev_pci_device_add add;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  48) 			uint32_t pxm;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  49) 		} add_ext = {
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  50) 			.add.seg = pci_domain_nr(pci_dev->bus),
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  51) 			.add.bus = pci_dev->bus->number,
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  52) 			.add.devfn = pci_dev->devfn
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  53) 		};
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  54) 		struct physdev_pci_device_add *add = &add_ext.add;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  55) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  56) #ifdef CONFIG_ACPI
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  57) 		acpi_handle handle;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  58) #endif
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  59) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100  60) #ifdef CONFIG_PCI_IOV
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  61) 		if (pci_dev->is_virtfn) {
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  62) 			add->flags = XEN_PCI_DEV_VIRTFN;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  63) 			add->physfn.bus = physfn->bus->number;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  64) 			add->physfn.devfn = physfn->devfn;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  65) 		} else
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  66) #endif
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  67) 		if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn))
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  68) 			add->flags = XEN_PCI_DEV_EXTFN;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  69) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  70) #ifdef CONFIG_ACPI
3a83f992490f8 (Rafael J. Wysocki     2013-11-14 23:17:21 +0100  71) 		handle = ACPI_HANDLE(&pci_dev->dev);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  72) #ifdef CONFIG_PCI_IOV
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  73) 		if (!handle && pci_dev->is_virtfn)
3a83f992490f8 (Rafael J. Wysocki     2013-11-14 23:17:21 +0100  74) 			handle = ACPI_HANDLE(physfn->bus->bridge);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  75) #endif
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  76) 		if (!handle) {
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  77) 			/*
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  78) 			 * This device was not listed in the ACPI name space at
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  79) 			 * all. Try to get acpi handle of parent pci bus.
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  80) 			 */
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  81) 			struct pci_bus *pbus;
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  82) 			for (pbus = pci_dev->bus; pbus; pbus = pbus->parent) {
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  83) 				handle = acpi_pci_get_bridge_handle(pbus);
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  84) 				if (handle)
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  85) 					break;
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  86) 			}
0b97b03d88b40 (Ross Lagerwall        2015-04-09 08:05:10 +0100  87) 		}
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  88) 		if (handle) {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  89) 			acpi_status status;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  90) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  91) 			do {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  92) 				unsigned long long pxm;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  93) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  94) 				status = acpi_evaluate_integer(handle, "_PXM",
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  95) 							       NULL, &pxm);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  96) 				if (ACPI_SUCCESS(status)) {
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  97) 					add->optarr[0] = pxm;
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400  98) 					add->flags |= XEN_PCI_DEV_PXM;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100  99) 					break;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 100) 				}
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 101) 				status = acpi_get_parent(handle, &handle);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 102) 			} while (ACPI_SUCCESS(status));
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 103) 		}
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 104) #endif /* CONFIG_ACPI */
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 105) 
486edb24952c9 (Boris Ostrovsky       2014-08-04 18:17:23 -0400 106) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, add);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 107) 		if (r != -ENOSYS)
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 108) 			return r;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 109) 		pci_seg_supported = false;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 110) 	}
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 111) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 112) 	if (pci_domain_nr(pci_dev->bus))
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 113) 		r = -ENOSYS;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 114) #ifdef CONFIG_PCI_IOV
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 115) 	else if (pci_dev->is_virtfn) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 116) 		struct physdev_manage_pci_ext manage_pci_ext = {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 117) 			.bus		= pci_dev->bus->number,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 118) 			.devfn		= pci_dev->devfn,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 119) 			.is_virtfn 	= 1,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 120) 			.physfn.bus	= physfn->bus->number,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 121) 			.physfn.devfn	= physfn->devfn,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 122) 		};
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 123) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 124) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 125) 			&manage_pci_ext);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 126) 	}
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 127) #endif
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 128) 	else if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn)) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 129) 		struct physdev_manage_pci_ext manage_pci_ext = {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 130) 			.bus		= pci_dev->bus->number,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 131) 			.devfn		= pci_dev->devfn,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 132) 			.is_extfn	= 1,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 133) 		};
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 134) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 135) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 136) 			&manage_pci_ext);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 137) 	} else {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 138) 		struct physdev_manage_pci manage_pci = {
4b0109830842f (Ruslan Pisarev        2011-07-26 14:16:38 +0300 139) 			.bus	= pci_dev->bus->number,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 140) 			.devfn	= pci_dev->devfn,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 141) 		};
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 142) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 143) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 144) 			&manage_pci);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 145) 	}
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 146) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 147) 	return r;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 148) }
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 149) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 150) static int xen_remove_device(struct device *dev)
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 151) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 152) 	int r;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 153) 	struct pci_dev *pci_dev = to_pci_dev(dev);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 154) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 155) 	if (pci_seg_supported) {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 156) 		struct physdev_pci_device device = {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 157) 			.seg = pci_domain_nr(pci_dev->bus),
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 158) 			.bus = pci_dev->bus->number,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 159) 			.devfn = pci_dev->devfn
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 160) 		};
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 161) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 162) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_remove,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 163) 					  &device);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 164) 	} else if (pci_domain_nr(pci_dev->bus))
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 165) 		r = -ENOSYS;
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 166) 	else {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 167) 		struct physdev_manage_pci manage_pci = {
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 168) 			.bus = pci_dev->bus->number,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 169) 			.devfn = pci_dev->devfn
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 170) 		};
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 171) 
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 172) 		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove,
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 173) 					  &manage_pci);
55e901fc1f03d (Jan Beulich           2011-09-22 09:17:57 +0100 174) 	}
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 175) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 176) 	return r;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 177) }
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 178) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 179) static int xen_pci_notifier(struct notifier_block *nb,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 180) 			    unsigned long action, void *data)
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 181) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 182) 	struct device *dev = data;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 183) 	int r = 0;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 184) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 185) 	switch (action) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 186) 	case BUS_NOTIFY_ADD_DEVICE:
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 187) 		r = xen_add_device(dev);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 188) 		break;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 189) 	case BUS_NOTIFY_DEL_DEVICE:
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 190) 		r = xen_remove_device(dev);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 191) 		break;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 192) 	default:
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 193) 		return NOTIFY_DONE;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 194) 	}
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 195) 	if (r)
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 196) 		dev_err(dev, "Failed to %s - passthrough or MSI/MSI-X might fail!\n",
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 197) 			action == BUS_NOTIFY_ADD_DEVICE ? "add" :
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 198) 			(action == BUS_NOTIFY_DEL_DEVICE ? "delete" : "?"));
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 199) 	return NOTIFY_OK;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 200) }
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 201) 
12e13ac84ca70 (Jan Beulich           2011-08-17 09:32:32 +0100 202) static struct notifier_block device_nb = {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 203) 	.notifier_call = xen_pci_notifier,
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 204) };
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 205) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 206) static int __init register_xen_pci_notifier(void)
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 207) {
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 208) 	if (!xen_initial_domain())
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 209) 		return 0;
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 210) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 211) 	return bus_register_notifier(&pci_bus_type, &device_nb);
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 212) }
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 213) 
e28c31a96b157 (Weidong Han           2010-10-27 17:55:04 +0100 214) arch_initcall(register_xen_pci_notifier);
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 215) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 216) #ifdef CONFIG_PCI_MMCONFIG
a4098bc6eed5e (Igor Druzhinin        2019-09-12 19:31:51 +0100 217) static int xen_mcfg_late(void)
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 218) {
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 219) 	struct pci_mmcfg_region *cfg;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 220) 	int rc;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 221) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 222) 	if (!xen_initial_domain())
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 223) 		return 0;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 224) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 225) 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 226) 		return 0;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 227) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 228) 	if (list_empty(&pci_mmcfg_list))
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 229) 		return 0;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 230) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 231) 	/* Check whether they are in the right area. */
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 232) 	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 233) 		struct physdev_pci_mmcfg_reserved r;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 234) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 235) 		r.address = cfg->address;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 236) 		r.segment = cfg->segment;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 237) 		r.start_bus = cfg->start_bus;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 238) 		r.end_bus = cfg->end_bus;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 239) 		r.flags = XEN_PCI_MMCFG_RESERVED;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 240) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 241) 		rc = HYPERVISOR_physdev_op(PHYSDEVOP_pci_mmcfg_reserved, &r);
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 242) 		switch (rc) {
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 243) 		case 0:
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 244) 		case -ENOSYS:
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 245) 			continue;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 246) 
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 247) 		default:
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 248) 			pr_warn("Failed to report MMCONFIG reservation"
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 249) 				" state for %s to hypervisor"
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 250) 				" (%d)\n",
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 251) 				cfg->name, rc);
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 252) 		}
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 253) 	}
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 254) 	return 0;
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 255) }
8deb3eb1461e4 (Konrad Rzeszutek Wilk 2013-10-25 16:26:02 -0400 256) #endif