Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8280867

Cpuid1Ecx feature parsing is incorrect for AMD CPUs

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      b08

      Backports

        Description

        Originally found by Ashutosh Mehra of Red Hat.

        If you look at our current CPU feature handling here:
         https://github.com/openjdk/jdk/blob/c2ee1b33c37e6f2848dc8b3e5417b93b1dac1112/src/hotspot/cpu/x86/vm_version_x86.hpp#L145-L158

          union ExtCpuid1Ecx {
            uint32_t value;
            struct {
              uint32_t LahfSahf : 1, // bit 0
                       CmpLegacy : 1, // bit 1
                                    : 3, // bits 2..4
                       lzcnt_intel : 1, // bit 5
                       lzcnt : 1, // bit 6
                       sse4a : 1, // bit 7
                       misalignsse : 1, // bit 8
                       prefetchw : 1, // bit 9
                                    : 22;
            } bits;
          };

        And compare it with Intel SDM and AMD APM, then you'll notice a discrepancy in bit positions.

        AMD APM V3 says (https://www.amd.com/system/files/TechDocs/40332.pdf, "Obtaining Processor Information Via the CPUID Instruction", page 610):

          Bit 0: LahfSahf LAHF and SAHF instruction support in 64-bit mode.
          Bit 1: CmpLegacy Core multi-processing legacy mode.
          Bit 2: SVM Secure virtual machine.
          Bit 3: ExtApicSpace
          Bit 4: AltMovCr8 LOCK MOV CR0 means MOV CR8.
          Bit 5: ABM Advanced bit manipulation. LZCNT instruction support.
          Bit 6: SSE4A
          Bit 7: MisAlignSse
          Bit 8: 3DNowPrefetch
          Bit 9: OSVW OS visible workaround.

        So CPUID returns {LZCNT, SSE4A, MisAlignSse, 3DNowPrefetch} in bits 5..8. Hotspot's code, however, reads {lzcnt, sse4a, misalignsse, prefetchw} from bits 6..9!

        Intel SDM 2A says (https://cdrdv2.intel.com/v1/dl/getContent/671199, "CPUID—CPU Identification", page 3-233):
          Bit 00: LAHF/SAHF available in 64-bit mode
          Bits 04-01 Reserved
          Bit 05: LZCNT
          Bits 07-06 Reserved
          Bit 08: PREFETCHW
          Bits 31-09 Reserved

        It matches the current structure well, except for prefetchw oddity (CPUID sets bit 8, Hotspot reads bit 9 "misalignsse") that is handled separately:

            // Intel features.
            if (is_intel()) {
        ...
              // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw
              if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
                result |= CPU_3DNOW_PREFETCH;
              }
        ...
            }

        I believe this went unnoticed, because all adjacent bits 6..9 are set on modern AMD CPUs.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                shade Aleksey Shipilev
                Reporter:
                shade Aleksey Shipilev
                Votes:
                0 Vote for this issue
                Watchers:
                8 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: