NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

re: port-amd64/38480



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