NetBSD-Bugs archive

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

Re: port-amd64/38480



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