microcode_amd_early.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Copyright (C) 2013 Advanced Micro Devices, Inc.
  3. *
  4. * Author: Jacob Shin <jacob.shin@amd.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/earlycpio.h>
  11. #include <linux/initrd.h>
  12. #include <asm/cpu.h>
  13. #include <asm/setup.h>
  14. #include <asm/microcode_amd.h>
  15. static bool ucode_loaded;
  16. static u32 ucode_new_rev;
  17. static unsigned long ucode_offset;
  18. static size_t ucode_size;
  19. /*
  20. * Microcode patch container file is prepended to the initrd in cpio format.
  21. * See Documentation/x86/early-microcode.txt
  22. */
  23. static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
  24. static struct cpio_data __init find_ucode_in_initrd(void)
  25. {
  26. long offset = 0;
  27. char *path;
  28. void *start;
  29. size_t size;
  30. unsigned long *uoffset;
  31. size_t *usize;
  32. struct cpio_data cd;
  33. #ifdef CONFIG_X86_32
  34. struct boot_params *p;
  35. /*
  36. * On 32-bit, early load occurs before paging is turned on so we need
  37. * to use physical addresses.
  38. */
  39. p = (struct boot_params *)__pa_nodebug(&boot_params);
  40. path = (char *)__pa_nodebug(ucode_path);
  41. start = (void *)p->hdr.ramdisk_image;
  42. size = p->hdr.ramdisk_size;
  43. uoffset = (unsigned long *)__pa_nodebug(&ucode_offset);
  44. usize = (size_t *)__pa_nodebug(&ucode_size);
  45. #else
  46. path = ucode_path;
  47. start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
  48. size = boot_params.hdr.ramdisk_size;
  49. uoffset = &ucode_offset;
  50. usize = &ucode_size;
  51. #endif
  52. cd = find_cpio_data(path, start, size, &offset);
  53. if (!cd.data)
  54. return cd;
  55. if (*(u32 *)cd.data != UCODE_MAGIC) {
  56. cd.data = NULL;
  57. cd.size = 0;
  58. return cd;
  59. }
  60. *uoffset = (u8 *)cd.data - (u8 *)start;
  61. *usize = cd.size;
  62. return cd;
  63. }
  64. /*
  65. * Early load occurs before we can vmalloc(). So we look for the microcode
  66. * patch container file in initrd, traverse equivalent cpu table, look for a
  67. * matching microcode patch, and update, all in initrd memory in place.
  68. * When vmalloc() is available for use later -- on 64-bit during first AP load,
  69. * and on 32-bit during save_microcode_in_initrd_amd() -- we can call
  70. * load_microcode_amd() to save equivalent cpu table and microcode patches in
  71. * kernel heap memory.
  72. */
  73. static void apply_ucode_in_initrd(void *ucode, size_t size)
  74. {
  75. struct equiv_cpu_entry *eq;
  76. u32 *header;
  77. u8 *data;
  78. u16 eq_id = 0;
  79. int offset, left;
  80. u32 rev, eax;
  81. u32 *new_rev;
  82. unsigned long *uoffset;
  83. size_t *usize;
  84. #ifdef CONFIG_X86_32
  85. new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
  86. uoffset = (unsigned long *)__pa_nodebug(&ucode_offset);
  87. usize = (size_t *)__pa_nodebug(&ucode_size);
  88. #else
  89. new_rev = &ucode_new_rev;
  90. uoffset = &ucode_offset;
  91. usize = &ucode_size;
  92. #endif
  93. data = ucode;
  94. left = size;
  95. header = (u32 *)data;
  96. /* find equiv cpu table */
  97. if (header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
  98. header[2] == 0) /* size */
  99. return;
  100. eax = cpuid_eax(0x00000001);
  101. while (left > 0) {
  102. eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
  103. offset = header[2] + CONTAINER_HDR_SZ;
  104. data += offset;
  105. left -= offset;
  106. eq_id = find_equiv_id(eq, eax);
  107. if (eq_id)
  108. break;
  109. /*
  110. * support multiple container files appended together. if this
  111. * one does not have a matching equivalent cpu entry, we fast
  112. * forward to the next container file.
  113. */
  114. while (left > 0) {
  115. header = (u32 *)data;
  116. if (header[0] == UCODE_MAGIC &&
  117. header[1] == UCODE_EQUIV_CPU_TABLE_TYPE)
  118. break;
  119. offset = header[1] + SECTION_HDR_SIZE;
  120. data += offset;
  121. left -= offset;
  122. }
  123. /* mark where the next microcode container file starts */
  124. offset = data - (u8 *)ucode;
  125. *uoffset += offset;
  126. *usize -= offset;
  127. ucode = data;
  128. }
  129. if (!eq_id) {
  130. *usize = 0;
  131. return;
  132. }
  133. /* find ucode and update if needed */
  134. rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
  135. while (left > 0) {
  136. struct microcode_amd *mc;
  137. header = (u32 *)data;
  138. if (header[0] != UCODE_UCODE_TYPE || /* type */
  139. header[1] == 0) /* size */
  140. break;
  141. mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
  142. if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id)
  143. if (__apply_microcode_amd(mc) == 0) {
  144. rev = mc->hdr.patch_id;
  145. *new_rev = rev;
  146. }
  147. offset = header[1] + SECTION_HDR_SIZE;
  148. data += offset;
  149. left -= offset;
  150. }
  151. /* mark where this microcode container file ends */
  152. offset = *usize - (data - (u8 *)ucode);
  153. *usize -= offset;
  154. if (!(*new_rev))
  155. *usize = 0;
  156. }
  157. void __init load_ucode_amd_bsp(void)
  158. {
  159. struct cpio_data cd = find_ucode_in_initrd();
  160. if (!cd.data)
  161. return;
  162. apply_ucode_in_initrd(cd.data, cd.size);
  163. }
  164. #ifdef CONFIG_X86_32
  165. u8 amd_bsp_mpb[MPB_MAX_SIZE];
  166. /*
  167. * On 32-bit, since AP's early load occurs before paging is turned on, we
  168. * cannot traverse cpu_equiv_table and pcache in kernel heap memory. So during
  169. * cold boot, AP will apply_ucode_in_initrd() just like the BSP. During
  170. * save_microcode_in_initrd_amd() BSP's patch is copied to amd_bsp_mpb, which
  171. * is used upon resume from suspend.
  172. */
  173. void load_ucode_amd_ap(void)
  174. {
  175. struct microcode_amd *mc;
  176. unsigned long *initrd;
  177. unsigned long *uoffset;
  178. size_t *usize;
  179. void *ucode;
  180. mc = (struct microcode_amd *)__pa(amd_bsp_mpb);
  181. if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
  182. __apply_microcode_amd(mc);
  183. return;
  184. }
  185. initrd = (unsigned long *)__pa(&initrd_start);
  186. uoffset = (unsigned long *)__pa(&ucode_offset);
  187. usize = (size_t *)__pa(&ucode_size);
  188. if (!*usize || !*initrd)
  189. return;
  190. ucode = (void *)((unsigned long)__pa(*initrd) + *uoffset);
  191. apply_ucode_in_initrd(ucode, *usize);
  192. }
  193. static void __init collect_cpu_sig_on_bsp(void *arg)
  194. {
  195. unsigned int cpu = smp_processor_id();
  196. struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
  197. uci->cpu_sig.sig = cpuid_eax(0x00000001);
  198. }
  199. #else
  200. static void collect_cpu_info_amd_early(struct cpuinfo_x86 *c,
  201. struct ucode_cpu_info *uci)
  202. {
  203. u32 rev, eax;
  204. rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
  205. eax = cpuid_eax(0x00000001);
  206. uci->cpu_sig.sig = eax;
  207. uci->cpu_sig.rev = rev;
  208. c->microcode = rev;
  209. c->x86 = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
  210. }
  211. void load_ucode_amd_ap(void)
  212. {
  213. unsigned int cpu = smp_processor_id();
  214. collect_cpu_info_amd_early(&cpu_data(cpu), ucode_cpu_info + cpu);
  215. if (cpu && !ucode_loaded) {
  216. void *ucode;
  217. if (!ucode_size || !initrd_start)
  218. return;
  219. ucode = (void *)(initrd_start + ucode_offset);
  220. if (load_microcode_amd(0, ucode, ucode_size) != UCODE_OK)
  221. return;
  222. ucode_loaded = true;
  223. }
  224. apply_microcode_amd(cpu);
  225. }
  226. #endif
  227. int __init save_microcode_in_initrd_amd(void)
  228. {
  229. enum ucode_state ret;
  230. void *ucode;
  231. #ifdef CONFIG_X86_32
  232. unsigned int bsp = boot_cpu_data.cpu_index;
  233. struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
  234. if (!uci->cpu_sig.sig)
  235. smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
  236. #endif
  237. if (ucode_new_rev)
  238. pr_info("microcode: updated early to new patch_level=0x%08x\n",
  239. ucode_new_rev);
  240. if (ucode_loaded || !ucode_size || !initrd_start)
  241. return 0;
  242. ucode = (void *)(initrd_start + ucode_offset);
  243. ret = load_microcode_amd(0, ucode, ucode_size);
  244. if (ret != UCODE_OK)
  245. return -EINVAL;
  246. ucode_loaded = true;
  247. return 0;
  248. }