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