From: Jiang Liu <liuj97@gmail.com>
To: Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>,
linux-pci@vger.kernel.org
Subject: Re: [PATCH] [RFC] PCI, ACPI, x86: MMCFG support for hotpluggable PCI hostbridges on x86, x86_64
Date: Sat, 07 Apr 2012 23:20:18 +0800 [thread overview]
Message-ID: <4F805B32.1080401@gmail.com> (raw)
In-Reply-To: <20120406201628.1621752c.izumi.taku@jp.fujitsu.com>
On 04/06/2012 07:16 PM, Taku Izumi wrote:
>
> This patch introduces the configuration for the base address of
> the memory mapped configuration space (MMCFG) for hotpluggable PCI
> hostbridges on x86 and x86_64.
>
> The MMCFG for hotpluggable host bridges must be described by using
> ACPI _CBA method. This patch adds implementation for _CBA method
> on ACPI pci_root driver and MMCFG manipulating functons for x86 and
> x86_64.
>
> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
> ---
> arch/x86/pci/mmconfig-shared.c | 61 ++++++++++++++++++++++++++++++++++-------
> drivers/acpi/pci_root.c | 28 ++++++++++++++++++
> drivers/pci/pci.c | 31 ++++++++++++++++++++
> include/acpi/acnames.h | 1
> include/linux/pci.h | 3 ++
> 5 files changed, 113 insertions(+), 11 deletions(-)
>
> Index: linux-next-build/drivers/acpi/pci_root.c
> ===================================================================
> --- linux-next-build.orig/drivers/acpi/pci_root.c
> +++ linux-next-build/drivers/acpi/pci_root.c
> @@ -451,7 +451,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set);
>
> static int __devinit acpi_pci_root_add(struct acpi_device *device)
> {
> - unsigned long long segment, bus;
> + unsigned long long segment, bus, base_addr;
> acpi_status status;
> int result;
> struct acpi_pci_root *root;
> @@ -506,6 +506,28 @@ static int __devinit acpi_pci_root_add(s
> device->driver_data = root;
>
> /*
> + * Check _CBA for hot pluggable host bridge
> + */
> + base_addr = 0;
> + status = acpi_evaluate_integer(device->handle, METHOD_NAME__CBA, NULL,
> + &base_addr);
> + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
> + printk(KERN_ERR PREFIX "can't evaluate _CBA\n");
> + result = -ENODEV;
> + goto end;
> + }
> + if (base_addr) {
> + result = pci_add_mmcfg_region(root->segment,
> + root->secondary.start,
> + root->secondary.end,
> + base_addr);
> + if (result) {
> + printk(KERN_ERR PREFIX "can't add MMCFG entry\n");
> + goto end;
> + }
The MMCFG information for host bridges present at boot time should have already
been added by __pci_mmcfg_init() when acpi_pci_root_add() is called.
So it would be better for pci_add_mmcfg_region() to return -EEXIST for host
bridges present at boot time.
> + }
> +
> + /*
> * All supported architectures that use ACPI have support for
> * PCI domains, so we indicate this in _OSC support capabilities.
> */
> @@ -625,6 +647,8 @@ static int __devinit acpi_pci_root_add(s
> return 0;
>
> end:
> + if (base_addr)
> + pci_remove_mmcfg_region(root->segment, root->secondary.start);
> if (!list_empty(&root->node))
> list_del(&root->node);
> kfree(root);
> @@ -646,6 +670,8 @@ static int acpi_pci_root_remove(struct a
> device_set_run_wake(root->bus->bridge, false);
> pci_acpi_remove_bus_pm_notifier(device);
>
> + pci_remove_mmcfg_region(root->segment, root->secondary.start);
> +
It would be better to only call pci_remove_mmcfg_region() if the host bridge has _CBA
method available, otherwise we have no way to recover this MMCFG information and
can't rebind the pci_root driver to a pci host bridge after an unbinding operation.
> kfree(root);
> return 0;
> }
> Index: linux-next-build/include/acpi/acnames.h
> ===================================================================
> --- linux-next-build.orig/include/acpi/acnames.h
> +++ linux-next-build/include/acpi/acnames.h
> @@ -61,6 +61,7 @@
> #define METHOD_NAME__AEI "_AEI"
> #define METHOD_NAME__PRW "_PRW"
> #define METHOD_NAME__SRS "_SRS"
> +#define METHOD_NAME__CBA "_CBA"
>
> /* Method names - these methods must appear at the namespace root */
>
> Index: linux-next-build/include/linux/pci.h
> ===================================================================
> --- linux-next-build.orig/include/linux/pci.h
> +++ linux-next-build/include/linux/pci.h
> @@ -1460,6 +1460,9 @@ void pcibios_disable_device(struct pci_d
> void pcibios_set_master(struct pci_dev *dev);
> int pcibios_set_pcie_reset_state(struct pci_dev *dev,
> enum pcie_reset_state state);
> +int pci_add_mmcfg_region(int segment, int start,
> + int end, u64 addr);
> +void pci_remove_mmcfg_region(int segment, int bus);
>
> #ifdef CONFIG_PCI_MMCONFIG
> extern void __init pci_mmcfg_early_init(void);
> Index: linux-next-build/arch/x86/pci/mmconfig-shared.c
> ===================================================================
> --- linux-next-build.orig/arch/x86/pci/mmconfig-shared.c
> +++ linux-next-build/arch/x86/pci/mmconfig-shared.c
> @@ -28,7 +28,7 @@ static int __initdata pci_mmcfg_resource
>
> LIST_HEAD(pci_mmcfg_list);
>
> -static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
> +static __devinit void pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
> {
> if (cfg->res.parent)
> release_resource(&cfg->res);
> @@ -45,7 +45,7 @@ static __init void free_all_mmcfg(void)
> pci_mmconfig_remove(cfg);
> }
>
> -static __init void list_add_sorted(struct pci_mmcfg_region *new)
> +static __devinit void list_add_sorted(struct pci_mmcfg_region *new)
> {
> struct pci_mmcfg_region *cfg;
>
> @@ -61,8 +61,8 @@ static __init void list_add_sorted(struc
> list_add_tail(&new->list, &pci_mmcfg_list);
> }
>
> -static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
> - int end, u64 addr)
> +static __devinit struct pci_mmcfg_region *pci_mmconfig_add(int segment,
> + int start, int end, u64 addr)
> {
> struct pci_mmcfg_region *new;
> struct resource *res;
> @@ -357,8 +357,10 @@ static void __init pci_mmcfg_insert_reso
> {
> struct pci_mmcfg_region *cfg;
>
> - list_for_each_entry(cfg, &pci_mmcfg_list, list)
> - insert_resource(&iomem_resource, &cfg->res);
> + list_for_each_entry(cfg, &pci_mmcfg_list, list) {
> + if (!cfg->res.parent)
> + insert_resource(&iomem_resource, &cfg->res);
> + }
>
> /* Mark that the resources have been inserted. */
> pci_mmcfg_resources_inserted = 1;
> @@ -401,7 +403,7 @@ static acpi_status __init check_mcfg_res
> return AE_OK;
> }
>
> -static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
> +static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl,
> void *context, void **rv)
> {
> struct resource *mcfg_res = context;
> @@ -415,7 +417,7 @@ static acpi_status __init find_mboard_re
> return AE_OK;
> }
>
> -static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
> +static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used)
> {
> struct resource mcfg_res;
>
> @@ -434,8 +436,9 @@ static int __init is_acpi_reserved(u64 s
>
> typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
>
> -static int __init is_mmconf_reserved(check_reserved_t is_reserved,
> - struct pci_mmcfg_region *cfg, int with_e820)
> +static int __devinit is_mmconf_reserved(check_reserved_t is_reserved,
> + struct pci_mmcfg_region *cfg,
> + int with_e820)
> {
> u64 addr = cfg->res.start;
> u64 size = resource_size(&cfg->res);
> @@ -580,6 +583,44 @@ static int __init pci_parse_mcfg(struct
> return 0;
> }
>
> +int pci_add_mmcfg_region(int segment, int start, int end, u64 addr)
> +{
> + struct pci_mmcfg_region *cfg;
> + int valid;
> +
> + cfg = pci_mmconfig_add(segment, start, end, addr);
> + if (!cfg) {
> + printk(KERN_WARNING PREFIX
> + "no memory for MMCFG entry\n");
> + return -ENOMEM;
> + }
> +
> + valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0);
> + if (!valid) {
> + printk(KERN_ERR FW_BUG PREFIX
> + "MMCONFIG at %pR not reserved in "
> + "ACPI motherboard resources\n",
> + &cfg->res);
> + pci_mmconfig_remove(cfg);
> + return -EINVAL;
> + }
> +
> + insert_resource(&iomem_resource, &cfg->res);
> +
> + return 0;
> +}
> +
> +void pci_remove_mmcfg_region(int segment, int bus)
> +{
> + struct pci_mmcfg_region *cfg;
> +
> + cfg = pci_mmconfig_lookup(segment, bus);
> + if (!cfg)
> + return;
> +
> + pci_mmconfig_remove(cfg);
> +}
> +
> static void __init __pci_mmcfg_init(int early)
> {
> /* MMCONFIG disabled */
> Index: linux-next-build/drivers/pci/pci.c
> ===================================================================
> --- linux-next-build.orig/drivers/pci/pci.c
> +++ linux-next-build/drivers/pci/pci.c
> @@ -79,6 +79,37 @@ unsigned long pci_hotplug_mem_size = DEF
>
> enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
>
> +/**
> + *
> + * pci_add_mmcfg_region
> + * @segment: segment number
> + * @start: start bus number
> + * @end: end bus number
> + * @addr: base address
> + *
> + * Add MMCONFIG entry for specified segment or bus range group
> + *
> + * This is the default implementation. Architecture implementations
> + * can override this.
> + */
> +int __attribute__ ((weak)) pci_add_mmcfg_region(int segment, int start,
> + int end, u64 addr)
> +{
> + return -EINVAL;
> +}
> +
> +/**
> + * pci_remove_mmcfg_region
> + * @segment: segment number
> + * @bus: bus number
> + *
> + * Remove MMCONFIG entry for specified segment or bus range group
> + *
> + * This is the default implementation. Architecture implementations
> + * can override this.
> + */
> +void __attribute__ ((weak)) pci_remove_mmcfg_region(int segment, int bus) {}
> +
> /*
> * The default CLS is used if arch didn't set CLS explicitly and not
> * all pci devices agree on the same value. Arch can override either
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2012-04-07 15:20 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-06 2:59 [PATCH] [RFC] PCI, ACPI, x86: MMCFG support for hotpluggable PCI hostbridges on x86, x86_64 Taku Izumi
2012-04-06 6:31 ` Kenji Kaneshige
2012-04-06 11:15 ` Taku Izumi
2012-04-06 11:16 ` Taku Izumi
2012-04-07 15:20 ` Jiang Liu [this message]
2012-04-25 17:14 ` Bjorn Helgaas
2012-04-26 2:55 ` Taku Izumi
2012-04-07 15:09 ` Jiang Liu
2012-04-08 17:12 ` [PATCH RFC 0/2] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
2012-04-25 17:17 ` Bjorn Helgaas
2012-04-08 17:12 ` [PATCH 1/2] PCI,x86: introduce new MMCFG interfaces to support PCI host bridge hotplug Jiang Liu
2012-04-08 19:12 ` Yinghai Lu
2012-04-08 17:12 ` [PATCH 2/2] PCI, ACPI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
2012-04-08 19:19 ` Yinghai Lu
2012-04-09 3:43 ` Jiang Liu
2012-04-09 14:37 ` Jiang Liu
2012-04-09 15:11 ` Yinghai Lu
2012-04-09 20:48 ` Yinghai Lu
2012-04-09 11:43 ` Kenji Kaneshige
2012-04-09 16:02 ` Jiang Liu
2012-04-10 10:32 ` Kenji Kaneshige
2012-04-10 15:47 ` Yinghai Lu
2012-04-10 16:05 ` Jiang Liu
2012-04-10 16:01 ` Jiang Liu
2012-05-02 23:55 ` Bjorn Helgaas
2012-05-03 6:39 ` Jiang Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F805B32.1080401@gmail.com \
--to=liuj97@gmail.com \
--cc=izumi.taku@jp.fujitsu.com \
--cc=kaneshige.kenji@jp.fujitsu.com \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.