Print this page
9578 HVM fails assertion in opteron_get_nnodes() with a Opteron 6262 HE CPU on the host system


  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright (c) 2010, Intel Corporation.
  27  * All rights reserved.
  28  */
  29 /*
  30  * Copyright 2018 Joyent, Inc.
  31  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  32  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/thread.h>
  37 #include <sys/cpuvar.h>
  38 #include <sys/cpu.h>
  39 #include <sys/t_lock.h>
  40 #include <sys/param.h>
  41 #include <sys/proc.h>
  42 #include <sys/disp.h>
  43 #include <sys/class.h>
  44 #include <sys/cmn_err.h>
  45 #include <sys/debug.h>
  46 #include <sys/note.h>
  47 #include <sys/asm_linkage.h>
  48 #include <sys/x_call.h>
  49 #include <sys/systm.h>
  50 #include <sys/var.h>
  51 #include <sys/vtrace.h>


 702 
 703 static void
 704 workaround_applied(uint_t erratum)
 705 {
 706         if (erratum > 1000000)
 707                 cmn_err(CE_CONT, "?workaround applied for cpu issue #%d\n",
 708                     erratum);
 709         else
 710                 cmn_err(CE_CONT, "?workaround applied for cpu erratum #%d\n",
 711                     erratum);
 712 }
 713 
 714 static void
 715 msr_warning(cpu_t *cp, const char *rw, uint_t msr, int error)
 716 {
 717         cmn_err(CE_WARN, "cpu%d: couldn't %smsr 0x%x, error %d",
 718             cp->cpu_id, rw, msr, error);
 719 }
 720 
 721 /*
 722  * Determine the number of nodes in a Hammer / Greyhound / Griffin family
 723  * system.





 724  */
 725 static uint_t
 726 opteron_get_nnodes(void)
 727 {
 728         static uint_t nnodes = 0;
 729 
 730         if (nnodes == 0) {
 731 #ifdef  DEBUG
 732                 uint_t family;
 733 
 734                 /*
 735                  * This routine uses a PCI config space based mechanism
 736                  * for retrieving the number of nodes in the system.
 737                  * Device 24, function 0, offset 0x60 as used here is not
 738                  * AMD processor architectural, and may not work on processor
 739                  * families other than those listed below.
 740                  *
 741                  * Callers of this routine must ensure that we're running on
 742                  * a processor which supports this mechanism.
 743                  * The assertion below is meant to catch calls on unsupported
 744                  * processors.
 745                  */
 746                 family = cpuid_getfamily(CPU);
 747                 ASSERT(family == 0xf || family == 0x10 || family == 0x11);
 748 #endif  /* DEBUG */
 749 
 750                 /*
 751                  * Obtain the number of nodes in the system from
 752                  * bits [6:4] of the Node ID register on node 0.
 753                  *
 754                  * The actual node count is NodeID[6:4] + 1
 755                  *
 756                  * The Node ID register is accessed via function 0,
 757                  * offset 0x60. Node 0 is device 24.
 758                  */

 759                 nnodes = ((pci_getl_func(0, 24, 0, 0x60) & 0x70) >> 4) + 1;
 760         }
 761         return (nnodes);
 762 }
 763 
 764 uint_t
 765 do_erratum_298(struct cpu *cpu)
 766 {
 767         static int      osvwrc = -3;
 768         extern int      osvw_opteron_erratum(cpu_t *, uint_t);
 769 
 770         /*
 771          * L2 Eviction May Occur During Processor Operation To Set
 772          * Accessed or Dirty Bit.
 773          */
 774         if (osvwrc == -3) {
 775                 osvwrc = osvw_opteron_erratum(cpu, 298);
 776         } else {
 777                 /* osvw return codes should be consistent for all cpus */
 778                 ASSERT(osvwrc == osvw_opteron_erratum(cpu, 298));
 779         }
 780 




  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright (c) 2010, Intel Corporation.
  27  * All rights reserved.
  28  */
  29 /*
  30  * Copyright 2018 Joyent, Inc.
  31  * Copyright 2018 Nexenta Systems, Inc.
  32  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/thread.h>
  37 #include <sys/cpuvar.h>
  38 #include <sys/cpu.h>
  39 #include <sys/t_lock.h>
  40 #include <sys/param.h>
  41 #include <sys/proc.h>
  42 #include <sys/disp.h>
  43 #include <sys/class.h>
  44 #include <sys/cmn_err.h>
  45 #include <sys/debug.h>
  46 #include <sys/note.h>
  47 #include <sys/asm_linkage.h>
  48 #include <sys/x_call.h>
  49 #include <sys/systm.h>
  50 #include <sys/var.h>
  51 #include <sys/vtrace.h>


 702 
 703 static void
 704 workaround_applied(uint_t erratum)
 705 {
 706         if (erratum > 1000000)
 707                 cmn_err(CE_CONT, "?workaround applied for cpu issue #%d\n",
 708                     erratum);
 709         else
 710                 cmn_err(CE_CONT, "?workaround applied for cpu erratum #%d\n",
 711                     erratum);
 712 }
 713 
 714 static void
 715 msr_warning(cpu_t *cp, const char *rw, uint_t msr, int error)
 716 {
 717         cmn_err(CE_WARN, "cpu%d: couldn't %smsr 0x%x, error %d",
 718             cp->cpu_id, rw, msr, error);
 719 }
 720 
 721 /*
 722  * Determine the number of nodes in a system.
 723  *
 724  * This routine uses a PCI config space based mechanism
 725  * for retrieving the number of nodes in the system.
 726  *
 727  * Current processor families that support this mechanism are
 728  * 0xf, 0x10, 0x11, and 0x15.
 729  */
 730 static uint_t
 731 opteron_get_nnodes(void)
 732 {
 733         static uint_t nnodes = 0;
 734 




 735         /*
















 736          * Obtain the number of nodes in the system from
 737          * bits [6:4] of the Node ID register on node 0.
 738          *
 739          * The actual node count is NodeID[6:4] + 1
 740          *
 741          * The Node ID register is accessed via function 0,
 742          * offset 0x60. Node 0 is device 24.
 743          */
 744         if (nnodes == 0)
 745                 nnodes = ((pci_getl_func(0, 24, 0, 0x60) & 0x70) >> 4) + 1;
 746 
 747         return (nnodes);
 748 }
 749 
 750 uint_t
 751 do_erratum_298(struct cpu *cpu)
 752 {
 753         static int      osvwrc = -3;
 754         extern int      osvw_opteron_erratum(cpu_t *, uint_t);
 755 
 756         /*
 757          * L2 Eviction May Occur During Processor Operation To Set
 758          * Accessed or Dirty Bit.
 759          */
 760         if (osvwrc == -3) {
 761                 osvwrc = osvw_opteron_erratum(cpu, 298);
 762         } else {
 763                 /* osvw return codes should be consistent for all cpus */
 764                 ASSERT(osvwrc == osvw_opteron_erratum(cpu, 298));
 765         }
 766