target-i386: CPUID: return highest basic leaf if eax > cpuid_xlevel

This fixes a subtle bug. A bug that probably won't cause trouble for any
existing OS, but a bug anyway:

Intel SDM Volume 2, CPUID Instruction states:

> Two types of information are returned: basic and extended function
> information. If a value entered for CPUID.EAX is higher than the maximum
> input value for basic or extended function for that processor then the
> data for the highest basic information leaf is returned. For example,
> using the Intel Core i7 processor, the following is true:
>
>   CPUID.EAX = 05H (* Returns MONITOR/MWAIT leaf. *)
>   CPUID.EAX = 0AH (* Returns Architectural Performance Monitoring leaf. *)
>   CPUID.EAX = 0BH (* Returns Extended Topology Enumeration leaf. *)
>   CPUID.EAX = 0CH (* INVALID: Returns the same information as CPUID.EAX = 0BH. *)
>   CPUID.EAX = 80000008H (* Returns linear/physical address size data. *)
>   CPUID.EAX = 8000000AH (* INVALID: Returns same information as CPUID.EAX = 0BH. *)

AMD's CPUID Specification, on the other hand, is less specific:

> The CPUID instruction supports two sets or ranges of functions,
> standard and extended.
>
> • The smallest function number of the standard function range is
>   Fn0000_0000. The largest function num- ber of the standard function
>   range, for a particular implementation, is returned in CPUID
>   Fn0000_0000_EAX.
>
> • The smallest function number of the extended function range is
>   Fn8000_0000. The largest function num- ber of the extended function
>   range, for a particular implementation, is returned in CPUID
>   Fn8000_0000_EAX.
>
> Functions that are neither standard nor extended are undefined and
> should not be relied upon.

QEMU's behavior matched Intel's specification before, but this was
changed by commit b3baa152aaef1905876670590275c2dd0bbb088c. This patch
restores the behavior documented by Intel when cpuid_xlevel2 is 0.

The existing behavior when cpuid_xlevel2 is set (falling back to
level=cpuid_xlevel) is being kept, as I couldn't find any public
documentation on the CPUID 0xC0000000 function range on Centaur CPUs.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
1 file changed
tree: c3e3d31d23769925ec536eaf5b5bc708dc17d2da
  1. audio/
  2. backends/
  3. block/
  4. bsd-user/
  5. default-configs/
  6. disas/
  7. docs/
  8. fpu/
  9. fsdev/
  10. gdb-xml/
  11. hw/
  12. include/
  13. ldscripts/
  14. libcacard/
  15. linux-headers/
  16. linux-user/
  17. net/
  18. pc-bios/
  19. qapi/
  20. qga/
  21. QMP/
  22. qom/
  23. roms/
  24. scripts/
  25. slirp/
  26. stubs/
  27. sysconfigs/
  28. target-alpha/
  29. target-arm/
  30. target-cris/
  31. target-i386/
  32. target-lm32/
  33. target-m68k/
  34. target-microblaze/
  35. target-mips/
  36. target-openrisc/
  37. target-ppc/
  38. target-s390x/
  39. target-sh4/
  40. target-sparc/
  41. target-unicore32/
  42. target-xtensa/
  43. tcg/
  44. tests/
  45. trace/
  46. ui/
  47. .exrc
  48. .gitignore
  49. .gitmodules
  50. .mailmap
  51. acl.c
  52. aes.c
  53. aio-posix.c
  54. aio-win32.c
  55. arch_init.c
  56. async.c
  57. balloon.c
  58. bitmap.c
  59. bitops.c
  60. block-migration.c
  61. block.c
  62. blockdev-nbd.c
  63. blockdev.c
  64. blockjob.c
  65. bt-host.c
  66. bt-vhci.c
  67. cache-utils.c
  68. Changelog
  69. cmd.c
  70. cmd.h
  71. CODING_STYLE
  72. compatfd.c
  73. configure
  74. COPYING
  75. COPYING.LIB
  76. coroutine-gthread.c
  77. coroutine-sigaltstack.c
  78. coroutine-ucontext.c
  79. coroutine-win32.c
  80. cpu-exec.c
  81. cpus.c
  82. cputlb.c
  83. cutils.c
  84. device_tree.c
  85. disas.c
  86. dma-helpers.c
  87. dump-stub.c
  88. dump.c
  89. envlist.c
  90. error.c
  91. event_notifier-posix.c
  92. event_notifier-win32.c
  93. exec.c
  94. gdbstub.c
  95. HACKING
  96. hmp-commands.hx
  97. hmp.c
  98. hmp.h
  99. host-utils.c
  100. iohandler.c
  101. ioport.c
  102. iov.c
  103. json-lexer.c
  104. json-parser.c
  105. json-streamer.c
  106. kvm-all.c
  107. kvm-stub.c
  108. LICENSE
  109. main-loop.c
  110. MAINTAINERS
  111. Makefile
  112. Makefile.objs
  113. Makefile.target
  114. memory.c
  115. memory_mapping-stub.c
  116. memory_mapping.c
  117. migration-exec.c
  118. migration-fd.c
  119. migration-tcp.c
  120. migration-unix.c
  121. migration.c
  122. module.c
  123. monitor.c
  124. nbd.c
  125. notify.c
  126. os-posix.c
  127. os-win32.c
  128. osdep.c
  129. oslib-posix.c
  130. oslib-win32.c
  131. page_cache.c
  132. path.c
  133. pci-ids.txt
  134. qapi-schema-test.json
  135. qapi-schema.json
  136. qbool.c
  137. qdict-test-data.txt
  138. qdict.c
  139. qemu-bridge-helper.c
  140. qemu-char.c
  141. qemu-config.c
  142. qemu-coroutine-io.c
  143. qemu-coroutine-lock.c
  144. qemu-coroutine-sleep.c
  145. qemu-coroutine.c
  146. qemu-doc.texi
  147. qemu-error.c
  148. qemu-img-cmds.hx
  149. qemu-img.c
  150. qemu-img.texi
  151. qemu-io.c
  152. qemu-log.c
  153. qemu-nbd.c
  154. qemu-nbd.texi
  155. qemu-option.c
  156. qemu-options-wrapper.h
  157. qemu-options.h
  158. qemu-options.hx
  159. qemu-progress.c
  160. qemu-seccomp.c
  161. qemu-sockets.c
  162. qemu-tech.texi
  163. qemu-thread-posix.c
  164. qemu-thread-win32.c
  165. qemu-timer-common.c
  166. qemu-timer.c
  167. qemu-tool.c
  168. qemu-user.c
  169. qemu.sasl
  170. qerror.c
  171. qfloat.c
  172. qint.c
  173. qjson.c
  174. qlist.c
  175. qmp-commands.hx
  176. qmp.c
  177. qstring.c
  178. qtest.c
  179. readline.c
  180. README
  181. rules.mak
  182. savevm.c
  183. spice-qemu-char.c
  184. tcg-runtime.c
  185. tci.c
  186. thread-pool.c
  187. thunk.c
  188. TODO
  189. trace-events
  190. translate-all.c
  191. translate-all.h
  192. uri.c
  193. user-exec.c
  194. VERSION
  195. version.rc
  196. vl.c
  197. xen-all.c
  198. xen-mapcache.c
  199. xen-stub.c