NetBSD Problem Report #38480
From tls@rek.tjls.com Mon Apr 21 18:50:15 2008
Return-Path: <tls@rek.tjls.com>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by narn.NetBSD.org (Postfix) with ESMTP id 71E1863B293
for <gnats-bugs@gnats.NetBSD.org>; Mon, 21 Apr 2008 18:50:15 +0000 (UTC)
Message-Id: <20080421184833.2FCDD49ABF@claw.hvg.tjls.com>
Date: Mon, 21 Apr 2008 14:48:33 -0400 (EDT)
From: tls@NetBSD.ORG
Reply-To: tls@NetBSD.oRG
To: gnats-bugs@gnats.NetBSD.org
Subject: x86 MTRR code makes invalid assumption of 8 variable MTRRs
X-Send-Pr-Version: 3.95
>Number: 38480
>Category: port-amd64
>Synopsis: x86 MTRR code makes invalid assumption of 8 variable MTRRs
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: port-amd64-maintainer
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Apr 21 18:55:00 +0000 2008
>Closed-Date: Fri Nov 06 22:44:02 +0000 2009
>Last-Modified: Thu Jun 06 07:15:01 +0000 2013
>Originator: tls@NetBSD.oRG
>Release: NetBSD 4.99.58
>Organization:
The NetBSD Foundation
>Environment:
System: NetBSD claw 4.99.58 NetBSD 4.99.58 (GENERIC) #1: Wed Apr 9 01:06:27 EDT 2008 tls@claw:/usr/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
On a 2 socket SuperMicro X7DCL motherboard with two 4-core Xeon E5405
processors, an amd64 INSTALL or GENERIC kernel panics in cpu_init
for the boot processor. This panic occurs because it receives a
protection fault on the rdmsr() for the 8th variable MTRR for the
CPU; this fault is not handled, though rdmsr() is defined to give
a protection fault on any attempt to read an invalid MSR.
It appears that on this CPU, as configured by this motherboard's
BIOS, only 7 (not 8) variable MTRRs can be used by the OS (at
least in 64 bit mode, possibly in 32 bit mode as well). Supposedly
this CPU family has a new (third?) MTRR type available which may,
though the BIOS has been configured to disable it, be what is
consuming the last variable MTRR.
Evidently, though all prior Intel CPUs have actually had 8 MTRRs
and some other manufacturers' CPU families are defined to have 8
MTRRs (e.g. VIA/Centaur), Intel has never specified that 8 MTRRs
will be present. Rather, the OS is supposed to read the MTRR
config register and mask the returned value with 0xff to obtain
the number of variable-size MTRRs available for use.
We can't do this because we use fixed size arrays to index the
hardware MTRRs. We need to adjust that. Also, Linux code seems
to believe that AMD CPUs have only 2 variable MTRRs but I think
this actually applies only to K6 generation CPUs and is already
handled by our i386 specific MTRR code.
If I knew how to find the fixed MTRRs with an arbitrary number of
variable MTRRs present, I think this would be a reasonably simple
fix -- but I don't know that and don't have time to find the
right Intel document today, thus this PR. If someone else has
it handy, I can provide access to my system which exhibits this
problem for quick testing.
>How-To-Repeat:
Try to boot a NetBSD/amd64 kernel on a SuperMicro X7DCL-3 or
X7DCL-I motherboard with BIOS revision 1.0 and two Intel Xeon
E5405 2.0GHz quad-core processors. Boom.
>Fix:
Removing options MTRR from the kernel config leaves the system
working reasonably well, though I doubt it'd make X happy (I
could care less about X).
>Release-Note:
>Audit-Trail:
From: Thor Lancelot Simon <tls@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/38480 CVS commit: src/sys/arch/amd64
Date: Mon, 21 Apr 2008 19:06:43 +0000 (UTC)
Module Name: src
Committed By: tls
Date: Mon Apr 21 19:06:43 UTC 2008
Modified Files:
src/sys/arch/amd64/amd64: netbsd32_machdep.c
src/sys/arch/amd64/conf: INSTALL
Log Message:
Work around PR38480 by making it possible to omit options MTRR from
amd64 INSTALL kernels -- and doing so. At least you can now get an
INSTALL kernel onto a box with this odd MTRR configuration to debug it.
To generate a diff of this commit:
cvs rdiff -r1.48 -r1.49 src/sys/arch/amd64/amd64/netbsd32_machdep.c
cvs rdiff -r1.78 -r1.79 src/sys/arch/amd64/conf/INSTALL
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-amd64/38480: x86 MTRR code makes invalid assumption of 8 variable MTRRs
Date: Tue, 22 Apr 2008 20:47:11 +0100
On Mon, Apr 21, 2008 at 06:55:00PM +0000, tls@NetBSD.ORG wrote:
> will be present. Rather, the OS is supposed to read the MTRR
> config register and mask the returned value with 0xff to obtain
> the number of variable-size MTRRs available for use.
Do you have a reference for that?
Andrew
From: Thor Lancelot Simon <tls@rek.tjls.com>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-amd64/38480: x86 MTRR code makes invalid assumption of 8 variable MTRRs
Date: Tue, 22 Apr 2008 16:03:07 -0400
On Tue, Apr 22, 2008 at 07:50:02PM +0000, Andrew Doran wrote:
>
> > will be present. Rather, the OS is supposed to read the MTRR
> > config register and mask the returned value with 0xff to obtain
> > the number of variable-size MTRRs available for use.
>
> Do you have a reference for that?
At this point, allow me to lamely indicate that it's what the Linux code,
which works on this platform, does... but I did find a reference to it
in an Intel document yesterday -- I'll try to find it again.
From: Thor Lancelot Simon <tls@rek.tjls.com>
To: gnats-bugs@NetBSD.org
Cc: port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, tls@NetBSD.ORG, ad@netbsd.org
Subject: Re: port-amd64/38480: x86 MTRR code makes invalid assumption of 8 variable MTRRs
Date: Sat, 26 Apr 2008 10:05:51 -0400
On Tue, Apr 22, 2008 at 07:50:02PM +0000, Andrew Doran wrote:
>
> Do you have a reference for that?
http://lkml.org/lkml/2005/9/28/323 refers to two Intel "Specification
Updates", 30240216 for 64-bit mode and 30235221 for 32-bit mode, but
I can't seem to fetch them from Intel's site right now.
--
Thor Lancelot Simon tls@rek.tjls.com
"The inconsistency is startling, though admittedly, if consistency is to
be abandoned or transcended, there is no problem." - Noam Chomsky
From: Thor Lancelot Simon <tls@rek.tjls.com>
To: gnats-bugs@NetBSD.org
Cc: port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, tls@NetBSD.ORG, ad@netbsd.org
Subject: Re: port-amd64/38480: x86 MTRR code makes invalid assumption of 8 variable MTRRs
Date: Sat, 26 Apr 2008 11:02:26 -0400
This is -- obliquely -- described in the architecture manual, part 3A,
(Intel document 253668) chapter 10, section 10.11. This section has
clearly been repeatedly revised -- it's got typos, and references to
it in other parts of the document sometimes get the section number
wrong...
Now, watch out! Evidently, newer processors -- such as the one I have --
are not really, quite, "Pentium 4, Intel Xeon, and P6 family processors"
in this regard, as you might guess from the fact that many other datasheets
and spec updates on the Intel site break out the Core and subsequent
processors separately (e.g. there's a whole separate set of spec updates
for "800 Mhz bus Xeon" processors); clearly, there are processors out there,
made by Intel, where "the IA32_MTRRCAP MSR always contains the value 508H"
is not so, and I've got one.
It looks like it should always be safe to read (and rely on) VCNT; but
assuming there are always 8 is no longer safe.
Anyway, 10.11.1 "MTRR Feature Identification" says:
The availability of the MTRR feature is model-specific. Software can determine
if MTRRs are supported on a processor by executing the CPUID instruction and
reading the state of the MTRR flag (bit 12) in the feature information
register (EDX).
If the MTRR flag is set (indicating that the processor implements MTRRs),
additional information about MTRRs can be obtained from the 64-bit
IA32_MTRRCAP MSR (named MTRRcap MSR for the P6 family processors). The
IA32_MTRRCAP MSR is a read-only MSR that can be read with the RDMSR
instruction. Figure 10-4 shows the contents of the IA32_MTRRCAP MSR. The
functions of the flags and field in this register are as follows:
* VCNT (variable range registers count) field, bits 0 through 7 --
Indicates the number of variable ranges implemented on the
processor. The Pentium 4, Intel Xeon, and P6 family processors
have eight pairs of MTRRs for setting up eight variable ranges.
* FIX (fixed range registers supported) flag, bit 8 -- Fixed
range MTRRs (IA32_MTRR_FIX64K_00000 through
IA32_MTRR_FIX4K_0F8000) are supported when set; no fixed
range registers are supported when clear.
* WC (write combining) flag, bit 10 -- The write-combining
(WC) memory type is supported when set; the WC type is not
supported when clear.
Bit 9 and bits 11 through 63 in the IA32_MTRRCAP MSR are reserved.
If software attempts to write to the IA32_MTRRCAP MSR, a general-protection
exception (#GP) is generated.
For the Pentium 4, Intel Xeon, and P6 family processors, the IA32_MTRRCAP MSR
always contains the value 508H.
From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, tls@NetBSD.ORG, ad@netbsd.org
Subject: re: port-amd64/38480
Date: Mon, 30 Jun 2008 05:58:14 +1000
this lame patch makes this problem go away for me, but it only papers over
the general problem, and works for MTRR VCNT < 8 case that now exists in
the real hardware.
i haven't tested this on real intel hardware (i don't have any that don't
have this problem i can easily reboot) so it would be great if someone
else tested this patch on an older intel cpu (i686-class, please :-)
andy, OK to commit this given it works? this PR can be decreased in
priority and i686_mtrr.c will need more work for >8 VCNT to properly
close it, but for now this lets my system actually work.
.mrg.
Index: include/mtrr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/mtrr.h,v
retrieving revision 1.3
diff -p -r1.3 mtrr.h
*** include/mtrr.h 28 Apr 2008 20:23:40 -0000 1.3
--- include/mtrr.h 29 Jun 2008 19:53:43 -0000
***************
*** 36,42 ****
#define MTRR_I686_FIXED_IDX16K 1
#define MTRR_I686_FIXED_IDX4K 3
! #define MTRR_I686_NVAR 8
#define MTRR_I686_64K_START 0x00000
#define MTRR_I686_16K_START 0x80000
--- 36,42 ----
#define MTRR_I686_FIXED_IDX16K 1
#define MTRR_I686_FIXED_IDX4K 3
! #define MTRR_I686_NVAR_MAX 8 /* could be upto 255? */
#define MTRR_I686_64K_START 0x00000
#define MTRR_I686_16K_START 0x80000
Index: x86/mtrr_i686.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/mtrr_i686.c,v
retrieving revision 1.17
diff -p -r1.17 mtrr_i686.c
*** x86/mtrr_i686.c 12 May 2008 14:41:07 -0000 1.17
--- x86/mtrr_i686.c 29 Jun 2008 19:53:43 -0000
*************** mtrr_raw[] = {
*** 96,104 ****
--- 96,106 ----
{ MSR_MTRRfix4K_F0000, 0 },
{ MSR_MTRRfix4K_F8000, 0 },
{ MSR_MTRRdefType, 0 },
+
};
static const int nmtrr_raw = sizeof(mtrr_raw)/sizeof(mtrr_raw[0]);
+ static int i686_mtrr_vcnt = 0;
static struct mtrr_state *mtrr_var_raw;
static struct mtrr_state *mtrr_fixed_raw;
*************** i686_mtrr_reload(int synch)
*** 229,234 ****
--- 231,238 ----
for (i = 0; i < nmtrr_raw; i++) {
uint64_t val = mtrr_raw[i].msrval;
uint32_t addr = mtrr_raw[i].msraddr;
+ if (addr == 0)
+ continue;
if (addr == MSR_MTRRdefType)
val &= ~MTRR_I686_ENABLE_MASK;
wrmsr(addr, val);
*************** i686_mtrr_init_first(void)
*** 294,302 ****
{
int i;
- for (i = 0; i < nmtrr_raw; i++)
- mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
i686_mtrr_cap = rdmsr(MSR_MTRRcap);
#if 0
mtrr_dump("init mtrr");
#endif
--- 298,320 ----
{
int i;
i686_mtrr_cap = rdmsr(MSR_MTRRcap);
+ i686_mtrr_vcnt = i686_mtrr_cap & MTRR_I686_CAP_VCNT_MASK;
+
+ if (i686_mtrr_vcnt > MTRR_I686_NVAR_MAX)
+ printf("\%s: FIXME: more than 8 mtrr's\n", __FILE__);
+ else if (i686_mtrr_vcnt < MTRR_I686_NVAR_MAX) {
+ for (i = MTRR_I686_NVAR_MAX - i686_mtrr_vcnt; i; i--) {
+ mtrr_raw[16 - (i*2)].msraddr = 0;
+ mtrr_raw[17 - (i*2)].msraddr = 0;
+ }
+ }
+
+ for (i = 0; i < nmtrr_raw; i++)
+ if (mtrr_raw[i].msraddr)
+ mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
+ else
+ mtrr_raw[i].msrval = 0;
#if 0
mtrr_dump("init mtrr");
#endif
*************** i686_mtrr_init_first(void)
*** 308,319 ****
panic("can't allocate fixed MTRR array");
mtrr_var = (struct mtrr *)
! malloc(MTRR_I686_NVAR * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
if (mtrr_var == NULL)
panic("can't allocate variable MTRR array");
mtrr_var_raw = &mtrr_raw[0];
! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR * 2];
mtrr_funcs = &i686_mtrr_funcs;
i686_raw2soft();
--- 326,337 ----
panic("can't allocate fixed MTRR array");
mtrr_var = (struct mtrr *)
! malloc(i686_mtrr_vcnt * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
if (mtrr_var == NULL)
panic("can't allocate variable MTRR array");
mtrr_var_raw = &mtrr_raw[0];
! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR_MAX * 2];
mtrr_funcs = &i686_mtrr_funcs;
i686_raw2soft();
*************** i686_raw2soft(void)
*** 326,332 ****
struct mtrr *mtrrp;
uint64_t base, mask;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
mtrrp = &mtrr_var[i];
memset(mtrrp, 0, sizeof *mtrrp);
mask = mtrr_var_raw[i * 2 + 1].msrval;
--- 344,350 ----
struct mtrr *mtrrp;
uint64_t base, mask;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
mtrrp = &mtrr_var[i];
memset(mtrrp, 0, sizeof *mtrrp);
mask = mtrr_var_raw[i * 2 + 1].msrval;
*************** i686_soft2raw(void)
*** 391,397 ****
uint64_t val;
struct mtrr *mtrrp;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
mtrrp = &mtrr_var[i];
mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
--- 409,415 ----
uint64_t val;
struct mtrr *mtrrp;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
mtrrp = &mtrr_var[i];
mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
*************** i686_mtrr_setone(struct mtrr *mtrrp, str
*** 588,594 ****
low = mtrrp->base;
high = low + mtrrp->len;
freep = NULL;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
if (!(mtrr_var[i].flags & MTRR_VALID)) {
freep = &mtrr_var[i];
continue;
--- 606,612 ----
low = mtrrp->base;
high = low + mtrrp->len;
freep = NULL;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
if (!(mtrr_var[i].flags & MTRR_VALID)) {
freep = &mtrr_var[i];
continue;
*************** i686_mtrr_clean(struct proc *p)
*** 631,637 ****
mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
}
! for (i = 0; i < MTRR_I686_NVAR; i++) {
if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
(mtrr_var[i].owner == p->p_pid))
mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
--- 649,655 ----
mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
}
! for (i = 0; i < i686_mtrr_vcnt; i++) {
if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
(mtrr_var[i].owner == p->p_pid))
mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
*************** i686_mtrr_set(struct mtrr *mtrrp, int *n
*** 646,652 ****
int i, error;
struct mtrr mtrr;
! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR)) {
*n = 0;
return EINVAL;
}
--- 664,670 ----
int i, error;
struct mtrr mtrr;
! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX)) {
*n = 0;
return EINVAL;
}
*************** i686_mtrr_get(struct mtrr *mtrrp, int *n
*** 678,684 ****
int idx, i, error;
if (mtrrp == NULL) {
! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR;
return 0;
}
--- 696,702 ----
int idx, i, error;
if (mtrrp == NULL) {
! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX;
return 0;
}
*************** i686_mtrr_get(struct mtrr *mtrrp, int *n
*** 698,704 ****
return error;
}
! for (i = 0; i < MTRR_I686_NVAR && idx < *n; idx++, i++) {
if (flags & MTRR_GETSET_USER) {
error = copyout(&mtrr_var[i], &mtrrp[idx],
sizeof *mtrrp);
--- 716,722 ----
return error;
}
! for (i = 0; i < i686_mtrr_vcnt && idx < *n; idx++, i++) {
if (flags & MTRR_GETSET_USER) {
error = copyout(&mtrr_var[i], &mtrrp[idx],
sizeof *mtrrp);
From: Andrew Doran <ad@netbsd.org>
To: matthew green <mrg@eterna.com.au>
Cc: gnats-bugs@NetBSD.org, kern-bug-people@netbsd.org,
gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, tls@NetBSD.ORG
Subject: Re: port-amd64/38480
Date: Tue, 1 Jul 2008 10:43:56 +0000
On Mon, Jun 30, 2008 at 05:58:14AM +1000, matthew green wrote:
> this lame patch makes this problem go away for me, but it only papers over
> the general problem, and works for MTRR VCNT < 8 case that now exists in
> the real hardware.
>
> i haven't tested this on real intel hardware (i don't have any that don't
> have this problem i can easily reboot) so it would be great if someone
> else tested this patch on an older intel cpu (i686-class, please :-)
>
>
> andy, OK to commit this given it works? this PR can be decreased in
> priority and i686_mtrr.c will need more work for >8 VCNT to properly
> close it, but for now this lets my system actually work.
If it works for you, please commit.
Thanks,
Andrew
>
> .mrg.
>
> Index: include/mtrr.h
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/x86/include/mtrr.h,v
> retrieving revision 1.3
> diff -p -r1.3 mtrr.h
> *** include/mtrr.h 28 Apr 2008 20:23:40 -0000 1.3
> --- include/mtrr.h 29 Jun 2008 19:53:43 -0000
> ***************
> *** 36,42 ****
> #define MTRR_I686_FIXED_IDX16K 1
> #define MTRR_I686_FIXED_IDX4K 3
>
> ! #define MTRR_I686_NVAR 8
>
> #define MTRR_I686_64K_START 0x00000
> #define MTRR_I686_16K_START 0x80000
> --- 36,42 ----
> #define MTRR_I686_FIXED_IDX16K 1
> #define MTRR_I686_FIXED_IDX4K 3
>
> ! #define MTRR_I686_NVAR_MAX 8 /* could be upto 255? */
>
> #define MTRR_I686_64K_START 0x00000
> #define MTRR_I686_16K_START 0x80000
> Index: x86/mtrr_i686.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/x86/x86/mtrr_i686.c,v
> retrieving revision 1.17
> diff -p -r1.17 mtrr_i686.c
> *** x86/mtrr_i686.c 12 May 2008 14:41:07 -0000 1.17
> --- x86/mtrr_i686.c 29 Jun 2008 19:53:43 -0000
> *************** mtrr_raw[] = {
> *** 96,104 ****
> --- 96,106 ----
> { MSR_MTRRfix4K_F0000, 0 },
> { MSR_MTRRfix4K_F8000, 0 },
> { MSR_MTRRdefType, 0 },
> +
> };
>
> static const int nmtrr_raw = sizeof(mtrr_raw)/sizeof(mtrr_raw[0]);
> + static int i686_mtrr_vcnt = 0;
>
> static struct mtrr_state *mtrr_var_raw;
> static struct mtrr_state *mtrr_fixed_raw;
> *************** i686_mtrr_reload(int synch)
> *** 229,234 ****
> --- 231,238 ----
> for (i = 0; i < nmtrr_raw; i++) {
> uint64_t val = mtrr_raw[i].msrval;
> uint32_t addr = mtrr_raw[i].msraddr;
> + if (addr == 0)
> + continue;
> if (addr == MSR_MTRRdefType)
> val &= ~MTRR_I686_ENABLE_MASK;
> wrmsr(addr, val);
> *************** i686_mtrr_init_first(void)
> *** 294,302 ****
> {
> int i;
>
> - for (i = 0; i < nmtrr_raw; i++)
> - mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
> i686_mtrr_cap = rdmsr(MSR_MTRRcap);
> #if 0
> mtrr_dump("init mtrr");
> #endif
> --- 298,320 ----
> {
> int i;
>
> i686_mtrr_cap = rdmsr(MSR_MTRRcap);
> + i686_mtrr_vcnt = i686_mtrr_cap & MTRR_I686_CAP_VCNT_MASK;
> +
> + if (i686_mtrr_vcnt > MTRR_I686_NVAR_MAX)
> + printf("\%s: FIXME: more than 8 mtrr's\n", __FILE__);
> + else if (i686_mtrr_vcnt < MTRR_I686_NVAR_MAX) {
> + for (i = MTRR_I686_NVAR_MAX - i686_mtrr_vcnt; i; i--) {
> + mtrr_raw[16 - (i*2)].msraddr = 0;
> + mtrr_raw[17 - (i*2)].msraddr = 0;
> + }
> + }
> +
> + for (i = 0; i < nmtrr_raw; i++)
> + if (mtrr_raw[i].msraddr)
> + mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
> + else
> + mtrr_raw[i].msrval = 0;
> #if 0
> mtrr_dump("init mtrr");
> #endif
> *************** i686_mtrr_init_first(void)
> *** 308,319 ****
> panic("can't allocate fixed MTRR array");
>
> mtrr_var = (struct mtrr *)
> ! malloc(MTRR_I686_NVAR * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
> if (mtrr_var == NULL)
> panic("can't allocate variable MTRR array");
>
> mtrr_var_raw = &mtrr_raw[0];
> ! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR * 2];
> mtrr_funcs = &i686_mtrr_funcs;
>
> i686_raw2soft();
> --- 326,337 ----
> panic("can't allocate fixed MTRR array");
>
> mtrr_var = (struct mtrr *)
> ! malloc(i686_mtrr_vcnt * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
> if (mtrr_var == NULL)
> panic("can't allocate variable MTRR array");
>
> mtrr_var_raw = &mtrr_raw[0];
> ! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR_MAX * 2];
> mtrr_funcs = &i686_mtrr_funcs;
>
> i686_raw2soft();
> *************** i686_raw2soft(void)
> *** 326,332 ****
> struct mtrr *mtrrp;
> uint64_t base, mask;
>
> ! for (i = 0; i < MTRR_I686_NVAR; i++) {
> mtrrp = &mtrr_var[i];
> memset(mtrrp, 0, sizeof *mtrrp);
> mask = mtrr_var_raw[i * 2 + 1].msrval;
> --- 344,350 ----
> struct mtrr *mtrrp;
> uint64_t base, mask;
>
> ! for (i = 0; i < i686_mtrr_vcnt; i++) {
> mtrrp = &mtrr_var[i];
> memset(mtrrp, 0, sizeof *mtrrp);
> mask = mtrr_var_raw[i * 2 + 1].msrval;
> *************** i686_soft2raw(void)
> *** 391,397 ****
> uint64_t val;
> struct mtrr *mtrrp;
>
> ! for (i = 0; i < MTRR_I686_NVAR; i++) {
> mtrrp = &mtrr_var[i];
> mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
> mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
> --- 409,415 ----
> uint64_t val;
> struct mtrr *mtrrp;
>
> ! for (i = 0; i < i686_mtrr_vcnt; i++) {
> mtrrp = &mtrr_var[i];
> mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
> mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
> *************** i686_mtrr_setone(struct mtrr *mtrrp, str
> *** 588,594 ****
> low = mtrrp->base;
> high = low + mtrrp->len;
> freep = NULL;
> ! for (i = 0; i < MTRR_I686_NVAR; i++) {
> if (!(mtrr_var[i].flags & MTRR_VALID)) {
> freep = &mtrr_var[i];
> continue;
> --- 606,612 ----
> low = mtrrp->base;
> high = low + mtrrp->len;
> freep = NULL;
> ! for (i = 0; i < i686_mtrr_vcnt; i++) {
> if (!(mtrr_var[i].flags & MTRR_VALID)) {
> freep = &mtrr_var[i];
> continue;
> *************** i686_mtrr_clean(struct proc *p)
> *** 631,637 ****
> mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
> }
>
> ! for (i = 0; i < MTRR_I686_NVAR; i++) {
> if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
> (mtrr_var[i].owner == p->p_pid))
> mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
> --- 649,655 ----
> mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
> }
>
> ! for (i = 0; i < i686_mtrr_vcnt; i++) {
> if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
> (mtrr_var[i].owner == p->p_pid))
> mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
> *************** i686_mtrr_set(struct mtrr *mtrrp, int *n
> *** 646,652 ****
> int i, error;
> struct mtrr mtrr;
>
> ! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR)) {
> *n = 0;
> return EINVAL;
> }
> --- 664,670 ----
> int i, error;
> struct mtrr mtrr;
>
> ! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX)) {
> *n = 0;
> return EINVAL;
> }
> *************** i686_mtrr_get(struct mtrr *mtrrp, int *n
> *** 678,684 ****
> int idx, i, error;
>
> if (mtrrp == NULL) {
> ! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR;
> return 0;
> }
>
> --- 696,702 ----
> int idx, i, error;
>
> if (mtrrp == NULL) {
> ! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX;
> return 0;
> }
>
> *************** i686_mtrr_get(struct mtrr *mtrrp, int *n
> *** 698,704 ****
> return error;
> }
>
> ! for (i = 0; i < MTRR_I686_NVAR && idx < *n; idx++, i++) {
> if (flags & MTRR_GETSET_USER) {
> error = copyout(&mtrr_var[i], &mtrrp[idx],
> sizeof *mtrrp);
> --- 716,722 ----
> return error;
> }
>
> ! for (i = 0; i < i686_mtrr_vcnt && idx < *n; idx++, i++) {
> if (flags & MTRR_GETSET_USER) {
> error = copyout(&mtrr_var[i], &mtrrp[idx],
> sizeof *mtrrp);
From: matthew green <mrg@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/38480 CVS commit: src/sys/arch/x86
Date: Tue, 1 Jul 2008 15:27:34 +0000 (UTC)
Module Name: src
Committed By: mrg
Date: Tue Jul 1 15:27:34 UTC 2008
Modified Files:
src/sys/arch/x86/include: mtrr.h
src/sys/arch/x86/x86: mtrr_i686.c
Log Message:
hack around PR#38480:
- rename MTRR_I686_NVAR to MTRR_I686_NVAR_MAX, still set to 8
- store mtrr VCNT value into i686_mtrr_vcnt. if it is less than 8,
zero out the relevant parts of mtrr_raw[].msraddr
- replace all usage of MTRR_I686_NVAR with either i686_mtrr_vcnt or
with MTRR_I686_NVAR_MAX as appropriate
- in i686_mtrr_reload() and mtrr_init_first() don't use mtrr_raw[]
addresses of 0
still needs a bunch of reworking to handle VCNT > 8 case.
To generate a diff of this commit:
cvs rdiff -r1.3 -r1.4 src/sys/arch/x86/include/mtrr.h
cvs rdiff -r1.17 -r1.18 src/sys/arch/x86/x86/mtrr_i686.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Manuel Bouyer <bouyer@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/38480 CVS commit: [netbsd-4] src/sys/arch/x86
Date: Wed, 20 Aug 2008 19:37:23 +0000 (UTC)
Module Name: src
Committed By: bouyer
Date: Wed Aug 20 19:37:23 UTC 2008
Modified Files:
src/sys/arch/x86/include [netbsd-4]: mtrr.h
src/sys/arch/x86/x86 [netbsd-4]: mtrr_i686.c
Log Message:
Pull up following revision(s) (requested by sborrill in ticket #1173):
sys/arch/x86/include/mtrr.h: revision 1.4
sys/arch/x86/x86/mtrr_i686.c: revision 1.18
hack around PR#38480:
- rename MTRR_I686_NVAR to MTRR_I686_NVAR_MAX, still set to 8
- store mtrr VCNT value into i686_mtrr_vcnt. if it is less than 8,
zero out the relevant parts of mtrr_raw[].msraddr
- replace all usage of MTRR_I686_NVAR with either i686_mtrr_vcnt or
with MTRR_I686_NVAR_MAX as appropriate
- in i686_mtrr_reload() and mtrr_init_first() don't use mtrr_raw[]
addresses of 0
still needs a bunch of reworking to handle VCNT > 8 case.
To generate a diff of this commit:
cvs rdiff -r1.2 -r1.2.52.1 src/sys/arch/x86/include/mtrr.h
cvs rdiff -r1.8.2.1 -r1.8.2.2 src/sys/arch/x86/x86/mtrr_i686.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Manuel Bouyer <bouyer@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/38480 CVS commit: [netbsd-4] src/sys/arch
Date: Tue, 18 Nov 2008 22:33:28 +0000 (UTC)
Module Name: src
Committed By: bouyer
Date: Tue Nov 18 22:33:28 UTC 2008
Modified Files:
src/sys/arch/amd64/amd64 [netbsd-4]: netbsd32_machdep.c
src/sys/arch/x86/include [netbsd-4]: mtrr.h
src/sys/arch/x86/x86 [netbsd-4]: mtrr_i686.c
Log Message:
Pull up following revision(s) (requested by sborrill in ticket #1173):
sys/arch/x86/include/mtrr.h: revision 1.4
sys/arch/amd64/amd64/netbsd32_machdep.c: revision 1.54
sys/arch/x86/x86/mtrr_i686.c: revision 1.18
hack around PR#38480:
- rename MTRR_I686_NVAR to MTRR_I686_NVAR_MAX, still set to 8
- store mtrr VCNT value into i686_mtrr_vcnt. if it is less than 8,
zero out the relevant parts of mtrr_raw[].msraddr
- replace all usage of MTRR_I686_NVAR with either i686_mtrr_vcnt or
with MTRR_I686_NVAR_MAX as appropriate
- in i686_mtrr_reload() and mtrr_init_first() don't use mtrr_raw[]
addresses of 0
still needs a bunch of reworking to handle VCNT > 8 case.
Ensure optional MTRR sections are built if MTRR is enabled (missing
Fix build due to changes in revision 1.4 of sys/arch/x86/include/mtrr.h
To generate a diff of this commit:
cvs rdiff -r1.30.2.1 -r1.30.2.2 src/sys/arch/amd64/amd64/netbsd32_machdep.c
cvs rdiff -r1.2.52.2 -r1.2.52.3 src/sys/arch/x86/include/mtrr.h
cvs rdiff -r1.8.2.3 -r1.8.2.4 src/sys/arch/x86/x86/mtrr_i686.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: dsl@NetBSD.org
State-Changed-When: Fri, 06 Nov 2009 22:44:02 +0000
State-Changed-Why:
Fix applied and pulled up to netbsd 4.
Maybe this will rear its ugly head again in the future.
From: "SAITOH Masanobu" <msaitoh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/38480 CVS commit: src/sys/arch/amd64/conf
Date: Thu, 6 Jun 2013 07:11:18 +0000
Module Name: src
Committed By: msaitoh
Date: Thu Jun 6 07:11:18 UTC 2013
Modified Files:
src/sys/arch/amd64/conf: INSTALL
Log Message:
Fix compile error. PR#38480 was correctly fixed in 2009, it's ok to remove
"no options MTRR"
To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 src/sys/arch/amd64/conf/INSTALL
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.