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: matthew green <mrg%eterna.com.au@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: kern-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
    netbsd-bugs%netbsd.org@localhost, tls%NetBSD.ORG@localhost, 
ad%netbsd.org@localhost
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);
 


Home | Main Index | Thread Index | Old Index