diff --git a/SOURCES/0001-linux-firmware-amd-ucode-Add-note-on-fam19h-warnings.patch b/SOURCES/0001-linux-firmware-amd-ucode-Add-note-on-fam19h-warnings.patch new file mode 100644 index 0000000..5878e4a --- /dev/null +++ b/SOURCES/0001-linux-firmware-amd-ucode-Add-note-on-fam19h-warnings.patch @@ -0,0 +1,35 @@ +From d252e92d50c02623ea9da0a140240f6d7ac4558e Mon Sep 17 00:00:00 2001 +From: Sandipan Das +Date: Thu, 14 Sep 2023 20:16:51 +0530 +Subject: linux-firmware: amd-ucode: Add note on fam19h warnings + +When running 5.19+ kernels on Genoa or Bergamo systems, some microcode +patches are known to trigger warnings in the PMI handler. Add a note +to list the required minimum patch levels for addressing this problem. + +Signed-off-by: Sandipan Das +Signed-off-by: Josh Boyer +--- + amd-ucode/README | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/amd-ucode/README b/amd-ucode/README +index fac11524..f47743c1 100644 +--- a/amd-ucode/README ++++ b/amd-ucode/README +@@ -53,3 +53,12 @@ a32b0f0db3f3 ("x86/microcode/AMD: Load late on both threads too") + When late loading the patches for Genoa or Bergamo, there may be one spurious + NMI observed per physical core. These NMIs are benign and don't cause any + functional issue but will result in kernel messages being logged. ++ ++NOTE: When running 5.19+ kernels on Genoa or Bergamo systems, some microcode ++patches are known to trigger warnings in the PMI handler. The following are ++the required minimum patch levels to address this problem: ++ ++ Family=0x19 Model=0x11 Stepping=0x01: Patch=0x0a10113e ++ Family=0x19 Model=0x11 Stepping=0x02: Patch=0x0a10123e ++ Family=0x19 Model=0xa0 Stepping=0x01: Patch=0x0aa00116 ++ Family=0x19 Model=0xa0 Stepping=0x02: Patch=0x0aa00212 +-- +2.41.0 + diff --git a/SOURCES/0002-linux-firmware-Update-AMD-cpu-microcode.patch b/SOURCES/0002-linux-firmware-Update-AMD-cpu-microcode.patch new file mode 100644 index 0000000..ab88b98 --- /dev/null +++ b/SOURCES/0002-linux-firmware-Update-AMD-cpu-microcode.patch @@ -0,0 +1,663 @@ +From 06afd7f939c5b245b2af9e0fee13026f2aaf77fa Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Thu, 19 Oct 2023 17:03:20 +0000 +Subject: linux-firmware: Update AMD cpu microcode + +* Update AMD cpu microcode for processor family 19h + +Key Name = AMD Microcode Signing Key (for signing microcode container files only) +Key ID = F328AE73 +Key Fingerprint = FC7C 6C50 5DAF CC14 7183 57CA E4BE 5339 F328 AE73 + +Signed-off-by: John Allen +--- + amd-ucode/README | 6 +++--- + amd-ucode/microcode_amd_fam19h.bin | Bin 39172 -> 39172 bytes + amd-ucode/microcode_amd_fam19h.bin.asc | 16 ++++++++-------- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/amd-ucode/README b/amd-ucode/README +index f47743c1..86d69822 100644 +--- a/amd-ucode/README ++++ b/amd-ucode/README +@@ -37,13 +37,13 @@ Microcode patches in microcode_amd_fam17h.bin: + Family=0x17 Model=0x01 Stepping=0x02: Patch=0x0800126e Length=3200 bytes + + Microcode patches in microcode_amd_fam19h.bin: +- Family=0x19 Model=0x11 Stepping=0x01: Patch=0x0a10113e Length=5568 bytes +- Family=0x19 Model=0x11 Stepping=0x02: Patch=0x0a10123e Length=5568 bytes +- Family=0x19 Model=0xa0 Stepping=0x02: Patch=0x0aa00212 Length=5568 bytes ++ Family=0x19 Model=0x11 Stepping=0x02: Patch=0x0a101244 Length=5568 bytes + Family=0x19 Model=0x01 Stepping=0x01: Patch=0x0a0011d1 Length=5568 bytes + Family=0x19 Model=0x01 Stepping=0x00: Patch=0x0a001079 Length=5568 bytes ++ Family=0x19 Model=0xa0 Stepping=0x02: Patch=0x0aa00213 Length=5568 bytes + Family=0x19 Model=0x01 Stepping=0x02: Patch=0x0a001234 Length=5568 bytes + Family=0x19 Model=0xa0 Stepping=0x01: Patch=0x0aa00116 Length=5568 bytes ++ Family=0x19 Model=0x11 Stepping=0x01: Patch=0x0a101144 Length=5568 bytes + + NOTE: For Genoa (Family=0x19 Model=0x11) and Bergamo (Family=0x19 Model=0xa0), + either AGESA version >= 1.0.0.8 OR a kernel with the following commit is +diff --git a/amd-ucode/microcode_amd_fam19h.bin b/amd-ucode/microcode_amd_fam19h.bin +index 02a5d051d58b8028275ee6a0b091f11f8d1b6e27..412e5fc83dafd35177aeb39bd75c463658694587 100644 +GIT binary patch +delta 15313 +zcmV;?J1)e8vI2y%0vbe3K>z>%004jh000sXp#T5?00000000u9kvbv{0uQPH00000 +z000000;-W(A`TG`p#T5?00000000r8k$M~h5eY<-VHO*IHFS{Lv@m<0RP$?^U>$L< +zwEq|1f`au?B#Z9oUK3)SoU?4AXM)eFtTDw5iQ#=AL;mZJ3x`aPi@wp&FxYzH>u(b9 +zF_rrgaC#9i#1vOiC+IA=8ic`){^&qRPee_k1s^x!A@ZAs${SvTMqc;&rX8&Z0~~Y_ByH5NXaE=<>%-Aje0LO*B)2Rh`Pb3su3dLK61d +z4vdg|D$6TWmk&>G>M=EFZCKQ74BONrNHT-s)zR>++^q}k3;LEl%Nh=2+$VVl4W6i| +zLSS_2Q0EH65aA%<+pN6{90i$6xkMBZI=61~C9aJEl8Li?7X$)-L=q4REc}5GQ74tF +zq)CJdg2!TsBQ)eOaTl) +zD8{}A<<%_~7%TMAA>3C7rOmsm2QW~SM18OJwNZZocyTd*C|=yf^;wGJm-Pv6fwSj+ +zw{dHb&a?J*FzhTC;8S$#aN_>A8)iUyf-_x7%eY2{+rje9>nRDzM#m|2sVd5dBB7lc +zk<4}3+_l_vFUCpM6U=LYt+MkXpIr?qm#QMHi*@n<^2MjZKc9{YS7yvF_4CQ-odwif +z<)%?k6MUk7HOcC{HK(JWktSk_TUi|bAD|I-^8 +zd_9pwFcyYC+0T4r(~=d~XDd32r2%J{XUBHrTk}SLlJ$Ihk4NvFa*+PQ(x?JdVzYZz +zbv#7Y*Ci4|g`F>hKGT?38{olNUrw--qO=9h07kvvmxM8d+xELEyHM$z`IMw$O~|^q +z+BQcw+b*WwxhyB@%%~*45J)lP(Su-dQ&KQw9%s6w1WO< +zlL!&syuDwLtAVKo;mRT4SurBfjf-N=WH(|rYyYUi*Fkc`dpk?lM{W=Z!hFWeZSm)?IWwpFho*adAunueI>v)yy`2o;!KP0 +zFJifD1_4e$kWRKS?aS4jXUj^pbg=CNUieoQ9<&nKbRSR +zeuZ#|neK)sw!yX!XkL5lLIK4fr>{fXh9}u!c{~egq_c^*${Du5*$4P=elC`ZI%aWi +zAztU8aQGI2g4htSq4>rmjyJn4`})xiNSC3c-NJY%i=Icw2Nk6b65hx2py@72+K@S9|2WH2=PTMmj=nv5kG0KH847eUK@avFT|Dj1}fQt@26F +zWmh7}4KivCO4ej4bviKVYxPfAKeHuaB2XjW-gGU>KLdAPDSappgju3Yp(UC`1il#w +zSCQ(7V*)}yv$ZR*t;Fl~$Ybb9j=Lwm^6X61mQNCMfEs(4vrv0aoox)3FrZyB^%3fe +z%fvtVQj9k%+!(X#TrsW=Q!+@Ew@|G9ZuDH=Ily%pbzn=+y!D!{-&-klzJN;dp#oJ( +zf>PuzJ2kziXyDE2$eW`o9YW!MEglap5MH8aE)tZzV)Pe7Z8~bV;0AeC^PTHM*{&_c +zBWy<7pM5^CisN{>kB2%_W=U5?#uMHFiN)e)J(NCIs9r=+LTfu(M>k_FmR>zidIn>5 +z3dey|nqPc__P5-pOR`?Az66R=O +z71@gjS5vE)#$is^DdSCl@&0Z8eYuinn^FxWEJlyDpq&@ +z*PuK2tICIAj{g4Y+&i-(xQoG(-R;#y6f5~n%b2N&$febxMB&%ND#^6itw9I4j)e(O +z>xpkeYe10?O*#@w;MmSA;`xaQ3Nt|mjBSdlZ1x`78fBz`;1&~qo~Mf_2wF!0hz6^$ +z+$=t!V`{F0#7%r>QGNKMY;(b`1b6u4szFVuo>KCf9b9)3#bFU|kQEp?Q~A@=mbCqw +zVrPbaRWYz!zA!tu6J{-60kSTg!M&;3ua%d@24>L-yk9KK`Nzq}xYw_8Jx +z#74FtvYAU&@wRtPI=A=DpSQqRprK^W>w*IzVsAKnXnf2Z%@3gFMIq?37;Xncb*Q!RjfsruyC`QTwuAhChi?2G1617ypE?~L+%5? +zC0wJnr4bXUZ4_>FiHn<9^czDNqxd#|#T}Y}WLV>WUm>CHhctc;QL-z41}zvZ9&WyW +zHFMcnKbyM*v6{o7e=um72y%YdVAlsG1*|_C;Hb9_=g}d+kg`&vSu$}Srr=i4l=qYw +zz3`zG6m$&lS57P}JU=T=O3vxF`f3=yf{GP8`bX1r;Z6#)?D!`%WZI5~$uMRjN=%0> +zwb!kG61*QhwDoy$^1>kfV*=J}V^Ry@5;4Dpl@DsJv;~!|vToXS%MyhUd;zo}irDK? +zNf*^XNpOrO-$EZbF%y7pRp>2RSiDXty}zt%#RtV=EMSZpdIa}I>)fY~ayP=OSe{@9 +zRo$w-jCQPKqq@392;x;B;8s9#s)b}0L4m7()}!LAS{ap<{$V-Tk}S0{!+k)FMs#=_ +z^xn7uU(XlUh$}sW8U5iibvL=_FcIu~%(X +zxDBk@Yo{8X9XPD9H7+EUs`j9?c)cTc&oKQbobw%K9~0-;7pYTXD;cZpPVq1z-|vCq*v;*?;2z3t4c +zN6oPxGMVTL(+y(YBTHMcNO~NxwS78SL#Q_G89%WtUiAJ}5kXYT74m?E3Y}}Ub;BG# +zMlC;Fx`?fp=_3h}h-9WjS;a~`KEC@_I<}LfZ(g4{FVIMnWBshM(n{hvA-l4o_J75I +zpo`&Rj&?3{Q)=RaT^btYkl1fR=_pWV5GdA<&%*z3Ocb*ZV&ppzF^jqra;& +zF++gyo8MPa9%Uw=*r@Ik>l+4lO_XfA8|s1?ZB!DYi8|sh1t%GBWYH)IG(t3(ZXWb> +z9${?&&JW6Os*=)h)#*t>5@9%}LA&5hRxV|-HZfnJ}c)u|`II?C+%)Az~8Wl!NiK)%)ihKcg8(~1zcJOT`yt*y~v_Az2 +z5=`>B^rd<*VUTFZnf2*^i8nvT??dv*@QH0b=9{uvP%pTE&8Bcx?N;XkQVB-uT_Tu= +z)3YcEbe@nEXP}lPXqGkc3MqUn}6@r;B2DXa+GYZxd@L?xQk=Sw}HgVK1jUt2AJ1Yb1$xM&S}iJ?(_1tR)J=HVIepFF$|*Np@(_Yaz9a+7exhN(K>w+f+u20h<(N=I#iS34%)L^(f^ +zUY2C?9=5V%vnUOS1Cr!HFXl}~PE7XbJADv^oUwv}*#Pa~KJ)OX8Ggp4HO!D#qc~V) +z=hg5@G26ORMN;o>ZQ?JkT@z{uCyIM6B99-NluK#FbdzvpzWA$T9+u!Yvd!Jc_XmGI +z9|DL%-aD{=pgKxtux!6Iv#t-Y4I_$iG14qrgMHf6mlevM5nMc6Tm_53!EfT@C(Sz> +z2+o-4N_D1&q9TRYK)7L|bRmyMin2^6$n8k6`Wv6HuJzyYL_5Z{-#t>bw0G7YDdlHK +zAqp%r8NcDIN#C|mp)mmYRnE?VHo+F;A$DRut}u~*{Xr+jBzX+;w~F&G&x~JO8WdAm +zqqoqZiFSXdV87zZbf={LUBUQuSVUNRtAk11<)2Q*r@lX*n1yOtWf4j0FvEi$-_KG( +z^S$eUiJ#Jz{x&(7$u8bO6WnQ3_9co^>Is!HAdfQ0$nzbekni2`anp07^xKGqhG?Ee +zWv)?w*)OxZ%MJ>!sxk@b@{ARwMFdw~#|*6^hA?0aWU1sHvi_tiNV8#8wq}VJedJfO +zl{_BX+6T$IA1hL7*iVxz +zXyF(^FX{A53HV*Uas4NN0U%Ha^SQLqd7c}8oS)~QdgM;KjL+NQ%=yp$?hQAkAP~|ZxVXLiSMLC)fU!n +znL!%o?NgeTVfPfSuXtqdm0!^6Y7_W>Y(0D65*NWIY9Pg0CmmyBJznD)zc~Rz08-@o +zq7SY9n;A}Q1?n8@CDx+C`StqB)DTSu9@`*&kqyln*yFx&H&V)+zJLT;-u7L9Rkm~smgPB@XIcj2#=I_p8fOvg~^4-H*$Zp#Lg!9;2r+=kdW22TAdW^;{*9OQ$J5h +zR-*^&40|~*4PZ`8Rm9{hMzGRMHd?#0YtvE$ygGhAfm-&Go+~`fcj>>$nTr%0 +zVo&1Ok5(0-y?Ws%7qa4YF5HgrPiTfQJVzmJyE_#}p2N +zTN!`$*62hSG_-l*YXaOh9`y!|pmy^9LFt=G(012M8y?RxHbd7dkru|g(b5&! +zp(+qPVY=u4s>O*)4cNT{ZXQCni8DDfS!u9)A|{SlSf($nH2-^NImPQ<3@(33ii%9_Inmj(5E~xkjt{xSW4m7(MbYNFoFDg93 +z)sK#gjIYt@MM58x5nml!xvPaFm%+Toh_7dEk7>J7we$spN<+USmO_duBWtP9G7VOJwK#1f(7GFt}v>`+Y`aNUKXj)9Y3y?To;g5gTsVhh%Gf?&D +zZjuOOXE?I~xbIM_>VTRb2*!Or421U4{{ +zeWLd|s?gj7sHC +zP+^*2?0FTh!%P8)^}^HyPSlQhC7YB%yi@bj{HNYY8qAv(6kw{bL +z2H2%h^Hnv)ix1LkjmMBEZFuNG5aHkIvF8~Var6Kf1^aQ>(op>tSfzAyj`!uZ@(!F; +zy~HVU*6~LtetSv-(JruG?@2Qr7E +zNw8g~g;>q7AmD%TDCC&{sUdB7*fIEJ!!t&$j>_0(KnMIMhkbnsVFaS$E;#_UiZdH( +zT4hdV@?Cf@&79kf=x=Mf25K=z$_8G5`53;P61t}k#n`8W9CV4IRP|HOjeQ_x9tpiw +z71Cek%%oGFGOdgy+6P0*siM`+T6yC_1{mFwkTn?ubtHdT6vP{QUtW#FCH3(dEKAa@ +zBFa!>c{ghc>1mrk|Llksx^y>*x0>)QyWN(PkNK&WoA*s?!A2k1kP7=e?46Sb$k#dB +zW~IblSHG-W%2Bf=xt|NNuzyXE?nPs6! +z@To8W#B)v335IzdgsCGiwt`4_(J+i8 +z;PdVnJu|&wUN;^qKYtIFePBu080?TMFm&r#{(zjVM3x5B{00Y?iVax9UMHY4tHW11 +z+k$^|o-bt}zc}0#V2|FD_Qh0EvP1AbOgw9Oc~?{YntQ+c%`OP=B<`gmu5T4Le_ +znYe`ZWU#unZgUHj;p#1;%XFooQ0?3BoS(JNNQD@}_oaj1${RYcqe0 +zD2I{w>wzPf^vez4ghU$*$&A(yo$~1)3n9-z7``(^k?g#aZ4Em#vSU=A$au +zRRma2?X_ZkGxA5|$}~wF3-r^pb^(pI_sKCB&YLFMKP^4M+;}_)IH(^7`-g(0O2>#3 +zbfbz)w!7NEeM?6&DJc6>IXy@&1!;dHlWZmhGrN>d{ +zQ_q!7e%;B+>N-J-KJR}xKR2qoc`obvLk}KoQ&~BGX)>e0u<(wjz!-WK&Xw|~PW3MU +zm88~WNPb!StA9V8gbUlkvlnb`(4z{noU2sB_3JSDb8U2%&i9@y!OUTsAI*Q$@ckr! +zXZUXb<6o)WiC{}p)L(V-UqoR=fWT)~Mwzd>76!P@84naW +zPm-w(ee32+PQZ0jsE3()8%_Now_#g8UVU*^*-R~I{=7aeU#u^fZV4N0|ggI2ZSxOa<2kr +z`4$GbpIeVy_TPgmEj@0Nk{{f|>vm}J>kt)grFXZ(I{HMWoZVH3n-qG=hHgqOJvLV` +zczJ6ybfLt{`rKZj{cL|RKP5G|rt=u0=fp1AcU!1Z01WwV4-O;8Y|aS(n@P +zfRJBBHR7tD%)_DJPTxJ1DQ#uR>A2CD0~Zdv0VIbQ +zhK&`Iuqf&5Png*5Lp!vMx#hT^hBNI|)oRAO)|h&lD&xjt7%t0HPpQEsnPFoH3#K34 +zhIJQAjOI>s=E;$2&kx<2vQ(IoNwe5Y%n^Zz-G>-5oy* +z1XcjM(Ljj1*o}>}9MHn%&}NP`D{Q|oOXON%AwZ3$?}Rb?WPgEw3^8ExJyjo#$Vm4B +zrbfhE4vc>{x?;V5O3kZ59qt9*t*Xg5$Gb2R2b@TC%d(V^kGaBxM1kby0F>!k6p{Vv +z*f~<$7CTpYhHJSFpAgH{O#zb+z$hu>F7(ih;TKJ^Yk~*yun~DEt<;aLF1LY~Hv;5n +z>|L&WWOHM6D$3r*!Bk2dfopV@i=<4K^AUzL6s&&_BQjJr&-U!sWmQ@# +zSYTqW13eFCJv$u6+P<&o^r0IZl-|?Em(LKN5Dk!E+{%66Ouq(G$?jpR{j8N!W285; +zMRD6&kL^K-$Kc`3)<|hH!8E@dt4p%vaUsra-F2M@LA{fAb +z8|R-KJXNMfQ=A{=Pl+4JVskNNxZ#J?S1x~G^LH5>7*`dh*u3@XJ^rY3=hqNthpq<7 +zCZ%KIScg*z%XzNckwBkdk+!Ri_NqI3uU}lhxxPW5m(X$)j2_n#=N6yz91NL0L&=D& +z+38itBIgXW2=i~6ow1R^QrH)p9*x#o+S3rbY$(1%T_@UAL)Dq7rvBt*?-001LJrlDgQRRW2spMc=w8bOXB_%jSR;@QYL%~QrCubzq$291eNQx* +z8!kw2r>XO-z*E(F+~SovXEVHyku9^oL_ +znpObNL(MHMzNN_3@RQeh=wf|ZcN@N90BYDK>FgUPJ?o-OMkqa}exxB(%b*|9y0>^k +zIB&d*4evc=b6R7`Xa%qxOhLg>-*t9Xsz<$EOrwCl_?8(A{$KX5pPwTJIlq5}Z;`w@ +z62(;6n!xlewwtqJ#fg$4#db@-nwF93`nG$mBE%=Xf~AO#K^2RND3=T`Z6H1FQtKq_ +zW=JT6Cc#@8%RCn|2WBwU(ityM-95KxGpD<-@mi5av(6`0K(dI0x7=HBz-f8K4b(9| +zV|)$5u9W=?Dm7(t#56e;Uxa_%?V7{4o<8u#)we%u?-q|m-=ICX=a=%t^pUn4S<0kr +z9K1p9OOyN}=Sf~&oOX1ZM>Zo17~p!I0x`! +z_d-NUT-9FY+X=8d22^=lt-vlR`AJ0#fVL8lS*>&matDo5K+cqQ2wv(V{hUNpQxtHM +zwHJ@_g?sijSz`6Qb<2MTmhi9Zf=r`TTM5W;N?gAO6(-4wsCC*#HobV%0^&Y!MR*k5F^HyAQQy8#K5Mh6%AYQQJv_?R_(hm3UUi41-J7G +z8JmrnA27tjBQ|bTEkTxbvCC7H&6Iu18Q)3aL=Cn*P=gbZ7#)8GOp~j2J^?LG_t7eO +z=%0O>QRN=4?#2qoBq9et}h!7&-$}z0$k#EpZB;C;`{uGj=Uz6^GUd|J)SZtmyL_v#zmpD@IG&QmHf4f6ZhRJ_W_YEvs_gLsnaVfl~R!jWF +z0>&!wvVnag>=$Qk#1gC2??AS>c~j7~uF{fnX)ryZ&|q4#2*DkgiHV5Q2*@Kjv(kwwqit6#$guAoe^RLp@B`IaIQfon>}KF +zlCQP8>Xd(a-SFx$e>9ZDk)hm?cwKlL(^;*KL#+#R895%;A4fUm(~%ncIUb4c)0;Fy +zlyT5$UU0;4P~ah=mtr;)!llF}qd;MZaKJ>4!RoW`tu;_7|Ivb)2MLSJU-iaJjDc%0 +zF;8Z7)vFdinRpQmJn6tmessNXG&&iy;7YpJvRQw2lnJ@b+6|+^r>0G3HAvo24jURGM3am#;hB^__bd?$QKq?>^8BVPo=`92xmikQ;XmAJ&eZVI&@P}`K +z|8alXM}h9Fwdw+aqsFrKygFMIortio22>lH9otU!+0PR6y1O^Vk5QQRSeT1m*TjKJ +zu}}B12fD8%It03GkDQr?*j+UESwjgQpDm_p&~VhFxyMK~NqiQwAyQA`tOWilZx}1R +zs8h$%++!jCONV#;4#cNeOflos?&AprjC?^msNW%lP0qO+bO01el8tpXj7LyU9s +zx|<}NL%*dydy#=c=pvf(^(SMO4X}_LBK_$9Pr>iVFcW{oM~oa@M`ASG<8d0x>Xr~q +z-KF9ItIW~(jOO5x5>JZC4oS%Qg`>7@inK;bZTLJ$&5I}iaUr(GYyZolfjD-qxXMm? +zVXkORiwg{-*@A1=4S!MvG4qxA^7EE3*<7ZNE;f?oYmjM(qIGPGyt}HlFt+2h%&p!V +z(k<@zmG}aT1PR$5) +zDJ(<2f#=$hjc5@FIwED&XXxhb^=y}j-re=2qVA0tqI@*N4_BSa0Ov6PZ$74R8vRUm +z*C0g&7EJK|wxAT))CXJ==-KH;scB`aSSStII3Ad@YIajf(UyM=ed%%yW=IZ&!iFAp +zc~V~fcZ!(4y~*m%o*Ls`nNW?_heZM%@ncIIzJxdt0Rd)+JS%Cda+tEPWhiwN*(RW0_lN8=68e@4#> +zM@~Wpeux0@Hqkk!vHw#6+&v9y`de;WW-lC-1AR^MvQi-(@w$)c7CZ-|-PUKv*e_@Z +z3q@B|J~HdGK+Jo3!qL>}{t)Ee(XBD1YNxM(W^Fo#Zd?kus6U_hKa8>T^$trjmSJy> +zvnN|Xc=dl#YLBHMT +zyf%)jb#!=y4qAut%Wx +zM-YFM|88>LaH6-V%nTk$FgY2*Y>9>mFr8q%h{o}2N{B#5H;eZjC+v-?BBR7+owDAU +z*N~auYD_LnyhZyw7~C-cv=1G_H9kf??48C(0zR1@>eDGUrclpf+5Pu_YcZRFcxfMX +zcA%SeZtagxtYuN6aj%j_cYo*8V6`d_(6oPOVKBav696-tZ$_1I3Yl57eFTxj=<=25 +zI^G;-`0c?P#DgL7!D2vZlho?JuIpcU$nBdY225xo5P}$GlL#M +zWSeKe{Fcfv3JxIb<)-SWkXFT43&5X^vU*2GLnGAvO3(_YJ?ji=1k&)=~6-_^RsT90Lm_` +zR{8s*#y@&m0vpoX!m3-v(c$pu)>8e}F8~7Dh;AJ9YPF6Uhu@JvT&9s82QYt(yVtU64I8t{HU4@fPd-wRteC~U&Imn6Y5U1Rg4GNcz@xE9?ig>l<;1xqjr +zMwN$eoWM_sxucPM?lCRKsDIl{#_=+>`AkC@8raQTa2d^uyMFX|B|?+R@;~GX7lmee +zjw4WAhLvE5Xyw<+8;msn@u06#|IrDWLtH9SgN5u9pV7 +z;<`ag$Eu|hoN329-1YuY@v+qIb^0g;W}tX8ra~MKMOV<*o34{aUJk>F^X;w2IwMR- +zFyHVkWm7?!)CA+qUmaWvk)Cxdd@N0qwbSvu3~cnA&W6#alX_3O3psy#lvjKU|1E$Z +zih;}j?(Y>?!UuOB6D0ACT0A0pQKPrhct$^a>8Sm{$nPi~XdL%ph>i(DS!~_$|kAbqgV%uT; +zC@MAg%l0=NxjZb58qzD+Y1*@?%G&POgFJMIdO^=1qe}!zw6!(jJ~pAuPPT14WfT8 +zJaqX0=l)8o1%Q8k-V6U9VtGVW_xXdp&DvqvfJ7l;bn@}NMYEN#6d60hpG55P;jd18O*?!FaU+~Wt-dQ +z3MZ)iKRiZ149sAzP9Xl{GF)z@Z4sp8UM>jNMw6 +zAdvx?IN|0&zVRYOyPaO33}M%|Xw@78lGsu*CA4+cu%M}p;O%EBD+!9t$>WE|sm@r@ +z`CQbF{Cb_)+MY(&Vbx?v0fP2MGHtMsC(*h>pASstDoi*{046WtaO#D4612^d2kZSo +zs}r@&t|@=t$A_%-YuJS4%uPf2vNT~5(4}nx6&PToHHw^8WaBrU2I!$t$y>>s6-h$f +z{Pdv(oa}Ob)tmx{VhMEa+5DNaQR^~`AC?}XQ4)am+xUQxT(Z2%X&~H)AWww3IlnWV +zOI6<0FVKK6Z5mvQZ>`gQaC$!#`>L;b<6-dRny5|43I&59`NFfX%n&(0t#JUK3(SJbr7< +z3ITtDz*j=vLBmK3(`pPiX9&1vZm6Gr4sHAEdIzB{a2>6)(jov6wD|t1fwKcz$?QJD +zB+|zM_=U2pYrOIZdx@(Vnex_RWSuxv;R1WLjc<3?4fd4c4hMY(f{(pn7?;aTg&6OR +zc@rE&#(qu%8 +zRo)*5v3+3Sc`q#m^GX+;0XgQ{@@~moomVs4+sWlPFBwE6U!7D<7y5njv;ajWM740AGrM$t_JI>fU(G=@nDIM?;=#U_dNw4-Fq3d$o34Mt +zo^OdQIz~PGO~5ZnBdWp!HlV;{%fgJ(d}G7Ieh6^=&ko1x3`Pu$On~hI75`yiPm?IH +z$4^=L1@>jNh>FAS26U;&RAwbC22Oa-xSVO4@ew+J;WN`*L1emOgnn3lZ2xaiL5<0d +zlNOB^%!pjbFe_87@zD|?iFX$3kzapVZ((4Gl$R#S4_YvBPcqrqzT}{=2zmwa2M5Ti +znO!^Eo%((z`&w5Y3=XzR^5anZa+EKQjx@g?>Jv-z#wKPK3Mfxg=hfcwK?8A>{eLAO +zBKvCAU!7Z5%JHt&;s*&kds6w??mgZDQMsZf_u5NT)r|pRy&iiP0gIwutDS$j^!H09 +zXW-}im+xUC=}TifDJC3WdJu%F%_<5)?K+Zf8^%ukUN2A6fscclcALEfs0Xw6zY`Fn +z@3-6`5ioxwT>hhpR|U;|L@TQb>rEk!VGjA6JbeDn3!c)2qPfQBgleDO{fzQ9x0b&+ +z5jJ`CoP>a7RG4!e^~Mro6R9Ht=qP7&QAV;fU`pVpuRyq?PyoSr~UQevLWwZRoY6YTG)%E +zoy%C={BI((VXE}1eF{haJ$qEN7en7@;at^7#PiIk3;sWvuuNeCbM}9uWLduHPrv~0 +zn2-F+I^G5{d=4>;_PB%O6&^Yba7?vAa?|eo^$q7yKe~OM6zBASHCv)w_riD`NMU+q +zoAt+#_6oWe5cwQ_P-g#_x39}{!PeofBSj5~+%L*%LGYzgM_-V8h2C4~71(qwsO9FE +zmhW=RBip77OXh`SOt^mp;L;m&36s^sD(5gDZGNSfg^E*pZ|8sa{t7@DZUAPMYT36I +z`|NWTcCcXSCnn$FX!7HFLgEgyrMI!MKxl|I%OM9?{Hk{TvZB|yQqXOsIt>)Xt(r^V +zU?$C&^p=3{O=a1Dt2Z|9rRPZ@k3jnADd~K?$BQ)rt7khL7zcm4^4PPemXd-LdZ%%s +z%=n<%an#6Uh_sIEMyr;Py^ICj?f~TXMMkV?!+DhS=L%AbX&%k^b9v?_V@ELR(@KVE +znR_6ObiI_fn;gLrD)r8gWnvLd19k;&HuX+i{YJQ^H=>5byEZXt8$7b)+BhIB%FPDJ +z_dVAkA2z1!?W%v5YCeJ{EFks3tPLaS$=I)VT-c&Hksi!8Uu%z!qnTH5zL2?$e!RDm +zvnN+#_34148?SQhkDZbcO|Fr6$RCDeyDa4OF({RrPDFi?l{cw+yUxlf7GO*TNB%hf +zSic^mVp~;+XBo2$tuhX5xRKv0>CquuezuR~Kbn}Z<{W=RQS-Na^zQDGR%5&dcgRcc +zJJ|76!-w6WJ;H0IgMP?8*`uO!U2CGN#|3rqC9_7p&dbDVZ*SA6i;ie}Fo~&OJbH*e +zA_c}x)D;Ce=I%$F6o&Cajx>!s(bFP^XmpD;4$uOXM1$ra-0E^e9YOH-8po1)q4lN#SaqNnYrU{Z7o>G&bmRt3 +zL|lQI&e=Q=FTJ6sX@MLJE|%1@+v0&(l$VzA{Pln51tko&X8u>A|6*K7tL2~#-%?{a +zkrs*bptlp`28R8)BEk@TNtv^!HvRWBX6s~=ulK=otMM{BgqO0YG83xFrZX`O;t^5+ +zPtJ{|Uotl{c*+W~*bQZq%dA%CdmAk +zy|{muRg(y!Ht{wV6+L@O56f5;QZKSr=_^BC21-CF^vM#bIwPAsTWNu>sSep2l@VH* +zZl}Xbsiho`15?mxf3m^{%qSPzo3)d9ie(2PoO!q&0C!~j5T?Vazid)#m+OgWaT(Hw +zFrS4Vv!^^q>z_<5kbM!4cFrzD10P%C0Th37EJRnxnvlCy7_~U1c#2Bp*)*$N6ZQif;b|YLO)(i;$|>BjI0DaJuK_ +z1r!7sY{e_@u_?zS&@pGi#taWAe{I@Mv8ZF+YHp|M=C%mjr>TtJ?8^izXt~N^COLnB +zL(n9&DlSj#x}cnU*YElE|5ZJo%^`Hi)RR1fTE=01`>JnX)WJQwZb$Sg;+sy{&xFgd +zj;(y0hurd*MjwPpwD6?Q0Y_4i{$b~W2~(0PoJ_514m4^g!sYs9FM=2(N}(4N1KU=8 +z67AE>za7f0Jb{d(4<%aoAD^Chgb;rMFO%8hvBI;wmi+VICL7RO>ZV1RX{ME2PfzPh +z(X)&(72iJ{Sxc+4UON0O=ZLYrZV`4Thbz2WEkjMM$0zay^7!mcc%H#NgI5*dTJ*lX +z0RFo?Fpyg;W#>|sl|W@fv#qmyS#W1MIqYh?Gb!>#v|WB?QP6QTIBr&`U><)E*cLZ* +z3&XD?#%#efnPdrPZ6FDAyS%h$hGD#&M4@kWV^AJJwY}ArQhuU|KER@a+N4y&x(+g~ +z#zH9*WmFsi!93@+1Ke8*@sQ2Aui&yt9o)|^{Pr?ST@q-wm+zJ;qT9<8T=0brCzLCT +zSu^*KNMxQYo%Cd!zk660=F34(P9Zmm-3ZFPGIS(H6nk0@u19@g-hg5X8+m3Sd8rF0d{KLdujTNXTN(VRmv@xaSpH_*2 + +delta 15323 +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 +zSkcFBmY||*jr_wU*iejN +z<1{iG856nf^P19XHpOHV2=$-6qOUW3?Gn!`n^P{|h=&yxc_}8IjE$}hyuMS|8Dkis +zVD6b1X$=HWs(?m@m*nr_Fog3vOPYQgTdguBU%NWwEOA6X&!{-xV`LwHeuwcdt!vxX +zuA-h-b65P}7?mI=lU|-Ra`F7JEnQ9bAQdG+MoL*+$BufWPsrf_JB%{1l|2?;O{w-f +z#@T$sOvPD?aSmBR&XBab^hPRU*It2dnrKd#?N-bxY9Qbm16==GCW8gzUnqahb&q}q +zqEwh+EwwqMuka_=3hiw>n$ovwlb1{%6{L=-4v!Uj?+5C$tBRypHLLElJV76U;V@IN +zMmb8Q26L-oG)~L(n@=nK0IH`UW>Iohc3BOBX1q1T=s;O21=zniRTvh4*L(i^q6cXh +zp+Vh|4`^d?B3XL~mb*4ERdN>A&391*M7(>BwF#T`*i{-XOGA#CblJ3ukGe`Wf! +ztDIV|d4ez}!$8sa3E_xD==zS3`Q4)Uj#hvLjXVHfJl=H~T;rVRx<+xbV_^b1w=jz} +z2jaya@EGxxh3l^Fkxo@{d>Y`h(by@hXL%Ph0oo_Qg;RVg;=lMZ#R3t@jUEhUM3M|8 +zjN0tyg8YB9)C5;Ti@y_`vwrmtAyz_@wYM`o7!8YGW#?5k6JWg0W1<=TkBw$>@$0PZA`0hVSN^qp-b4G +zb;gFoOP8eY;Q~>MC0tJlt&)eu{laHK$tH~xua}Zxf4p)dPiXw-+lC;+QKPTJG1Y`XhF!lYRGW`Tl#>;KanNT476H!*j%D>jm&6NtkC6+}isaSGcjReHuP5xmgLn}$SNqP(nrwf*OIPN88M5s_l*zy`_(G=3GoXE2n +zqj;gDlxk0QmvBt%c`|nwNp=MP0_Fl%Cx&{H`TWo#qI}lxMAq>kiA$3WJ)1=Z|JI{G +z9%d7xO{9nQ$`wF~F!$mo1_n!)&f*Er>OwttV)m0TZO5Sy+EN|<-1B{Q>FGUOnKWHa +zaONfo#Lhl+<*F3A#~|?#^t^yeH9qCrt2q>#Kd8smGi2Msf-xP4kj>*}gNvMXYo~Us0eeN{P?s|Sq +z#~`! +zMIAh8yma{Y{soN(2p@(%KuNzq!RPz|Ni +z#Xe?gX}rVA>T+2)%#Tvy1i#{4k0s_FE$Kvho=SvT8DGC4_Vds523hWiB{A5oKA_!J +zxc;8aT~nY-@$yJD&SR<*R}%Gi)o>@g0LQwLLISNw&~M4HHx#kk +zqd7dDzl8&OOMa)StcbO&_-8*DUO`oIa|L)YF(W_ur;-E)-9BNz#2h0)!-`N%Ck*%GE +z*4`e9gPc%ibdof)WT+kXaS>ERCS^eX!+gD%ARuHU|DnCOG<+ar4ko*^U6{HW_F$_Z +zm5&S-Rn56=M-;5MnDniIuZ+%{Daw1*)pW)CU3P0dCFTf$D78f1(}RthXD(3Mo{>>v +z-ZXLyy`JSc$iUrO_2r)rtGgi5C&g{~$s5!4AA(js?QVv-EG`U3!EbcmslTikzD*M} +z3As&$*Kp6e@2NnLC>dpoZl7l&KUkb-1*(mC?I@}ljo+QoM>bBKRT+Asrkx(EF$_cC +zE8sE@mGxO-`7LcjJ-6vzYfPCv{36K>-vC#ACFU1okAN6ZPgqQaK8#deMNN$9dc|o7 +zL)kFBXARN?skkAPjx&P&ct!%j%)K!b$HI$aeq(HqkPkLZ^nb`68VVd)9X5l^j3I@) +zxvhULw_Z+sT>YBF&{ZEwN4+A_c +zPQE2Cq`4^q$pf|3uceiitbW65`UV0I?^tkUI#zV`zi~~O0^U@|+hS)}Phajeux>!i +z_vRYf(<@qqo_T@PhlR3ZC7?V>5zDhTTirocZ@M&SkwaASW?CB=3IsE%=2y#es$p!f +z)6O%?Z7N-SNrWpiUfe +z%F1#z;uQyk)Qnr~^Pd|jZdxdwf5Vg^9Nf=OznQMS9+Ch}X*Po)zqMuoo`uC;Ed`Jy +zuq6$bP7U%Ku5D+1P^M#GCd__X@7fY}vPuIQT$ReM!^af3GbBhP@R98P>PYzGLImdnK$or0`plg=z6pG +zvgEq~4YL3U-)A<+oh@vuH6S7^ML%Hox=lmRx(^kpz!X!&B^fH&Q-!}k9(JUb{TEf9 +zn5z&*Gj6Z7o*Q+NeR{jdwdOL))-mmza$@V3;)$W2deSsB5^6lzA(P$4a=7U|VUv5= +zTGjr^bqt;=hu{9a^C{D}LU_KQU;$(m6QklWY7-Eq=p_06?a7Vl4bvdZJ6h`0bo!Nm +zm~P-9Q0?8l3@=Rx6@O(ooy~n$Ute8KHCNxfck$a>Z^Vh1j!*h*k}oSq1K$j9sorHS +zb2l?n_v0vyfp`m1OqGC=Z_fuVq|(HX%tF@xKB0&4tBuP~_21mNNRP_2kA1N7vO4BE +z*E+y$0GX^B_`L2%JS1U+52tsCHEUg>g0RpMn%9YYh{34^!@pWFCtN>%<8Q#8s2}5q +z;{i53X*n&!g1abNUept$n3Wxg9Y_9115mRsXes@({`|g$dS0{&G +zbi!Ardb>G0rXr{kH`*v)xTRVeuYcQ>y9ZECxRQ1XoQcb_ADtFB;;Wv0I|YjOk!I+p +zja-?t7*?R@38+X`x#GbT!;xhM)+B!8=iqVbd{s{Kj)kSnO8pDH`P^rZ2(Crl>XGeQ +z_r1rt*wSbmKnnj>x3`arYcfC&W16)xj&~;n?I!&D)Aph1iD!kd<{y@^X(|n2qFzfVx4MZ{}dJ4s+!K&zi!^HdJ=E2{QXbQJk;)~$L?U9z#}=G +z@OC54ezTnHr|-4i$ZtKKJhLv*&2T++gW_Vw(p}@i>jE*f`CV7ODe!fjO-?e>PY-f3c{;1Lhq0dD>aGh7-*s|Vnd9?o7pEZQ)10kh2T>3DdUD%-Y&iL_5cQ%;5EeHQzX92 +z=RcQBr|BrLjWYw=tSZhl)uhG8MziK|=oc=&NDN$O^LAI=Xdp4OyUKroqFL_!sT|rp +zgoa9BoRqJB9QI#1JE_YftYZrpX^P~01V4c*t#Z1iX1Ar!XoH7L&(!@B`g0-@5o)2C +zF8y{CD!IhdH~;f9eE@jQ9Vo%+!;n7M=jnzq(Hl8s)_cB~3^`zNwt633fq)Es5drtA +zvY8dFk0`|#f-hOYUK1CaOG;;h9mEbxy0foa?+eQ&(^EJ?G}^F2xov5m#Hjhmx#+qbn(ay!jOI6bV?}df6E$3nbc0N56(F16B4iFAN`PwVH9YEmK +zPY>|Q=~2-@inYnWW@%V2y}-H*NfSsU#yF|mPB%}QXf5xi{z+CdqIhZd%L@hLn-LXR +zZP(SE(Wi%FG3>#jo*r^@x)_YiN9VT1Kk~E+wjm8{R^yrdU|dylMyKj;pA#+Nin8D%QJS^N$?SMeKH +zt-Q#1QN6_!>@%Gj$?}<3V$=BFWi}G$;y-UScaDWBUYQ%R4*p6Xy|xjk;ZY~>2e5As +z;P(}Xrzw($noYf#{c7VBJiG^g{bQ}QQz%FZ<_YZ7!Q1Aku8l=TEWtd^_4w4#c_xOe +zdNJqz0BErd{RW>gi}*w5VN4QpG&Vzy{92l^Dsdx^;4vQ|XVO0N-LcvK70UHQ!F=ao +z(5mTCHEze_WvU146$~YuEw@>0%S>hAO+rK{VldzHu5|p2YPJvhn$RS?h^WT^wzDg!l^f4&MV&dV>&0ku%O9{ya2YBJwuxozLJnK4Zm$gEl>mD +zW4OkvwLgpyGFh`)>*zIla+@8 +zKOYwc69)ayt!~h}Z9lq++iAz61KyR)P%mJI#<5jKuSTnVfz-uLm}o*wM1X%}$LSW- +zb2_zzfiG$x)t-#jzx;$>KK{POR +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 +zOk_JwIpS;#Mm+q#(Hc+TD*@v9GEHL>K%ZDM +zYGWiPa7XnYo-I0&_?Mi1{zNgM5n%(PA5vNr!Eaox3IZM^a-MfyX{_TNJ~1?RwNac3 +zBS^*<|06oTZ7QDE|Ic`T$$wj{cFR>h;Fs`2y?BnNAUd=c1D@6(4uSd}TPH_KyIo%b +zy0@2x6Q|_2d3(VV3?H;|Ma-auX>lhU<=k~ap_W0dP`+}P}N$V;zYpMR2gg{UaIBDJ3Vg@)`R +zAngzMEvDe^4d7oZbZ?b{JuGNgQc%)u;Vq3DY%5$)7?Xxi_{ov=Ytnh{Z^`L#4jf77 +zitGtjFn1B5t=C)RED8pGf~9WYxBJXfl1$3(jdXxs^lU&$c4$oxWl`L +zVF{KSD*du;^d2>jKMJNU^!yR&PzS^h%l>5UY2b2T49 +zs%w_9kQ0Ks+vh-)mKRDn&~OYHpuw{HaQCb2Z4Wxki6x%9*!;r(QiR)ww!eT)Ez4+` +zzWQfT;}K-uS9U9jns_BSrK@>f`x99%>_CmJ5V(Yu*&1>SwK;2sgY9p-Y28cgZFcmN +zK=lD3xoAFx%1e`pKKhrdCwjfx%H>B!io4Bcww~OgGyaHU->EayfhJf%m&x7s9iQgk +zOWr)ZdbTDLw&RK7NAaV@n_NlJ9AVUULAAO@eLX2P>=V(@aLXJ@&-(qIGvvc)KNBHQ +z0eHSz%ik4w|Fl$#U9-SU|ynCK9^ +zS>SxtW_B3L?kXe*=_@d&f<@Q5LvKX<3rIDT>*-?cR{s|z?g&!PnGK*(vj!r(3!w7~ +zu&Z~d4jf2ss5KXarYl87Oo7WD;k0-ex#3i?F6#Z=*~isr5<2jIt(g4%F8y*Ye><6H +z9jPrco`JlrcvBi;HGPUK;_ks!HpMYYXA%`dd6pt)*m%Yq`^2?%?+X&Gyc|JI5BTBZ +z=1|AMnS_5zGucUcui!`Hw2CNr#13u9(jD#|jtd0~pWNPx)iaI&Ar!~Sah~-%GYD&n1$BE!s{`T +zzfwAK3~Pv=nIpi7O26Ac>TUoBcz#1=BnLQsb+1WwE!r?a-gMZqGeyw8yAV><9ZRT1C +z)snGRXkdm4_tXd7VJ-Gln!%D5=${U#e0Cts^tWW7d=EtH=Bf3gye4U_#rSFNAO}gt +zZpGvp$2#Dfqd(K-=!^eD>cxC)MsGNW_svo9my|+7xASI5sP`JqbX~TV(T^JyrDy{u +z33?pHyL8p9j#UdW#*kA$j@2`J7vZny&z!$2P(NGx>B#vPhI`W<5HI!Y-uAhaDw029 +zg*C}eT%c*<=2>L!P~>YImo3EQ0^BqOqIPLeIix5=##1jyrb{JlM#VrX1=-q=>`f-} +zkD1o#48){}NkWc(TxxC?zrA%)Nw4+L!(-pmf?Sn>;*$`_2o2c)KeyGy@+Pz6dhe1f +zV#R{YTI9Li@6oyb#AtJ17<(CV@6Y5^p|+URhhh)X)JJ>G6w@a*90%WaQki>{otn$$W=aVu +zEhcoGl)gtrt~yaWY!NczD63!Ud4FKkd7&!Re_98*U+v!7{H@fO6UoF<)2qI%FR7G$ +z1}-3%mHj&g?prOqOTAv&VyG*{<=<^>#Ntzkg=q>mg!QEWFH{a;j0h>RT?mM_Kv@|H +zN{|aWjI+u3To)YXnvT*4D9iP8aRTN>7QrmmNv3Z| +zoDRuE0Do8}UP@wEpP0GfXR7t_A@ly1Yic)N?>Z=o;wR^GKlYq|`zR6xf-_S1XuDe$ +z#Y$XSt8*qmX$M><6WVKpG8L_?hkY&ecLwxq1!<()PI>;Jr7dl}{gr!n|8l?)g4Q79 +zn0Pl;DaOV$RZbM171uewbqoJ1en&eYXeZ^FU=(HL;4#pz8r(%MPSTVhflpdVP_X?6 +z8^E)+4M6yl?^Gl)2_uU-TH#dYoCag*6WYiAQ?0&#*>O!PU^^$XHM= +zuUuO%3T<6v)sd@rV=ZMe~D}l1-)SftP0&8=yG9| +zT@846mp6|ebN?|MPcjIJE={<(3jA;xpq*JxvSSj!sMyxZ8Ru@OTgUv-!7;bb>G8Wl +zc?AaOuu7teX+ECbv0y#cF{w5hF!(Ee`MBJ4kTLI7F%tyekP`ox|AP`0UuOsm3D(|- +z%d5oytQyYbhK})!?GG@$ +zhJ2Jj$#>+EZ*_8=Zz+_iM((C(@1}bkl^zTbg{lK!l}G!}N&Ms4xiw`h-0&_5U_)p+ +z{fyvUG{M%1QC@c_B69dr%={>-Sx1pML_9AHi-_@)#B?}|Ilv%EC@3p);O-2r_E3f8 +z$EN?fkKVd1*xnEAyk#Wg42FuQo&Gb=xo*r#uA{$J{ww7kWadyrnXV*XBlFczO7{fv^-OhSfy0Ms>as{QJx?grk&};DOW&zs>%Mae +zJg72hVlj|tt(h8sXIvQ_Yd5#bi)yEhG$NPuJ8EQGnN)$R&w32BXboaj-0ZH1ff+3H +zo9?=2y_U;|;*5k{`1fV=@dfPa#?2`hP%{MZA0+tB!9kn3%G>mXI_(hq;Ceu(o*L$7 +z`$Im>S0eF;lw(&EW2{o*=Y>xpG_JzpCF-XtOlmt<}DzOgWcd01C>AkWMw4->sY-3@LeZbaDisvzU~ +zFDSfm4JxzMCiEI-%NOUNTS2Iuv>8@g0tIxRa +zF3uUR1w{Qo)DGcz)Y}A0NV07QZWu_WIlITP6O+hiX$ZS${M{RXO%7z~B$jgHQc +z*3E1XJ|$0tgYvAkO2_MTe=a3+sFwr^(O5F2-yweqwdDa}is?aujxd-enzI>Djy{%b*n@7t|KGbVdYwSZd&r +z2w^D6ET1=oCq6!I#G@-NL;VV~j|rg2Q(-SsqU0Wz&W3XY^KxxZ`_r+#jPhpr?-lG8 +zq5-RaH`hr*l5s(C0r7|ZDOFJ`&hN%wr$M)M`E5^H7t+A=zZ)eR+D#B2#a36F4h?^6 +z0~qxW(L!rHDa^l9EFUxEQ;Xc>SYeqx!M}KVm`%6`QlQ*>zb+BVq6X-4i;vVU19vVS +zVkW!U!g0oAsYt(cQT$#_K9*z0mz3Z6W=zavo9r|nd`bmOeF|@RYStMWuZtocpbx9r +zFi)BpnVf*VGh^_KT>tz-SlKwuFmnHn*MTPW?_6;f-YFy}-WwSrC={Vhh3}u?YG)_O +z$H;+v+aXs^!go^@Dz3goJUv==#>a)zBWs_i_C$d3W+gt!*g(UptbzNBTw*3Y3cstv +zku`1O-kiM>g@t%-T>JMh?-r>I{L!Hbo||^DT$VbHEhM8ztwP*sN7t$~jPrDhM4vD= +zQagwr~W#!wIhRQ3$&qlEIp?ORBjjJtxHk0`_oV?OcBBOGlHi%9V9BT*)ueUEx +z)=R)(wg|o()GAyQ!a5Zed3P?VB}w*eFnm#Z4Nep)cO>3X&An%`$@a?Gjln%oiZUD7 +z%?laoOtTCgp`E5kl#q_}$rhX)23z2*?zmUuQZPXEhqmNA=_#?^)E!RekAv7ZYtl4` +zcKOU>B!wWGdG+H5%`Qrx+sTqysl~lk_H=4^5%*7&zv%qg!E2>SBLcl_Z!(h%N +zog{-Ax9D9-=<0xz3qj-FQ8gXukB#yqbxZLtolE`#aV`)+Q@wwYMx`GqViR|KWMMV4 +zsP+!E;C(jJW#t21;gI<8nhhIh;|nV4vo_6 +z5zWWiUWWfs{22bWN(N2oQxwv2-A8op%vUk=(au5I!tB&g$;ZhQ@wZ@fUYKt#3YuG3MJlBAl2sJ{eXSgYM<(XTMwbh9t4_`+U6x`E$92gYNqZK3NTYiYWQpWKv87U^6v6*gCN7Sm| +z4aC?a;AGxK4Qh90k}#s!Hx-!AFBfSD3qhs+Bib*dkhjW9*}Pd*l%QB!K&|}4n; +z>a%Dk7u*V`3d#l#U=VVN5aJu$cm6U8eXO?`Tc+WFNOBV&tieRb4d +zK1GVNW0@aXML;Q$!ImBb#aaX+yfavNfKh3Ww7a#Ie}tIjBn)q?NkEFq74tI6pPX-^ +z@9gi%3CB?$;$T7RO`?Z8;%ky5rHOiuwftedQ)7m+Udj7lX&`AwqVIBEY%pO-Bd?+? +zb0WuRGf_2`uUD-_M$IHmUuC>qrhe+8-_iMt@dTcIhj64a)c-A8#C-s +qY&_HPxxa^jYRmZ$u5sbv$igCr8@?@z^~FvNs#xi?4b2+CwEqMBF~yDm + +diff --git a/amd-ucode/microcode_amd_fam19h.bin.asc b/amd-ucode/microcode_amd_fam19h.bin.asc +index 8cff9013..3955e529 100644 +--- a/amd-ucode/microcode_amd_fam19h.bin.asc ++++ b/amd-ucode/microcode_amd_fam19h.bin.asc +@@ -1,11 +1,11 @@ + -----BEGIN PGP SIGNATURE----- + +-iQEzBAABCgAdFiEE/HxsUF2vzBRxg1fK5L5TOfMornMFAmTEYrcACgkQ5L5TOfMo +-rnN4IQf/QKbOezXZ4OYzaPANvsZQEAzLNfuylC/aQMwrPaO7daz5/zmCN4HU5XkH +-dDT8DYfPg+fQHIgxAw0/L24xPOm5Op/QuLVDyDqVr4qvL8+65eeI+JqxD/wXMXYN +-V34kkLM2p8iuyY1Nc8IDLXu4X75KGNPbKZlMRKMU3Pr7ai5O4ihmiAM+N6qv1KEJ +-YToNN6vrg0qt1cv0SLM8sa4e7L1+oblUrg/o0FViYE8pxsU3ZRRVSJMUg+lKjvl/ +-1ZPGKOdD80fcNJ+ItYGHNNs3eCc3WgW7Kc/E668eH75Yu9Zt7ewWZX8Sg/mygleY +-OzMwhbPJg4bF4zm7C/Pku7i1T2Omcg== +-=km2X ++iQEzBAABCgAdFiEE/HxsUF2vzBRxg1fK5L5TOfMornMFAmUoW6AACgkQ5L5TOfMo ++rnMHAAf/SxaKEu5l7FGXR+QJYc2oSJDpf9ZsHTkVnxqF1I3ReItEGAR3iqSWrsRw ++KA4niP9Ihr8EqwhOaOtqkRKKF9D5yg+DksnRWbh2VTUECO4KQxjHNrPp3JWEzBwb ++Xn+vRVP02ZRi3u4MCYbnDC4AfUSnKnldY3TTlNi/6HUaGS2pcw8Vjli/C06zwfgh ++WwUAoFMQl4SDJhbGfC9cb93MKjBl/0Hv4uhK5W8fJ1iUkMvY8Ijna/oDTZCNPqP0 ++0AgOwdAdzoyOYWjbUXcwofz2Umpz12xmJW8yXNwdv1pmaCvv9aCJz1L49lGwFH9E ++lhhoFQ1SQL3hhPjTXO6DbeeT9+fjOg== ++=9Xav + -----END PGP SIGNATURE----- +-- +2.41.0 + diff --git a/SOURCES/amd_ucode_info.py b/SOURCES/amd_ucode_info.py deleted file mode 100755 index 8186cbc..0000000 --- a/SOURCES/amd_ucode_info.py +++ /dev/null @@ -1,374 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: MIT License -# Copyright (C) 2020 Advanced Micro Devices, Inc. - -""" -Parse an amd-ucode container file and print the family, model, stepping number, -and patch level for each patch in the file. The --extract option will dump the -raw microcode patches to a provided directory. -""" - -import argparse -import sys -import os - -from collections import namedtuple -from collections import OrderedDict - -EQ_TABLE_ENTRY_SIZE = 16 -EQ_TABLE_LEN_OFFSET = 8 -EQ_TABLE_OFFSET = 12 -EQ_TABLE_TYPE = 0 -PATCH_TYPE = 1 - -VERBOSE_DEBUG = 2 - -FMS = namedtuple("FMS", ("family", "model", "stepping")) -EquivTableEntry = namedtuple("EquivTableEntry", ("cpuid", "equiv_id", "data", "offset")) -PatchEntry = namedtuple("PatchEntry", ("file", "offset", "size", "equiv_id", "level")) - -def read_int32(ucode_file): - """ Read four bytes of binary data and return as a 32 bit int """ - return int.from_bytes(ucode_file.read(4), 'little') - -def read_int16(ucode_file): - """ Read two bytes of binary data and return as a 16 bit int """ - return int.from_bytes(ucode_file.read(2), 'little') - -def read_int8(ucode_file): - """ Read one byte of binary data and return as a 8 bit int """ - return int.from_bytes(ucode_file.read(1), 'little') - -def cpuid2fms(cpu_id): - family = (cpu_id >> 8) & 0xf - family += (cpu_id >> 20) & 0xff - - model = (cpu_id >> 4) & 0xf - model |= (cpu_id >> 12) & 0xf0 - - stepping = cpu_id & 0xf - - return FMS(family, model, stepping) - -def fms2str(fms): - return "Family=%#04x Model=%#04x Stepping=%#04x" % \ - (fms.family, fms.model, fms.stepping) - -def parse_equiv_table(opts, ucode_file, start_offset, eq_table_len): - """ - Read equivalence table and return a list of the equivalence ids contained - """ - table = {} - raw_table = [] - # For sanity check only - cpuid_map = {} - - table_item = start_offset + EQ_TABLE_OFFSET - table_stop = start_offset + EQ_TABLE_OFFSET + eq_table_len - - while table_item < table_stop: - ucode_file.seek(table_item, 0) - data = ucode_file.read(EQ_TABLE_ENTRY_SIZE) - ucode_file.seek(table_item, 0) - - cpu_id = read_int32(ucode_file) - - if opts.verbose >= VERBOSE_DEBUG: - errata_mask = read_int32(ucode_file) - errata_compare = read_int32(ucode_file) - else: - # Skip errata mask and compare fields - ucode_file.seek(8, 1) - - equiv_id = read_int16(ucode_file) - if opts.verbose >= VERBOSE_DEBUG: - res = read_int16(ucode_file) - - if equiv_id != 0: - if equiv_id not in table: - table[equiv_id] = OrderedDict() - - if cpu_id in table[equiv_id]: - print("WARNING: Duplicate CPUID %#010x (%s) in the equivalence table for equiv_id %#06x " % - (fms2str(cpuid2fms(cpu_id)), equiv_id)) - - if cpu_id in cpuid_map: - if equiv_id != cpuid_map[cpu_id]: - print("WARNING: Different equiv_id's (%#06x and %#06x) are present in the equivalence table for CPUID %#010x (%s)" % - (equiv_id, cpuid_map[cpu_id], cpu_id, - fms2str(cpuid2fms(cpu_id)))) - else: - cpuid_map[cpu_id] = equiv_id - - entry = EquivTableEntry(cpu_id, equiv_id, data, table_item) - table[equiv_id][cpu_id] = entry - raw_table.append(entry) - - if opts.verbose >= VERBOSE_DEBUG: - print(" [equiv entry@%#010x: cpuid %#010x, equiv id %#06x, errata mask %#010x, errata compare %#010x, res %#06x]" % - (table_item, cpu_id, equiv_id, errata_mask, errata_compare, res)) - - table_item += EQ_TABLE_ENTRY_SIZE - - return (table, raw_table) - -def extract_patch(opts, out_dir, ucode_file, patch, equiv_table=None): - """ - Extract raw microcode patch starting at patch_start to the directory - provided by the -o option or the current directory if not specified. - Directory will be created if it doesn't already exist. - """ - cwd = os.getcwd() - - if not os.path.exists(out_dir): - os.makedirs(out_dir) - - os.chdir(out_dir) - - if equiv_table is None: - # Raw patch - out_file_name = "mc_patch_0%x.bin" % patch.level - else: - out_file_name = "mc_equivid_%#06x" % patch.equiv_id - for cpuid in equiv_table[patch.equiv_id]: - out_file_name += '_cpuid_%#010x' % cpuid - out_file_name += "_patch_%#010x.bin" % patch.level - - out_path = "%s/%s" % (os.getcwd(), out_file_name) - out_file = open(out_file_name, "wb") - - os.chdir(cwd) - - if equiv_table is not None: - cpuids = equiv_table[patch.equiv_id].values() if patch.equiv_id in equiv_table else [] - else: - cpuids = None - - write_mc(opts, out_file, [patch], ucode_file, cpuids) - - out_file.close() - - print(" Patch extracted to %s" % out_path) - -def merge_mc(opts, out_path, table, patches): - # Do some sanity checks, ut only warn about the issues - equivid_map = {} - cpuid_map = {} - - for entry in table: - if entry.equiv_id not in equivid_map: - equivid_map[entry.equiv_id] = dict() - - if entry.cpuid in equivid_map[entry.equiv_id]: - print("WARNING: Duplicate CPUID %#010x (%s) in the equivalence table for equiv_id %#06x " % - (fms2str(cpuid2fms(entry.cpuid)), entry.equiv_id)) - else: - equivid_map[entry.equiv_id][entry.cpuid] = entry - - if entry.cpuid in cpuid_map: - if entry.equiv_id != cpuid_map[entry.cpuid]: - print("WARNING: Different equiv_id's (%#06x and %#06x) are present in the equivalence table for CPUID %#010x (%s)" % - (entry.equiv_id, cpuid_map[entry.cpuid], entry.cpuid, - fms2str(cpuid2fms(entry.cpuid)))) - else: - cpuid_map[entry.cpuid] = entry.equiv_id - - with open(out_path, "wb") as out_file: - write_mc(opts, out_file, patches, equiv_table=table) - - print("Microcode written to %s" % out_path) - -def write_mc(opts, out_file, patches, ucode_file=None, equiv_table=None): - """ - Writes microcode data to the specified file. - """ - if equiv_table is not None: - # Container header - out_file.write(b'DMA\x00') - - # Equivalence table header - out_file.write(EQ_TABLE_TYPE.to_bytes(4, 'little')) - table_size = EQ_TABLE_ENTRY_SIZE * (len(equiv_table) + 1) - out_file.write(table_size.to_bytes(4, 'little')) - - # Equivalence table - for cpuid in equiv_table: - out_file.write(cpuid.data) - - out_file.write(b'\0' * EQ_TABLE_ENTRY_SIZE) - - for patch in patches: - # Patch header - if equiv_table is not None: - out_file.write(PATCH_TYPE.to_bytes(4, 'little')) - out_file.write(patch.size.to_bytes(4, 'little')) - - if ucode_file is None: - in_file = open(patch.file, "rb") - else: - in_file = ucode_file - - in_file.seek(patch.offset, 0) - out_file.write(in_file.read(patch.size)) - - if ucode_file is None: - in_file.close() - -def parse_ucode_file(opts, path, start_offset): - """ - Scan through microcode container file printing the microcode patch level - for each model contained in the file. - """ - table = None - patches = [] - - with open(path, "rb") as ucode_file: - print("Microcode patches in %s%s:" % - (path, "+%#x" % start_offset if start_offset else "")) - - # Seek to end of file to determine file size - ucode_file.seek(0, 2) - end_of_file = ucode_file.tell() - - # Check magic number - ucode_file.seek(start_offset, 0) - if ucode_file.read(4) != b'DMA\x00': - print("ERROR: Missing magic number at beginning of container") - return (None, None, None) - - # Check the equivalence table type - eq_table_type = read_int32(ucode_file) - if eq_table_type != EQ_TABLE_TYPE: - print("ERROR: Invalid equivalence table identifier: %#010x" % - eq_table_type) - return (None, None, None) - - # Read the equivalence table length - eq_table_len = read_int32(ucode_file) - - ids, table = parse_equiv_table(opts, ucode_file, start_offset, eq_table_len) - - cursor = start_offset + EQ_TABLE_OFFSET + eq_table_len - while cursor < end_of_file: - # Seek to the start of the patch information - ucode_file.seek(cursor, 0) - - patch_start = cursor + 8 - - patch_type_bytes = ucode_file.read(4) - # Beginning of a new container - if patch_type_bytes == b'DMA\x00': - return (cursor, table, patches) - patch_type = int.from_bytes(patch_type_bytes, 'little') - if patch_type != PATCH_TYPE: - print("Invalid patch identifier: %#010x" % (patch_type)) - return (None, table, patches) - - patch_length = read_int32(ucode_file) - if opts.verbose: - data_code = read_int32(ucode_file) - else: - ucode_file.seek(4, 1) - ucode_level = read_int32(ucode_file) - if opts.verbose >= VERBOSE_DEBUG: - mc_patch_data_id = read_int16(ucode_file) - mc_patch_data_len = read_int8(ucode_file) - init_flag = read_int8(ucode_file) - mc_patch_data_checksum = read_int32(ucode_file) - nb_dev_id = read_int32(ucode_file) - sb_dev_id = read_int32(ucode_file) - else: - ucode_file.seek(16, 1) - equiv_id = read_int16(ucode_file) - if opts.verbose >= VERBOSE_DEBUG: - nb_rev_id = read_int8(ucode_file) - sb_rev_id = read_int8(ucode_file) - bios_api_rev = read_int8(ucode_file) - reserved1 = [read_int8(ucode_file) for _ in range(3)] - match_reg = [read_int32(ucode_file) for _ in range(8)] - - if opts.verbose: - add_info = " Start=%u bytes Date=%04x-%02x-%02x Equiv_id=%#06x" % \ - (patch_start, data_code & 0xffff, data_code >> 24, - (data_code >> 16) & 0xff, equiv_id) - else: - add_info = "" - - if equiv_id not in ids: - print("Patch equivalence id not present in equivalence table (%#06x)" - % (equiv_id)) - print(" Family=???? Model=???? Stepping=????: Patch=%#010x Length=%u bytes%s" - % (ucode_level, patch_length, add_info)) - - # The cpu_id is the equivalent to CPUID_Fn00000001_EAX - for cpuid in ids[equiv_id]: - print(" %s: Patch=%#010x Length=%u bytes%s" - % (fms2str(cpuid2fms(cpuid)), ucode_level, patch_length, add_info)) - - if opts.verbose >= VERBOSE_DEBUG: - print(" [data_code=%#010x, mc_patch_data_id=%#06x, mc_patch_data_len=%#04x, init_flag=%#04x, mc_patch_data_checksum=%#010x]" % - (data_code, mc_patch_data_id, mc_patch_data_len, init_flag, mc_patch_data_checksum)) - print(" [nb_dev_id=%#010x, sb_dev_id=%#010x, nb_rev_id=%#04x, sb_rev_id=%#04x, bios_api_rev=%#04x, reserved=[%#04x, %#04x, %#04x]]" % - (nb_dev_id, sb_dev_id, nb_rev_id, sb_rev_id, bios_api_rev, reserved1[0], reserved1[1], reserved1[2])) - - patch = PatchEntry(path, patch_start, patch_length, equiv_id, ucode_level) - patches.append(patch) - - if opts.extract: - extract_patch(opts, opts.extract, ucode_file, patch) - - if opts.split: - extract_patch(opts, opts.split, ucode_file, patch, ids) - - cursor = cursor + patch_length + 8 - - return (None, table, patches) - -def parse_ucode_files(opts): - all_tables = [] - all_patches = [] - - for f in opts.container_file: - offset = 0 - while offset is not None: - offset, table, patches = parse_ucode_file(opts, f, offset) - if opts.merge: - if table is not None: - all_tables += table - if patches is not None: - all_patches += patches - - if opts.merge: - merge_mc(opts, opts.merge, all_tables, all_patches) - -def parse_options(): - """ Parse options """ - parser = argparse.ArgumentParser(description="Print information about an amd-ucode container") - parser.add_argument("container_file", nargs='+') - parser.add_argument("-e", "--extract", - help="Dump each patch in container to the specified directory") - parser.add_argument("-s", "--split", - help="Split out each patch in a separate container to the specified directory") - parser.add_argument("-m", "--merge", - help="Write a merged container to the specified file") - parser.add_argument("-v", "--verbose", action="count", default=0, - help="Be verbose about the information in the container file") - opts = parser.parse_args() - - for f in opts.container_file: - if not os.path.isfile(f): - parser.print_help() - print() - print("ERROR: Container file \"%s\" does not exist" % f) - sys.exit() - - return opts - -def main(): - """ main """ - opts = parse_options() - - parse_ucode_files(opts) - -if __name__ == "__main__": - main() diff --git a/SPECS/linux-firmware.spec b/SPECS/linux-firmware.spec index 077fcb6..e4f7d12 100644 --- a/SPECS/linux-firmware.spec +++ b/SPECS/linux-firmware.spec @@ -1,6 +1,6 @@ %global checkout 0e048b06 -%global firmware_release 119 +%global firmware_release 120 %global _firmwarepath /usr/lib/firmware %define _binaries_in_noarch_packages_terminate_build 0 @@ -18,7 +18,14 @@ BuildArch: noarch # This is still causing problems in RHEL9 (see bug 1959913) and because of that we should keep out of RHEL8 too # 2) git archive --worktree-attributes --format=tar --prefix=linux-firmware-%%{checkout}/ %%{checkout} | xz > linux-firmware-%%{version}.tar.xz Source0: %{name}-%{version}.tar.xz -Source1: amd_ucode_info.py + +# Patches generated below were created with git running in the linux-firmware +# upstream repository. +# Latest AMD microcode addressing CVE-2023-20569, with WHENCE hunk excluded. +# The patches were generated with: +# git format-patch --keep-subject d252e92d50c02623ea9da0a140240f6d7ac4558e^..06afd7f939c5b245b2af9e0fee13026f2aaf77fa amd-ucode/ +Patch01: 0001-linux-firmware-amd-ucode-Add-note-on-fam19h-warnings.patch +Patch02: 0002-linux-firmware-Update-AMD-cpu-microcode.patch Provides: kernel-firmware = %{version} xorg-x11-drv-ati-firmware = 7.0 Obsoletes: kernel-firmware < %{version} xorg-x11-drv-ati-firmware < 6.13.0-0.22 @@ -42,7 +49,6 @@ Conflicts: microcode_ctl < 2.1-0 Obsoletes: ivtv-firmware < 2:20080701-28 BuildRequires: git make -BuildRequires: python3 %description This package includes firmware files required for some devices to @@ -259,33 +265,18 @@ License: Redistributable, no modification permitted Firmware for Marvell Libertas SD 8787 Network Adapter %prep -%setup -q -n linux-firmware-%{checkout} - -# Repack AMD Family 19h microcode -/usr/bin/python3 %{SOURCE1} -vv -s amd-ucode/fam19 amd-ucode/microcode_amd_fam19h.bin -rm -rvf amd-ucode/fam19/*cpuid_0x00aa0f0*.bin -/usr/bin/python3 %{SOURCE1} -vv amd-ucode/fam19/* -m amd-ucode/microcode_amd_fam19h.bin -/usr/bin/python3 %{SOURCE1} -vv amd-ucode/microcode_amd_fam19h.bin -rm -rvf amd-ucode/fam19 - -%if 0 -git init . -if [ -z "$GIT_COMMITTER_NAME" ]; then - git config user.email "nobody@fedoraproject.org" - git config user.name "Fedora linux-firmware packagers" -fi -git add . -git commit -m init . - -git am %{patches} - -%endif +%autosetup -S git -p1 -n linux-firmware-%{checkout} %build %install mkdir -p $RPM_BUILD_ROOT/%{_firmwarepath} mkdir -p $RPM_BUILD_ROOT/%{_firmwarepath}/updates + +# Move amd-ucode readme to docs directory due to dracut issue (RHEL-16800) +mkdir -p %{buildroot}/%{_defaultdocdir}/%{name}/amd-ucode +mv -f amd-ucode/README %{buildroot}/%{_defaultdocdir}/%{name}/amd-ucode + make DESTDIR=%{buildroot}/ FIRMWAREDIR=%{_firmwarepath} install pushd $RPM_BUILD_ROOT/%{_firmwarepath} @@ -434,10 +425,18 @@ sed -e 's/^/%%dir /' linux-firmware.dirs >> linux-firmware.files %files -f linux-firmware.files %dir %{_firmwarepath} +%doc %{_defaultdocdir}/%{name} %license WHENCE LICENCE.* %config(noreplace) %{_firmwarepath}/netronome/nic_AMDA* %changelog +* Fri Nov 17 2023 Patrick Talbert - 20230824-120.git0e048b06 +- Move amd-ucode README to docs directory due to dracut issue (RHEL-16800) +- Update AMD cpu microcode from upstream 06afd7f939c5 (RHEL-16783) +- Update amd-ucode/README from upstream d252e92d50c0 (RHEL-16783) +- Revert 'Exclude AMD cpu ucode for fam19/*cpuid_0x00aa0f0*' +Resolves: RHEL-16783, RHEL-16800 + * Tue Sep 26 2023 Patrick Talbert - 20230824-119.git0e048b06 - Exclude AMD cpu ucode for fam19/*cpuid_0x00aa0f0* Resolves: RHEL-3903