* [PATCH 2/6] x86: split e820 reserved entries record to late v4 - fix v7
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
@ 2008-09-01 23:37 ` Yinghai Lu
2008-09-01 23:37 ` [PATCH 3/6] x86: unify using pci_mmcfg_insert_resource Yinghai Lu
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yinghai Lu @ 2008-09-01 23:37 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes
Cc: linux-kernel, Yinghai Lu, Linus Torvalds
try to insert_resource second time, by expand the resource...
for case: e820 reserved entry is partially overlapped with bar res...
hope it will never happen
v2: according to Linus, add insert_resource_expand_to_fit, and change
__insert_resource to static without lock
v3: use reserve_region_with_split() instead to hand overlapping
with test case by extend 0xe0000000 - 0xeffffff to 0xdd800000 -
get
e0000000-efffffff : PCI MMCONFIG 0
e0000000-efffffff : reserved
in /proc/iomem
get
found conflict for reserved [dd800000, efffffff], try to reserve with split
__reserve_region_with_split: (PCI Bus #80) [dd000000, ddffffff], res: (reserved) [dd800000, efffffff]
__reserve_region_with_split: (PCI Bus #00) [de000000, dfffffff], res: (reserved) [de000000, efffffff]
initcall pci_subsys_init+0x0/0x121 returned 0 after 381 msecs
in dmesg
v4: take out __insert_resource and insert_resource_expand_to_fit : Linus already check in.
use reserve_region_with_split at the first point
use const char *name
v5: fix checking on overlapping
v6: only reserve common area in conflict
so got sth in /proc/iomem
d8000000-dfffffff : PCI Bus #00
dc000000-dfffffff : GART
dc000000-dfffffff : reserved
e0000000-efffffff : PCI MMCONFIG 0
e0000000-efffffff : reserved
when we have big range in e820
00000000dc000000-00000000f0000000 (reserved)
v7: remove wrong removing of write_unlock(&resource_lock) in adjust_resource()
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
---
arch/x86/kernel/e820.c | 2 -
include/linux/ioport.h | 3 ++
kernel/resource.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
Index: linux-2.6/arch/x86/kernel/e820.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/e820.c
+++ linux-2.6/arch/x86/kernel/e820.c
@@ -1320,7 +1320,7 @@ void __init e820_reserve_resources_late(
res = e820_res;
for (i = 0; i < e820.nr_map; i++) {
if (!res->parent && res->end)
- insert_resource(&iomem_resource, res);
+ reserve_region_with_split(&iomem_resource, res->start, res->end, res->name);
res++;
}
}
Index: linux-2.6/include/linux/ioport.h
===================================================================
--- linux-2.6.orig/include/linux/ioport.h
+++ linux-2.6/include/linux/ioport.h
@@ -108,6 +108,9 @@ extern struct resource iomem_resource;
extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
+extern void reserve_region_with_split(struct resource *root,
+ resource_size_t start, resource_size_t end,
+ const char *name);
extern int insert_resource(struct resource *parent, struct resource *new);
extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new,
Index: linux-2.6/kernel/resource.c
===================================================================
--- linux-2.6.orig/kernel/resource.c
+++ linux-2.6/kernel/resource.c
@@ -516,6 +516,74 @@ int adjust_resource(struct resource *res
return result;
}
+static void __init __reserve_region_with_split(struct resource *root,
+ resource_size_t start, resource_size_t end,
+ const char *name)
+{
+ struct resource *parent = root;
+ struct resource *conflict;
+ struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
+
+ if (!res)
+ return;
+
+ res->name = name;
+ res->start = start;
+ res->end = end;
+ res->flags = IORESOURCE_BUSY;
+
+ for (;;) {
+ conflict = __request_resource(parent, res);
+ if (!conflict)
+ break;
+ if (conflict != parent) {
+ parent = conflict;
+ if (!(conflict->flags & IORESOURCE_BUSY))
+ continue;
+ }
+
+ /* Uhhuh, that didn't work out.. */
+ kfree(res);
+ res = NULL;
+ break;
+ }
+
+ if (!res) {
+ printk(KERN_DEBUG " __reserve_region_with_split: (%s) [%llx, %llx], res: (%s) [%llx, %llx]\n",
+ conflict->name, conflict->start, conflict->end,
+ name, start, end);
+
+ /* failed, split and try again */
+
+ /* conflict coverred whole area */
+ if (conflict->start <= start && conflict->end >= end)
+ return;
+
+ if (conflict->start > start)
+ __reserve_region_with_split(root, start, conflict->start-1, name);
+ if (!(conflict->flags & IORESOURCE_BUSY)) {
+ resource_size_t common_start, common_end;
+
+ common_start = max(conflict->start, start);
+ common_end = min(conflict->end, end);
+ if (common_start < common_end)
+ __reserve_region_with_split(root, common_start, common_end, name);
+ }
+ if (conflict->end < end)
+ __reserve_region_with_split(root, conflict->end+1, end, name);
+ }
+
+}
+
+void reserve_region_with_split(struct resource *root,
+ resource_size_t start, resource_size_t end,
+ const char *name)
+{
+ write_lock(&resource_lock);
+ __reserve_region_with_split(root, start, end, name);
+ write_unlock(&resource_lock);
+}
+
EXPORT_SYMBOL(adjust_resource);
/**
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH 3/6] x86: unify using pci_mmcfg_insert_resource
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
2008-09-01 23:37 ` [PATCH 2/6] x86: split e820 reserved entries record to late v4 - fix v7 Yinghai Lu
@ 2008-09-01 23:37 ` Yinghai Lu
2008-09-01 23:37 ` [PATCH 4/6] x86: delay early cpu initialization until cpuid is done Yinghai Lu
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yinghai Lu @ 2008-09-01 23:37 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes
Cc: linux-kernel, Yinghai Lu
even with known_bridge insert them late too.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Index: linux-2.6/arch/x86/pci/mmconfig-shared.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/mmconfig-shared.c
+++ linux-2.6/arch/x86/pci/mmconfig-shared.c
@@ -209,7 +209,7 @@ static int __init pci_mmcfg_check_hostbr
return name != NULL;
}
-static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
+static void __init pci_mmcfg_insert_resources(void)
{
#define PCI_MMCFG_RESOURCE_NAME_LEN 19
int i;
@@ -233,7 +233,7 @@ static void __init pci_mmcfg_insert_reso
cfg->pci_segment);
res->start = cfg->address;
res->end = res->start + (num_buses << 20) - 1;
- res->flags = IORESOURCE_MEM | resource_flags;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
insert_resource(&iomem_resource, res);
names += PCI_MMCFG_RESOURCE_NAME_LEN;
}
@@ -434,11 +434,9 @@ static void __init __pci_mmcfg_init(int
(pci_mmcfg_config[0].address == 0))
return;
- if (pci_mmcfg_arch_init()) {
- if (known_bridge)
- pci_mmcfg_insert_resources(IORESOURCE_BUSY);
+ if (pci_mmcfg_arch_init())
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
- } else {
+ else {
/*
* Signal not to attempt to insert mmcfg resources because
* the architecture mmcfg setup could not initialize.
@@ -475,7 +473,7 @@ static int __init pci_mmcfg_late_insert_
* marked so it won't cause request errors when __request_region is
* called.
*/
- pci_mmcfg_insert_resources(0);
+ pci_mmcfg_insert_resources();
return 0;
}
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH 4/6] x86: delay early cpu initialization until cpuid is done
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
2008-09-01 23:37 ` [PATCH 2/6] x86: split e820 reserved entries record to late v4 - fix v7 Yinghai Lu
2008-09-01 23:37 ` [PATCH 3/6] x86: unify using pci_mmcfg_insert_resource Yinghai Lu
@ 2008-09-01 23:37 ` Yinghai Lu
2008-09-01 23:37 ` [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx Yinghai Lu
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yinghai Lu @ 2008-09-01 23:37 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes
Cc: linux-kernel, Krzysztof Helt, Yinghai Lu
From: Krzysztof Helt <krzysztof.h1@wp.pl>
Move early cpu initialization after cpu
early get cap so the early cpu initialization
can fix up cpu caps.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d3bc82f..f970cbf 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -335,11 +335,11 @@ static void __init early_cpu_detect(void)
get_cpu_vendor(c, 1);
+ early_get_cap(c);
+
if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
cpu_devs[c->x86_vendor]->c_early_init)
cpu_devs[c->x86_vendor]->c_early_init(c);
-
- early_get_cap(c);
}
/*
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
` (2 preceding siblings ...)
2008-09-01 23:37 ` [PATCH 4/6] x86: delay early cpu initialization until cpuid is done Yinghai Lu
@ 2008-09-01 23:37 ` Yinghai Lu
2008-09-04 19:13 ` Ingo Molnar
2008-09-01 23:37 ` [PATCH 6/6] x86: make (early)_identify_cpu more the same between 32bit and 64 bit Yinghai Lu
2008-09-09 18:45 ` [PATCH 1/6] pci: fix merging left out for BAR print out Jesse Barnes
5 siblings, 1 reply; 11+ messages in thread
From: Yinghai Lu @ 2008-09-01 23:37 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes
Cc: linux-kernel, Yinghai Lu, Krzysztof Helt
Krzysztof Helt <krzysztof.h1@wp.pl> found mtrr is not detected on k6-2
root case:
we move mtrr_bp_init early for mtrr trimming.
and in early_detect, only read cap from cpuid, so some cpu doesn't have
that bit in cpuid and need to set workaround bit will have problem.
need to add early_init_xxxx to preset those bit before mtrr_bp_init
for those earlier cpus.
this patch is for 2.6.27
Reported-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Krzysztof Helt <krzysztof.h1@wp.pl>
---
arch/x86/kernel/cpu/amd.c | 9 +++++----
arch/x86/kernel/cpu/centaur.c | 11 +++++++++++
arch/x86/kernel/cpu/cyrix.c | 32 ++++++++++++++++++++++++++++----
3 files changed, 44 insertions(+), 8 deletions(-)
Index: linux-2.6/arch/x86/kernel/cpu/amd.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/amd.c
+++ linux-2.6/arch/x86/kernel/cpu/amd.c
@@ -31,6 +31,11 @@ static void __cpuinit early_init_amd(str
if (c->x86_power & (1<<8))
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
}
+
+ /* Set MTRR capability flag if appropriate */
+ if (c->x86_model == 13 || c->x86_model == 9 ||
+ (c->x86_model == 8 && c->x86_mask >= 8))
+ set_cpu_cap(c, X86_FEATURE_K6_MTRR);
}
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
@@ -166,10 +171,6 @@ static void __cpuinit init_amd(struct cp
mbytes);
}
- /* Set MTRR capability flag if appropriate */
- if (c->x86_model == 13 || c->x86_model == 9 ||
- (c->x86_model == 8 && c->x86_mask >= 8))
- set_cpu_cap(c, X86_FEATURE_K6_MTRR);
break;
}
Index: linux-2.6/arch/x86/kernel/cpu/centaur.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/centaur.c
+++ linux-2.6/arch/x86/kernel/cpu/centaur.c
@@ -314,6 +314,16 @@ enum {
EAMD3D = 1<<20,
};
+static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
+{
+ switch (c->x86) {
+ case 5:
+ /* Emulate MTRRs using Centaur's MCR. */
+ set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
+ break;
+ }
+}
+
static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
{
@@ -462,6 +472,7 @@ centaur_size_cache(struct cpuinfo_x86 *c
static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
.c_vendor = "Centaur",
.c_ident = { "CentaurHauls" },
+ .c_early_init = early_init_centaur,
.c_init = init_centaur,
.c_size_cache = centaur_size_cache,
};
Index: linux-2.6/arch/x86/kernel/cpu/cyrix.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cyrix.c
+++ linux-2.6/arch/x86/kernel/cpu/cyrix.c
@@ -15,13 +15,11 @@
/*
* Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
*/
-static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void __cpuinit __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
{
unsigned char ccr2, ccr3;
- unsigned long flags;
/* we test for DEVID by checking whether CCR3 is writable */
- local_irq_save(flags);
ccr3 = getCx86(CX86_CCR3);
setCx86(CX86_CCR3, ccr3 ^ 0x80);
getCx86(0xc0); /* dummy to change bus */
@@ -44,9 +42,16 @@ static void __cpuinit do_cyrix_devid(uns
*dir0 = getCx86(CX86_DIR0);
*dir1 = getCx86(CX86_DIR1);
}
- local_irq_restore(flags);
}
+static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __do_cyrix_devid(dir0, dir1);
+ local_irq_restore(flags);
+}
/*
* Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
* order to identify the Cyrix CPU model after we're out of setup.c
@@ -161,6 +166,24 @@ static void __cpuinit geode_configure(vo
local_irq_restore(flags);
}
+static void __cpuinit early_init_cyrix(struct cpuinfo_x86 *c)
+{
+ unsigned char dir0, dir0_msn, dir1 = 0;
+
+ __do_cyrix_devid(&dir0, &dir1);
+ dir0_msn = dir0 >> 4; /* identifies CPU "family" */
+
+ switch (dir0_msn) {
+ case 3: /* 6x86/6x86L */
+ /* Emulate MTRRs using Cyrix's ARRs. */
+ set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
+ break;
+ case 5: /* 6x86MX/M II */
+ /* Emulate MTRRs using Cyrix's ARRs. */
+ set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
+ break;
+ }
+}
static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
{
@@ -416,6 +439,7 @@ static void __cpuinit cyrix_identify(str
static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
.c_vendor = "Cyrix",
.c_ident = { "CyrixInstead" },
+ .c_early_init = early_init_cyrix,
.c_init = init_cyrix,
.c_identify = cyrix_identify,
};
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx
2008-09-01 23:37 ` [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx Yinghai Lu
@ 2008-09-04 19:13 ` Ingo Molnar
2008-09-04 19:17 ` Yinghai Lu
0 siblings, 1 reply; 11+ messages in thread
From: Ingo Molnar @ 2008-09-04 19:13 UTC (permalink / raw)
To: Yinghai Lu
Cc: Thomas Gleixner, H. Peter Anvin, Andrew Morton, Jesse Barnes,
linux-kernel, Krzysztof Helt
* Yinghai Lu <yhlu.kernel@gmail.com> wrote:
> Krzysztof Helt <krzysztof.h1@wp.pl> found mtrr is not detected on k6-2
>
> root case:
> we move mtrr_bp_init early for mtrr trimming.
> and in early_detect, only read cap from cpuid, so some cpu doesn't have
> that bit in cpuid and need to set workaround bit will have problem.
>
> need to add early_init_xxxx to preset those bit before mtrr_bp_init
> for those earlier cpus.
>
> this patch is for 2.6.27
hm, not sure we can do it in v2.6.27 as it depends on the other CPU init
patches and that is a rather sensitive codepath. This problem should be
present in v2.6.26 too, right?
Ingo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx
2008-09-04 19:13 ` Ingo Molnar
@ 2008-09-04 19:17 ` Yinghai Lu
2008-09-04 20:14 ` Krzysztof Helt
0 siblings, 1 reply; 11+ messages in thread
From: Yinghai Lu @ 2008-09-04 19:17 UTC (permalink / raw)
To: Ingo Molnar
Cc: Thomas Gleixner, H. Peter Anvin, Andrew Morton, Jesse Barnes,
linux-kernel, Krzysztof Helt
On Thu, Sep 4, 2008 at 12:13 PM, Ingo Molnar <mingo@elte.hu> wrote:
>
> * Yinghai Lu <yhlu.kernel@gmail.com> wrote:
>
>> Krzysztof Helt <krzysztof.h1@wp.pl> found mtrr is not detected on k6-2
>>
>> root case:
>> we move mtrr_bp_init early for mtrr trimming.
>> and in early_detect, only read cap from cpuid, so some cpu doesn't have
>> that bit in cpuid and need to set workaround bit will have problem.
>>
>> need to add early_init_xxxx to preset those bit before mtrr_bp_init
>> for those earlier cpus.
>>
>> this patch is for 2.6.27
>
> hm, not sure we can do it in v2.6.27 as it depends on the other CPU init
> patches and that is a rather sensitive codepath. This problem should be
> present in v2.6.26 too, right?
Yes. old cpus without cpuid bit for mtrr need this patch...
Krzysztof Helt tested it and it works with 2.6.27-rc5 (?)
YH
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx
2008-09-04 19:17 ` Yinghai Lu
@ 2008-09-04 20:14 ` Krzysztof Helt
2008-09-06 15:51 ` Ingo Molnar
0 siblings, 1 reply; 11+ messages in thread
From: Krzysztof Helt @ 2008-09-04 20:14 UTC (permalink / raw)
To: Yinghai Lu
Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes, linux-kernel, Krzysztof Helt
On Thu, 4 Sep 2008 12:17:14 -0700
"Yinghai Lu" <yhlu.kernel@gmail.com> wrote:
> On Thu, Sep 4, 2008 at 12:13 PM, Ingo Molnar <mingo@elte.hu> wrote:
> >
> > * Yinghai Lu <yhlu.kernel@gmail.com> wrote:
> >
> >> Krzysztof Helt <krzysztof.h1@wp.pl> found mtrr is not detected on k6-2
> >>
> >> root case:
> >> we move mtrr_bp_init early for mtrr trimming.
> >> and in early_detect, only read cap from cpuid, so some cpu doesn't have
> >> that bit in cpuid and need to set workaround bit will have problem.
> >>
> >> need to add early_init_xxxx to preset those bit before mtrr_bp_init
> >> for those earlier cpus.
> >>
> >> this patch is for 2.6.27
> >
> > hm, not sure we can do it in v2.6.27 as it depends on the other CPU init
> > patches and that is a rather sensitive codepath. This problem should be
> > present in v2.6.26 too, right?
>
> Yes. old cpus without cpuid bit for mtrr need this patch...
> Krzysztof Helt tested it and it works with 2.6.27-rc5 (?)
>
>
Yes, I tested the patches with 2.6.27-rc5.
I was too lazy to find the case of this breakage as the mtrr register
detection was "always" displayed during boot on this machine.
I found the source of the breakage now:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=03ae5768b6110ebaa97dc3e7abf1c3d8bec5f874
The early_cpu_init() called directly amd_init_cpu() which set up mtrr flags on K6 cpus.
This got removed by this patch with no replacement. This is dated as 2008-04-17.
As the K6 machine is my secondary computer (to test older stuff, ISA, etc) I do not
boot it every day. Add holidays and it could be that it went unnoticed since April.
I hope this is answer your question. If you want I can retest the 2.6.26 kernel version.
Kind regards,
Krzysztof
----------------------------------------------------------------------
Mobilne aplikacje na Twoj telefon!
Sprawdz >> http://link.interia.pl/f1eff
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx
2008-09-04 20:14 ` Krzysztof Helt
@ 2008-09-06 15:51 ` Ingo Molnar
0 siblings, 0 replies; 11+ messages in thread
From: Ingo Molnar @ 2008-09-06 15:51 UTC (permalink / raw)
To: Krzysztof Helt
Cc: Yinghai Lu, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes, linux-kernel, Krzysztof Helt
* Krzysztof Helt <krzysztof.h1@poczta.fm> wrote:
> On Thu, 4 Sep 2008 12:17:14 -0700
> "Yinghai Lu" <yhlu.kernel@gmail.com> wrote:
>
> > On Thu, Sep 4, 2008 at 12:13 PM, Ingo Molnar <mingo@elte.hu> wrote:
> > >
> > > * Yinghai Lu <yhlu.kernel@gmail.com> wrote:
> > >
> > >> Krzysztof Helt <krzysztof.h1@wp.pl> found mtrr is not detected on k6-2
> > >>
> > >> root case:
> > >> we move mtrr_bp_init early for mtrr trimming.
> > >> and in early_detect, only read cap from cpuid, so some cpu doesn't have
> > >> that bit in cpuid and need to set workaround bit will have problem.
> > >>
> > >> need to add early_init_xxxx to preset those bit before mtrr_bp_init
> > >> for those earlier cpus.
> > >>
> > >> this patch is for 2.6.27
> > >
> > > hm, not sure we can do it in v2.6.27 as it depends on the other CPU init
> > > patches and that is a rather sensitive codepath. This problem should be
> > > present in v2.6.26 too, right?
> >
> > Yes. old cpus without cpuid bit for mtrr need this patch...
> > Krzysztof Helt tested it and it works with 2.6.27-rc5 (?)
> >
> >
>
> Yes, I tested the patches with 2.6.27-rc5.
ok, i've cherry-picked those two commits over into tip/x86/urgent.
Ingo
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 6/6] x86: make (early)_identify_cpu more the same between 32bit and 64 bit
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
` (3 preceding siblings ...)
2008-09-01 23:37 ` [PATCH 5/6] x86: move mtrr cpu cap setting early in early_init_xxxx Yinghai Lu
@ 2008-09-01 23:37 ` Yinghai Lu
2008-09-09 18:45 ` [PATCH 1/6] pci: fix merging left out for BAR print out Jesse Barnes
5 siblings, 0 replies; 11+ messages in thread
From: Yinghai Lu @ 2008-09-01 23:37 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
Jesse Barnes
Cc: linux-kernel, Yinghai Lu
1. add extended_cpuid_level for 32bit
2. add generic_identify for 64bit
3. add early_identify_cpu for 32bit
4. early_identify_cpu not be called by identify_cpu
5. remove early in get_cpu_vendor for 32bit
6. add get_cpu_cap
7. add cpu_detect for 64bit
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/cpu/common.c | 136 ++++++++++++++-------------------------
arch/x86/kernel/cpu/common_64.c | 139 +++++++++++++++++++++++++---------------
include/asm-x86/processor.h | 2
3 files changed, 141 insertions(+), 136 deletions(-)
Index: linux-2.6/arch/x86/kernel/cpu/common.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/common.c
+++ linux-2.6/arch/x86/kernel/cpu/common.c
@@ -96,7 +96,7 @@ int __cpuinit get_model_name(struct cpui
unsigned int *v;
char *p, *q;
- if (cpuid_eax(0x80000000) < 0x80000004)
+ if (c->extended_cpuid_level < 0x80000004)
return 0;
v = (unsigned int *) c->x86_model_id;
@@ -125,7 +125,7 @@ void __cpuinit display_cacheinfo(struct
{
unsigned int n, dummy, ecx, edx, l2size;
- n = cpuid_eax(0x80000000);
+ n = c->extended_cpuid_level;
if (n >= 0x80000005) {
cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
@@ -186,7 +186,7 @@ static char __cpuinit *table_lookup_mode
}
-static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
+static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
{
char *v = c->x86_vendor_id;
int i;
@@ -198,8 +198,7 @@ static void __cpuinit get_cpu_vendor(str
(cpu_devs[i]->c_ident[1] &&
!strcmp(v, cpu_devs[i]->c_ident[1]))) {
c->x86_vendor = i;
- if (!early)
- this_cpu = cpu_devs[i];
+ this_cpu = cpu_devs[i];
return;
}
}
@@ -284,34 +283,30 @@ void __init cpu_detect(struct cpuinfo_x8
}
}
}
-static void __cpuinit early_get_cap(struct cpuinfo_x86 *c)
+
+static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
{
u32 tfms, xlvl;
- unsigned int ebx;
+ u32 ebx;
- memset(&c->x86_capability, 0, sizeof c->x86_capability);
- if (have_cpuid_p()) {
- /* Intel-defined flags: level 0x00000001 */
- if (c->cpuid_level >= 0x00000001) {
- u32 capability, excap;
- cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
- c->x86_capability[0] = capability;
- c->x86_capability[4] = excap;
- }
+ /* Intel-defined flags: level 0x00000001 */
+ if (c->cpuid_level >= 0x00000001) {
+ u32 capability, excap;
+ cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
+ c->x86_capability[0] = capability;
+ c->x86_capability[4] = excap;
+ }
- /* AMD-defined flags: level 0x80000001 */
- xlvl = cpuid_eax(0x80000000);
- if ((xlvl & 0xffff0000) == 0x80000000) {
- if (xlvl >= 0x80000001) {
- c->x86_capability[1] = cpuid_edx(0x80000001);
- c->x86_capability[6] = cpuid_ecx(0x80000001);
- }
+ /* AMD-defined flags: level 0x80000001 */
+ xlvl = cpuid_eax(0x80000000);
+ c->extended_cpuid_level = xlvl;
+ if ((xlvl & 0xffff0000) == 0x80000000) {
+ if (xlvl >= 0x80000001) {
+ c->x86_capability[1] = cpuid_edx(0x80000001);
+ c->x86_capability[6] = cpuid_ecx(0x80000001);
}
-
}
-
}
-
/*
* Do minimum CPU detection early.
* Fields really needed: vendor, cpuid_level, family, model, mask,
@@ -321,25 +316,29 @@ static void __cpuinit early_get_cap(stru
* WARNING: this function is only called on the BP. Don't add code here
* that is supposed to run on all CPUs.
*/
-static void __init early_cpu_detect(void)
+static void __init early_identify_cpu(struct cpuinfo_x86 *c)
{
- struct cpuinfo_x86 *c = &boot_cpu_data;
-
c->x86_cache_alignment = 32;
c->x86_clflush_size = 32;
if (!have_cpuid_p())
return;
+ c->extended_cpuid_level = 0;
+
+ memset(&c->x86_capability, 0, sizeof c->x86_capability);
+
cpu_detect(c);
- get_cpu_vendor(c, 1);
+ get_cpu_vendor(c);
- early_get_cap(c);
+ get_cpu_cap(c);
if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
cpu_devs[c->x86_vendor]->c_early_init)
cpu_devs[c->x86_vendor]->c_early_init(c);
+
+ validate_pat_support(c);
}
/*
@@ -373,60 +372,32 @@ static void __cpuinit detect_nopl(struct
static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
{
- u32 tfms, xlvl;
- unsigned int ebx;
+ if (!have_cpuid_p())
+ return;
+
+ c->extended_cpuid_level = 0;
+
+ cpu_detect(c);
+
+ get_cpu_vendor(c);
+
+ get_cpu_cap(c);
- if (have_cpuid_p()) {
- /* Get vendor name */
- cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
- (unsigned int *)&c->x86_vendor_id[0],
- (unsigned int *)&c->x86_vendor_id[8],
- (unsigned int *)&c->x86_vendor_id[4]);
-
- get_cpu_vendor(c, 0);
- /* Initialize the standard set of capabilities */
- /* Note that the vendor-specific code below might override */
- /* Intel-defined flags: level 0x00000001 */
- if (c->cpuid_level >= 0x00000001) {
- u32 capability, excap;
- cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
- c->x86_capability[0] = capability;
- c->x86_capability[4] = excap;
- c->x86 = (tfms >> 8) & 15;
- c->x86_model = (tfms >> 4) & 15;
- if (c->x86 == 0xf)
- c->x86 += (tfms >> 20) & 0xff;
- if (c->x86 >= 0x6)
- c->x86_model += ((tfms >> 16) & 0xF) << 4;
- c->x86_mask = tfms & 15;
- c->initial_apicid = (ebx >> 24) & 0xFF;
+ if (c->cpuid_level >= 0x00000001) {
+ c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
#ifdef CONFIG_X86_HT
- c->apicid = phys_pkg_id(c->initial_apicid, 0);
- c->phys_proc_id = c->initial_apicid;
+ c->apicid = phys_pkg_id(c->initial_apicid, 0);
+ c->phys_proc_id = c->initial_apicid;
#else
- c->apicid = c->initial_apicid;
+ c->apicid = c->initial_apicid;
#endif
- if (test_cpu_cap(c, X86_FEATURE_CLFLSH))
- c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8;
- } else {
- /* Have CPUID level 0 only - unheard of */
- c->x86 = 4;
- }
+ }
- /* AMD-defined flags: level 0x80000001 */
- xlvl = cpuid_eax(0x80000000);
- if ((xlvl & 0xffff0000) == 0x80000000) {
- if (xlvl >= 0x80000001) {
- c->x86_capability[1] = cpuid_edx(0x80000001);
- c->x86_capability[6] = cpuid_ecx(0x80000001);
- }
- if (xlvl >= 0x80000004)
- get_model_name(c); /* Default name */
- }
+ if (c->extended_cpuid_level >= 0x80000004)
+ get_model_name(c); /* Default name */
- init_scattered_cpuid_features(c);
- detect_nopl(c);
- }
+ init_scattered_cpuid_features(c);
+ detect_nopl(c);
}
static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
@@ -651,13 +622,10 @@ void __init early_cpu_init(void)
{
struct cpu_vendor_dev *cvdev;
- for (cvdev = __x86cpuvendor_start ;
- cvdev < __x86cpuvendor_end ;
- cvdev++)
+ for (cvdev = __x86cpuvendor_start; cvdev < __x86cpuvendor_end; cvdev++)
cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
- early_cpu_detect();
- validate_pat_support(&boot_cpu_data);
+ early_identify_cpu(&boot_cpu_data);
}
/* Make sure %fs is initialized properly in idle threads */
Index: linux-2.6/arch/x86/kernel/cpu/common_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/common_64.c
+++ linux-2.6/arch/x86/kernel/cpu/common_64.c
@@ -198,6 +198,7 @@ static void __cpuinit get_cpu_vendor(str
printk(KERN_ERR "CPU: Your system may be unstable.\n");
}
c->x86_vendor = X86_VENDOR_UNKNOWN;
+ this_cpu = &default_cpu;
}
static void __init early_cpu_support_print(void)
@@ -252,56 +253,18 @@ static void __cpuinit detect_nopl(struct
}
}
-static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
-
-void __init early_cpu_init(void)
+void __cpuinit cpu_detect(struct cpuinfo_x86 *c)
{
- struct cpu_vendor_dev *cvdev;
-
- for (cvdev = __x86cpuvendor_start ;
- cvdev < __x86cpuvendor_end ;
- cvdev++)
- cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
- early_cpu_support_print();
- early_identify_cpu(&boot_cpu_data);
-}
-
-/* Do some early cpuid on the boot CPU to get some parameter that are
- needed before check_bugs. Everything advanced is in identify_cpu
- below. */
-static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
-{
- u32 tfms, xlvl;
-
- c->loops_per_jiffy = loops_per_jiffy;
- c->x86_cache_size = -1;
- c->x86_vendor = X86_VENDOR_UNKNOWN;
- c->x86_model = c->x86_mask = 0; /* So far unknown... */
- c->x86_vendor_id[0] = '\0'; /* Unset */
- c->x86_model_id[0] = '\0'; /* Unset */
- c->x86_clflush_size = 64;
- c->x86_cache_alignment = c->x86_clflush_size;
- c->x86_max_cores = 1;
- c->x86_coreid_bits = 0;
- c->extended_cpuid_level = 0;
- memset(&c->x86_capability, 0, sizeof c->x86_capability);
-
/* Get vendor name */
cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
(unsigned int *)&c->x86_vendor_id[0],
(unsigned int *)&c->x86_vendor_id[8],
(unsigned int *)&c->x86_vendor_id[4]);
- get_cpu_vendor(c);
-
- /* Initialize the standard set of capabilities */
- /* Note that the vendor-specific code below might override */
-
/* Intel-defined flags: level 0x00000001 */
if (c->cpuid_level >= 0x00000001) {
- __u32 misc;
- cpuid(0x00000001, &tfms, &misc, &c->x86_capability[4],
- &c->x86_capability[0]);
+ u32 junk, tfms, cap0, misc;
+ cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
c->x86 = (tfms >> 8) & 0xf;
c->x86_model = (tfms >> 4) & 0xf;
c->x86_mask = tfms & 0xf;
@@ -309,17 +272,32 @@ static void __cpuinit early_identify_cpu
c->x86 += (tfms >> 20) & 0xff;
if (c->x86 >= 0x6)
c->x86_model += ((tfms >> 16) & 0xF) << 4;
- if (test_cpu_cap(c, X86_FEATURE_CLFLSH))
+ if (cap0 & (1<<19))
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
} else {
/* Have CPUID level 0 only - unheard of */
c->x86 = 4;
}
+}
+
+
+static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+{
+ u32 tfms, xlvl;
+ u32 ebx;
+
+ /* Initialize the standard set of capabilities */
+ /* Note that the vendor-specific code below might override */
+
+ /* Intel-defined flags: level 0x00000001 */
+ if (c->cpuid_level >= 0x00000001) {
+ u32 capability, excap;
+
+ cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
+ c->x86_capability[0] = capability;
+ c->x86_capability[4] = excap;
+ }
- c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xff;
-#ifdef CONFIG_SMP
- c->phys_proc_id = c->initial_apicid;
-#endif
/* AMD-defined flags: level 0x80000001 */
xlvl = cpuid_eax(0x80000000);
c->extended_cpuid_level = xlvl;
@@ -328,8 +306,6 @@ static void __cpuinit early_identify_cpu
c->x86_capability[1] = cpuid_edx(0x80000001);
c->x86_capability[6] = cpuid_ecx(0x80000001);
}
- if (xlvl >= 0x80000004)
- get_model_name(c); /* Default name */
}
/* Transmeta-defined flags: level 0x80860001 */
@@ -349,8 +325,26 @@ static void __cpuinit early_identify_cpu
c->x86_virt_bits = (eax >> 8) & 0xff;
c->x86_phys_bits = eax & 0xff;
}
+}
- detect_nopl(c);
+/* Do some early cpuid on the boot CPU to get some parameter that are
+ needed before check_bugs. Everything advanced is in identify_cpu
+ below. */
+static void __init early_identify_cpu(struct cpuinfo_x86 *c)
+{
+
+ c->x86_clflush_size = 64;
+ c->x86_cache_alignment = c->x86_clflush_size;
+
+ memset(&c->x86_capability, 0, sizeof c->x86_capability);
+
+ c->extended_cpuid_level = 0;
+
+ cpu_detect(c);
+
+ get_cpu_vendor(c);
+
+ get_cpu_cap(c);
if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
cpu_devs[c->x86_vendor]->c_early_init)
@@ -359,6 +353,39 @@ static void __cpuinit early_identify_cpu
validate_pat_support(c);
}
+void __init early_cpu_init(void)
+{
+ struct cpu_vendor_dev *cvdev;
+
+ for (cvdev = __x86cpuvendor_start; cvdev < __x86cpuvendor_end; cvdev++)
+ cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
+
+ early_cpu_support_print();
+ early_identify_cpu(&boot_cpu_data);
+}
+
+static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
+{
+ c->extended_cpuid_level = 0;
+
+ cpu_detect(c);
+
+ get_cpu_vendor(c);
+
+ get_cpu_cap(c);
+
+ c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xff;
+#ifdef CONFIG_SMP
+ c->phys_proc_id = c->initial_apicid;
+#endif
+
+ if (c->extended_cpuid_level >= 0x80000004)
+ get_model_name(c); /* Default name */
+
+ init_scattered_cpuid_features(c);
+ detect_nopl(c);
+}
+
/*
* This does the hard work of actually picking apart the CPU stuff...
*/
@@ -366,9 +393,19 @@ static void __cpuinit identify_cpu(struc
{
int i;
- early_identify_cpu(c);
+ c->loops_per_jiffy = loops_per_jiffy;
+ c->x86_cache_size = -1;
+ c->x86_vendor = X86_VENDOR_UNKNOWN;
+ c->x86_model = c->x86_mask = 0; /* So far unknown... */
+ c->x86_vendor_id[0] = '\0'; /* Unset */
+ c->x86_model_id[0] = '\0'; /* Unset */
+ c->x86_clflush_size = 64;
+ c->x86_cache_alignment = c->x86_clflush_size;
+ c->x86_max_cores = 1;
+ c->x86_coreid_bits = 0;
+ memset(&c->x86_capability, 0, sizeof c->x86_capability);
- init_scattered_cpuid_features(c);
+ generic_identify(c);
c->apicid = phys_pkg_id(0);
Index: linux-2.6/include/asm-x86/processor.h
===================================================================
--- linux-2.6.orig/include/asm-x86/processor.h
+++ linux-2.6/include/asm-x86/processor.h
@@ -78,9 +78,9 @@ struct cpuinfo_x86 {
__u8 x86_phys_bits;
/* CPUID returned core id bits: */
__u8 x86_coreid_bits;
+#endif
/* Max extended CPUID function supported: */
__u32 extended_cpuid_level;
-#endif
/* Maximum supported CPUID level, -1=no CPUID: */
int cpuid_level;
__u32 x86_capability[NCAPINTS];
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 1/6] pci: fix merging left out for BAR print out
2008-09-01 23:37 [PATCH 1/6] pci: fix merging left out for BAR print out Yinghai Lu
` (4 preceding siblings ...)
2008-09-01 23:37 ` [PATCH 6/6] x86: make (early)_identify_cpu more the same between 32bit and 64 bit Yinghai Lu
@ 2008-09-09 18:45 ` Jesse Barnes
5 siblings, 0 replies; 11+ messages in thread
From: Jesse Barnes @ 2008-09-09 18:45 UTC (permalink / raw)
To: Yinghai Lu
Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
linux-kernel
On Monday, September 01, 2008 4:37 pm Yinghai Lu wrote:
> print out for Device BAR address before kernel try to update them.
>
> also change it to KERN_DEBUG instead...
>
> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Can you resend this against my linux-next branch? It didn't apply to my
latest bits...
Thanks,
Jesse
^ permalink raw reply [flat|nested] 11+ messages in thread