ref: 6cc223ee56e5f0aa20dfc6f51b70607b5b14cf5f
parent: 0ba91ae22a06af3a7561db15973dd98f715cc9eb
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Nov 4 18:08:52 EST 2020
pc/pc64: fix faulty mtrr slot reuse (thanks Fulton) The change 3306:c5cf77167bfe made the code reuse MTRR slots of the default memory type. But this did not take overlapping ranges into account! If two or more variable-range MTRRs overlap, the following rules apply: a. If the memory types are identical, then that memory type is used. b. If at least one of the memory types is UC, then UC memory type is used. c. If at least of of the memory types is WT. and the only other memory type is WB, then th WT memory type is used. d. If the combination of memory types is not listed above, then the memory type used in undefined. It so happend that on a Dell Latitude E7450 that the BIOS defines the default type as UC. and the first slot defines a 16GB range of type WB. Then the rest of the ranges mark the PCI space back as UC, but overlapping the first WB range! This works because of rule (B) above. When trying to make the framebuffer write-combining, we would falsely reuse one of the UC sub-ranges and making the UC memory into WB as a side effect. Thanks to Fulton for his patience and providing debug logs and doing experiments for us to narrow the problem down.
--- a/sys/src/9/pc/mtrr.c
+++ b/sys/src/9/pc/mtrr.c
@@ -292,7 +292,7 @@
slot = -1;
for(i = 0; i < vcnt; i++){
mok = mtrrdec(&mtrreg[i], &mp, &msize, &mtype);
- if(slot == -1 && (!mok || mtype == (def & Deftype)))
+ if(slot == -1 && !mok)
slot = i; /* good, but look further for exact match */
if(mok && mp == base && msize == size){
slot = i;