NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-amd64/38480
The following reply was made to PR port-amd64/38480; it has been noted by GNATS.
From: Andrew Doran <ad%netbsd.org@localhost>
To: matthew green <mrg%eterna.com.au@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, kern-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
tls%NetBSD.ORG@localhost
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);
Home |
Main Index |
Thread Index |
Old Index