aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Shin <jacob.shin@amd.com>2013-06-20 10:52:50 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2013-06-26 17:55:37 -0400
commit9608d33b8210c993af4430d661a6474946480c9b (patch)
treeda966e44d9cc8a01e552cb26a9e964d4ca7fa769
parentcd1c32ca969ebfd65e61312c988223bb14f09c2e (diff)
x86, microcode, amd: Another early loading fixup
commit cd1c32ca969ebfd65e61312c988223bb14f09c2e is an early premature rendition of the patch. Augment it with this delta patch to: * correctly mark offset and size of the matching bin file * use __pa instead of __pa_nodebug during AP load * check for !initrd_start before using it Signed-off-by: Jacob Shin <jacob.shin@amd.com> Link: http://lkml.kernel.org/r/20130620152414.GA6676@jshin-Toonie Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/kernel/microcode_amd_early.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c
index 4c593c276114..1ac6e9aee766 100644
--- a/arch/x86/kernel/microcode_amd_early.c
+++ b/arch/x86/kernel/microcode_amd_early.c
@@ -143,13 +143,17 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size)
143 left -= offset; 143 left -= offset;
144 } 144 }
145 145
146 offset = data - (u8 *)ucode; 146 /* mark where the next microcode container file starts */
147 offset = data - (u8 *)ucode;
147 *uoffset += offset; 148 *uoffset += offset;
148 *usize -= offset; 149 *usize -= offset;
150 ucode = data;
149 } 151 }
150 152
151 if (!eq_id) 153 if (!eq_id) {
154 *usize = 0;
152 return; 155 return;
156 }
153 157
154 /* find ucode and update if needed */ 158 /* find ucode and update if needed */
155 159
@@ -166,15 +170,21 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size)
166 mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE); 170 mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
167 if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) 171 if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id)
168 if (__apply_microcode_amd(mc) == 0) { 172 if (__apply_microcode_amd(mc) == 0) {
169 if (!(*new_rev)) 173 rev = mc->hdr.patch_id;
170 *new_rev = mc->hdr.patch_id; 174 *new_rev = rev;
171 break;
172 } 175 }
173 176
174 offset = header[1] + SECTION_HDR_SIZE; 177 offset = header[1] + SECTION_HDR_SIZE;
175 data += offset; 178 data += offset;
176 left -= offset; 179 left -= offset;
177 } 180 }
181
182 /* mark where this microcode container file ends */
183 offset = *usize - (data - (u8 *)ucode);
184 *usize -= offset;
185
186 if (!(*new_rev))
187 *usize = 0;
178} 188}
179 189
180void __init load_ucode_amd_bsp(void) 190void __init load_ucode_amd_bsp(void)
@@ -204,19 +214,20 @@ void __cpuinit load_ucode_amd_ap(void)
204 size_t *usize; 214 size_t *usize;
205 void *ucode; 215 void *ucode;
206 216
207 mc = (struct microcode_amd *)__pa_nodebug(amd_bsp_mpb); 217 mc = (struct microcode_amd *)__pa(amd_bsp_mpb);
208 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { 218 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
209 __apply_microcode_amd(mc); 219 __apply_microcode_amd(mc);
210 return; 220 return;
211 } 221 }
212 222
213 initrd = (unsigned long *)__pa_nodebug(&initrd_start); 223 initrd = (unsigned long *)__pa(&initrd_start);
214 uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); 224 uoffset = (unsigned long *)__pa(&ucode_offset);
215 usize = (size_t *)__pa_nodebug(&ucode_size); 225 usize = (size_t *)__pa(&ucode_size);
216 if (!*usize) 226
227 if (!*usize || !*initrd)
217 return; 228 return;
218 229
219 ucode = (void *)((unsigned long)__pa_nodebug(*initrd) + *uoffset); 230 ucode = (void *)((unsigned long)__pa(*initrd) + *uoffset);
220 apply_ucode_in_initrd(ucode, *usize); 231 apply_ucode_in_initrd(ucode, *usize);
221} 232}
222 233
@@ -250,7 +261,7 @@ void __cpuinit load_ucode_amd_ap(void)
250 if (cpu && !ucode_loaded) { 261 if (cpu && !ucode_loaded) {
251 void *ucode; 262 void *ucode;
252 263
253 if (!ucode_size) 264 if (!ucode_size || !initrd_start)
254 return; 265 return;
255 266
256 ucode = (void *)(initrd_start + ucode_offset); 267 ucode = (void *)(initrd_start + ucode_offset);
@@ -278,10 +289,7 @@ int __init save_microcode_in_initrd_amd(void)
278 pr_info("microcode: updated early to new patch_level=0x%08x\n", 289 pr_info("microcode: updated early to new patch_level=0x%08x\n",
279 ucode_new_rev); 290 ucode_new_rev);
280 291
281 if (ucode_loaded) 292 if (ucode_loaded || !ucode_size || !initrd_start)
282 return 0;
283
284 if (!ucode_size)
285 return 0; 293 return 0;
286 294
287 ucode = (void *)(initrd_start + ucode_offset); 295 ucode = (void *)(initrd_start + ucode_offset);