x86: MMCONF enable MCFG early
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 2/2 x86: MMCONF enable MCFG early
[PATCH] x86: MMCONF enable MCFG early
patch
x86: validate against ACPI motherboard resources
changed the mmconf init sequence, and init MMCONF late in acpi_init.
here change it back to old sequence
1. check hostbridge in early
2. check MCFG with e820 in early
3. if all fail, will check MCFg with acpi _CRS in acpi_init
So we can make MCONF working again when acpi=off is set if hostbridge support that.
arch/x86/pci/mmconfig-shared.c +61 -45
@@ -274,7 +274,7 @@ static int __init is_acpi_reserved(unsigreturn mcfg_res.flags; } -static void __init pci_mmcfg_reject_broken (void ) +static void __init pci_mmcfg_reject_broken (int type,int early) {typeof (pci_mmcfg_config[0 ]) *cfg;int i;
@@ -299,34 +299,43 @@ static void __init pci_mmcfg_reject_brok }for (i =0 ; i < pci_mmcfg_config_num; i++) { +int valid =0 ;u32 size = (cfg->end_bus_number +1 ) <<20 ; cfg = &pci_mmcfg_config[i]; -printk (KERN_NOTICE "PCI: MCFG configuration %d: base %lu " +printk (KERN_NOTICE "PCI: MCFG configuration %d: base %lx " "segment %hu buses %u - %u\n" , i, (unsigned long )cfg->address, cfg->pci_segment, (unsigned int )cfg->start_bus_number, (unsigned int )cfg->end_bus_number); + +if (!early)if (is_acpi_reserved (cfg->address, cfg->address + size -1 )) {printk (KERN_NOTICE "PCI: MCFG area at %Lx reserved " "in ACPI motherboard resources\n" , cfg->address); - }else { + valid =1 ; + } + +if (valid) +continue ; + +if (!early)printk (KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" " reserved in ACPI motherboard resources\n" , cfg->address); -/* Don't try to do this check unless configuration -type 1 is available. */ -if ((pci_probe &PCI_PROBE_CONF1 ) && -e820_all_mapped (cfg->address, - cfg->address + size -1 , -E820_RESERVED )) -printk (KERN_NOTICE -"PCI: MCFG area at %Lx reserved in " -"E820\n" , - cfg->address); -else - goto reject; +/* Don't try to do this check unless configuration +type 1 is available. */ +if (type ==1 &&e820_all_mapped (cfg->address, + cfg->address + size -1 , +E820_RESERVED )) { +printk (KERN_NOTICE +"PCI: MCFG area at %Lx reserved in E820\n" , + cfg->address); + valid =1 ; } + +if (!valid) + goto reject; }return ;
@@ -339,46 +348,37 @@ reject: pci_mmcfg_config_num =0 ; } -void __init pci_mmcfg_early_init (int type) -{ -if ((pci_probe &PCI_PROBE_MMCONF ) ==0 ) -return ; - -/* If type 1 access is available, no need to enable MMCONFIG yet, we can -defer until later when the ACPI interpreter is available to better -validate things. */ -if (type ==1 ) -return ; - -acpi_table_parse (ACPI_SIG_MCFG , acpi_parse_mcfg); - -if ((pci_mmcfg_config_num ==0 ) || - (pci_mmcfg_config ==NULL ) || - (pci_mmcfg_config[0 ].address ==0 )) -return ; - -if (pci_mmcfg_arch_init ()) - pci_probe = (pci_probe & ~PCI_PROBE_MASK ) |PCI_PROBE_MMCONF ; -} +static int __initdata known_bridge; -void __init pci_mmcfg_late_init (void ) +void __init __pci_mmcfg_init (int type,int early) { -int known_bridge =0 ; -/* MMCONFIG disabled */ if ((pci_probe &PCI_PROBE_MMCONF ) ==0 )return ;/* MMCONFIG already enabled */ +if (!early)if (!(pci_probe &PCI_PROBE_MASK & ~PCI_PROBE_MMCONF ))return ; -if ((pci_probe &PCI_PROBE_CONF1 ) &&pci_mmcfg_check_hostbridge ()) - known_bridge =1 ; -else -acpi_table_parse (ACPI_SIG_MCFG , acpi_parse_mcfg); +/* for late to exit */ +if (known_bridge) +return ; -pci_mmcfg_reject_broken (); +if (early && type ==1 ) { +if (pci_mmcfg_check_hostbridge ()) + known_bridge =1 ; +#if 0 +/* check e820 in late? */ + else + return; +#endif + } + +if (!known_bridge) { +acpi_table_parse (ACPI_SIG_MCFG , acpi_parse_mcfg); +pci_mmcfg_reject_broken (type, early); + } if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) ||
@@ -386,10 +386,11 @@ void __init pci_mmcfg_late_init(void)return ;if (pci_mmcfg_arch_init ()) { -if (pci_probe &PCI_PROBE_CONF1 ) +if (type ==1 )unreachable_devices ();if (known_bridge)pci_mmcfg_insert_resources (IORESOURCE_BUSY ); + pci_probe = (pci_probe & ~PCI_PROBE_MASK ) |PCI_PROBE_MMCONF ; }else {/*
@@ -400,6 +401,21 @@ void __init pci_mmcfg_late_init(void) } } +void __init pci_mmcfg_early_init (int type) +{ +__pci_mmcfg_init (type,1 ); +} + +void __init pci_mmcfg_late_init (void ) +{ +int type =0 ; + +if (pci_probe &PCI_PROBE_CONF1 ) + type =1 ; + +__pci_mmcfg_init (type,0 ); +} +static int __init pci_mmcfg_late_insert_resources (void ) {/*
Quoted 5 lines · Yinghai Lu
[PATCH] x86: MMCONF enable MCFG early
patch
x86: validate against ACPI motherboard resources
Quoted 9 lines
changed the mmconf init sequence, and init MMCONF late in
acpi_init.here change it back to old sequence
1. check hostbridge in early
2. check MCFG with e820 in early
3. if all fail, will check MCFg with acpi_CRSinacpi_initSo we can make MCONF working again when acpi=off is set if hostbridge support that.
Ingo,
it seems you removed
Quoted 2 lines
patch
x86: validate against ACPI motherboard resources
last night.
was it dropped?
YH
Quoted 7 lines · Yinghai Lu
Ingo,
it seems you removedQuoted 2 lines
patch
x86: validate against ACPI motherboard resourceslast night.
was it dropped?
yeah, i bounced it over to Greg - but Greg has not indicated it yet whether he has picked it up. Andrew has it in -rc8-mm1 at the moment.
Ingo
Quoted 10 lines · Ingo Molnar
Quoted 7 lines
Ingo,
it seems you removedQuoted 2 lines
patch
x86: validate against ACPI motherboard resourceslast night.
was it dropped?
yeah, i bounced it over to Greg - but Greg has not indicated it yet whether he has picked it up. Andrew has it in -rc8-mm1 at the moment.
so these two patches of yours:
Subject: [PATCH 1/2] x86: clear pci_mmcfg_virt when mmcfg get rejected
Subject: [PATCH 2/2] x86: MMCONF enable MCFG early
should probably go to Andrew/Greg as well.
Ingo
Quoted 14 lines · Ingo Molnar
Quoted 10 lines · Ingo Molnar
Quoted 7 lines
Ingo,
it seems you removedQuoted 2 lines
patch
x86: validate against ACPI motherboard resourceslast night.
was it dropped?
yeah, i bounced it over to Greg - but Greg has not indicated it yet whether he has picked it up. Andrew has it in -rc8-mm1 at the moment.
Quoted 6 lines
so these two patches of yours:
Subject: [PATCH 1/2] x86: clear
pci_mmcfg_virtwhen mmcfg get rejected
Subject: [PATCH 2/2] x86: MMCONF enable MCFG earlyshould probably go to Andrew/Greg as well.
Andrew,
can you pick them up? or need me to resend that to you again.
Thanks
YH
Quoted 20 lines · On Wed, 16 Jan 2008 14:09:02 -0800 Yinghai Lu <[email protected]> wrote:
[PATCH] x86: MMCONF enable MCFG early
patch
x86: validate against ACPI motherboard resourceschanged the mmconf init sequence, and init MMCONF late in
acpi_init.here change it back to old sequence
1. check hostbridge in early
2. check MCFG with e820 in early
3. if all fail, will check MCFg with acpi_CRSinacpi_initSo we can make MCONF working again when acpi=off is set if hostbridge support that.
...
(quoted diff) +1
-0+ printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " "segment %hu buses %u - %u\n", i, (unsigned long)cfg->address, cfg->pci_segment, (unsigned int)cfg->start_bus_number,
Review
Quoted 10 lines
(quoted diff) +4
-1(unsigned int)cfg->end_bus_number); + + if (!early) if (is_acpi_reserved(cfg->address, cfg->address + size - 1)) { printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved " "in ACPI motherboard resources\n", cfg->address); - } else { + valid = 1; + }
grumble. Please don't mess up the kernel source like that.
Quoted 4 lines
(quoted diff) +1
-1-void __init pci_mmcfg_late_init(void) +void __init __pci_mmcfg_init(int type, int early) {
Review
Quoted 10 lines
(quoted diff) +1
-2- int known_bridge = 0; - /* MMCONFIG disabled */ if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; /* MMCONFIG already enabled */ + if (!early) if (!(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF)) return;
and that. Do it properly.
arch/x86/pci/mmconfig-shared.c renamed from arch/x86/pci/mmconfig-shared.c~x86-mmconf-enable-mcfg-early-cleanup +3 -4
@@ -308,8 +308,8 @@ static void __init pci_mmcfg_reject_brok (unsigned int )cfg->start_bus_number, (unsigned int)cfg->end_bus_number); -if (!early) -if (is_acpi_reserved (cfg->address, cfg->address + size -1 )) { +if (!early && +is_acpi_reserved (cfg->address, cfg->address + size -1 )) {printk (KERN_NOTICE "PCI: MCFG area at %Lx reserved " "in ACPI motherboard resources\n" , cfg->address);
@@ -357,8 +357,7 @@ void __init __pci_mmcfg_init(int type, ireturn ;/* MMCONFIG already enabled */ -if (!early) -if (!(pci_probe &PCI_PROBE_MASK & ~PCI_PROBE_MMCONF )) +if (!early && !(pci_probe &PCI_PROBE_MASK & ~PCI_PROBE_MMCONF ))return ;/* for late to exit */
_
PATCH 1/2 x86: clear pci_mmcfg_virt when mmcfg get rejected
In reply to a message not in the archive[PATCH] x86: clear pci_mmcfg_virt when mmcfg get rejected
for x86_64, need to free pci_mmcfg_virt, and iounmap some pointers when MMCONF is not reserved in E820 or acpi _CRS and get rejected
arch/x86/pci/mmconfig-shared.c +1 -0
@@ -333,6 +333,7 @@ static void __init pci_mmcfg_reject_brok reject:printk (KERN_ERR "PCI: Not using MMCONFIG.\n" ); +pci_mmcfg_arch_free ();kfree (pci_mmcfg_config); pci_mmcfg_config =NULL ; pci_mmcfg_config_num =0 ;
arch/x86/pci/mmconfig_32.c +4 -0
@@ -146,3 +146,7 @@ int __init pci_mmcfg_arch_init(void) raw_pci_ops = &pci_mmcfg;return 1 ; } + +void __init pci_mmcfg_arch_free (void ) +{ +}
arch/x86/pci/mmconfig_64.c +21 -1
@@ -135,7 +135,7 @@ int __init pci_mmcfg_arch_reachable(unsiint __init pci_mmcfg_arch_init (void ) {int i; - pci_mmcfg_virt =kmalloc (sizeof (*pci_mmcfg_virt) * + pci_mmcfg_virt =kzalloc (sizeof (*pci_mmcfg_virt) * pci_mmcfg_config_num,GFP_KERNEL );if (pci_mmcfg_virt ==NULL ) {printk (KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n" );
@@ -149,9 +149,29 @@ int __init pci_mmcfg_arch_init(void)printk (KERN_ERR "PCI: Cannot map mmconfig aperture for " "segment %d\n" , pci_mmcfg_config[i].pci_segment); +pci_mmcfg_arch_free ();return 0 ; } } raw_pci_ops = &pci_mmcfg;return 1 ; } + +void __init pci_mmcfg_arch_free (void ) +{ +int i; + +if (pci_mmcfg_virt ==NULL ) +return ; + +for (i =0 ; i < pci_mmcfg_config_num; ++i) { +if (pci_mmcfg_virt[i].virt) { +iounmap (pci_mmcfg_virt[i].virt); + pci_mmcfg_virt[i].virt =NULL ; + pci_mmcfg_virt[i].cfg =NULL ; + } + } + +kfree (pci_mmcfg_virt); + pci_mmcfg_virt =NULL ; +}
arch/x86/pci/pci.h +1 -0
@@ -105,6 +105,7 @@ extern DECLARE_BITMAP(pci_mmcfg_fallbackextern int __init pci_mmcfg_arch_reachable (unsigned int seg,unsigned int bus,unsigned int devfn);extern int __init pci_mmcfg_arch_init (void ); +extern void __init pci_mmcfg_arch_free (void );/* * AMD Fam10h CPUs are buggy, and cannot access MMIO config space