@@ -117,14 +117,17 @@ const (
117117 ExtraPlatformInfoV0Size = 8
118118
119119 // CpuidProductMask keeps only the SevProduct-relevant bits from the CPUID(1).EAX result.
120- CpuidProductMask = 0x0fff0f0f
120+ CpuidProductMask = 0x0fff0fff
121121 extendedFamilyShift = 20
122122 extendedModelShift = 16
123123 familyShift = 8
124- sevExtendedFamily = 0xA
125- sevFamily = 0xF
126- milanExtendedModel = 0
127- genoaExtendedModel = 1
124+ modelShift = 4
125+ // Combined extended values
126+ zen3zen4Family = 0x19
127+ zen5Family = 0x1A
128+ milanModel = 0 | 1
129+ genoaModel = (1 << 4 ) | 1
130+ turinModel = 2
128131
129132 // ReportVersion2 is set by the SNP API specification
130133 // https://web.archive.org/web/20231222054111if_/http://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56860.pdf
@@ -487,9 +490,7 @@ func ReportToProto(data []uint8) (*pb.Report, error) {
487490 mbzLo := 0x188
488491 if r .Version == ReportVersion3 {
489492 mbzLo = 0x18B
490- r .CpuidFamId = []byte {data [0x188 ]}
491- r .CpuidModId = []byte {data [0x189 ]}
492- r .CpuidStep = []byte {data [0x18A ]}
493+ r .Cpuid1EaxFms = FmsToCpuid1Eax (data [0x188 ], data [0x189 ], data [0x18A ])
493494 }
494495
495496 if err := mbz (data , mbzLo , 0x1A0 ); err != nil {
@@ -635,9 +636,10 @@ func ReportToAbiBytes(r *pb.Report) ([]byte, error) {
635636
636637 // Add CPUID information if this is a version 3 report.
637638 if r .Version == ReportVersion3 {
638- data [0x188 ] = r .CpuidFamId [0 ]
639- data [0x189 ] = r .CpuidModId [0 ]
640- data [0x18A ] = r .CpuidStep [0 ]
639+ family , model , stepping := FmsFromCpuid1Eax (r .Cpuid1EaxFms )
640+ data [0x188 ] = family
641+ data [0x189 ] = model
642+ data [0x18A ] = stepping
641643 }
642644
643645 copy (data [0x1A0 :0x1E0 ], r .ChipId [:])
@@ -903,59 +905,106 @@ func (c *CertTable) Proto() *pb.CertificateChain {
903905// See assembly implementations in cpuid_*.s
904906var cpuid func (op uint32 ) (eax , ebx , ecx , edx uint32 )
905907
906- // SevProductFromCpuid1Eax returns the SevProduct that is represented by cpuid(1).eax.
907- func SevProductFromCpuid1Eax (eax uint32 ) * pb.SevProduct {
908+ // FmsToCpuid1Eax returns the masked CPUID_1_EAX value that represents the given
909+ // family, model, stepping (FMS) values.
910+ func FmsToCpuid1Eax (family , model , stepping byte ) uint32 {
911+ var extendedFamily byte
912+
913+ familyID := family
914+ if family >= 0xf {
915+ extendedFamily = family - 0xf
916+ familyID = 0xf
917+ }
918+ extendedModel := model >> 4
919+ modelID := model & 0xf
920+ return (uint32 (extendedFamily ) << extendedFamilyShift ) |
921+ (uint32 (extendedModel ) << extendedModelShift ) |
922+ (uint32 (familyID ) << familyShift ) |
923+ (uint32 (modelID ) << modelShift ) |
924+ (uint32 (stepping & 0xf ))
925+ }
926+
927+ // FmsFromCpuid1Eax returns the family, model, stepping (FMS) values extracted from a
928+ // CPUID_1_EAX value.
929+ func FmsFromCpuid1Eax (eax uint32 ) (byte , byte , byte ) {
908930 // 31:28 reserved
909931 // 27:20 Extended Family ID
910- extendedFamily := ( eax >> extendedFamilyShift ) & 0xff
932+ extendedFamily := byte (( eax >> extendedFamilyShift ) & 0xff )
911933 // 19:16 Extended Model ID
912- extendedModel := ( eax >> extendedModelShift ) & 0xf
934+ extendedModel := byte (( eax >> extendedModelShift ) & 0xf )
913935 // 15:14 reserved
914936 // 11:8 Family ID
915- family := (eax >> familyShift ) & 0xf
937+ familyID := byte ((eax >> familyShift ) & 0xf )
938+ // 7:4 Model
939+ modelID := byte ((eax >> modelShift ) & 0xf )
916940 // 3:0 Stepping
917- stepping := eax & 0xf
941+ family := extendedFamily + familyID
942+ model := (extendedModel << 4 ) | modelID
943+ stepping := byte (eax & 0xf )
944+ return family , model , stepping
945+ }
946+
947+ // SevProductFromCpuid1Eax returns the SevProduct that is represented by cpuid(1).eax.
948+ func SevProductFromCpuid1Eax (eax uint32 ) * pb.SevProduct {
949+ family , model , stepping := FmsFromCpuid1Eax (eax )
918950 // Ah, Fh, {0h,1h} values from the KDS specification,
919951 // section "Determining the Product Name".
920952 var productName pb.SevProduct_SevProductName
953+ unknown := func () {
954+ productName = pb .SevProduct_SEV_PRODUCT_UNKNOWN
955+ stepping = 0 // Reveal nothing.
956+ }
921957 // Product information specified by processor programming reference publications.
922- if extendedFamily == sevExtendedFamily && family == sevFamily {
923- switch extendedModel {
924- case milanExtendedModel :
958+ switch family {
959+ case zen3zen4Family :
960+ switch model {
961+ case milanModel :
925962 productName = pb .SevProduct_SEV_PRODUCT_MILAN
926- case genoaExtendedModel :
963+ case genoaModel :
927964 productName = pb .SevProduct_SEV_PRODUCT_GENOA
928965 default :
929- productName = pb .SevProduct_SEV_PRODUCT_UNKNOWN
930- stepping = 0 // Reveal nothing.
966+ unknown ()
967+ }
968+ case zen5Family :
969+ switch model {
970+ case turinModel :
971+ productName = pb .SevProduct_SEV_PRODUCT_TURIN
972+ default :
973+ unknown ()
931974 }
975+ default :
976+ unknown ()
932977 }
933978 return & pb.SevProduct {
934979 Name : productName ,
935- MachineStepping : & wrapperspb.UInt32Value {Value : stepping },
980+ MachineStepping : & wrapperspb.UInt32Value {Value : uint32 ( stepping ) },
936981 }
937982}
938983
939984// MaskedCpuid1EaxFromSevProduct returns the Cpuid1Eax value expected from the given product
940985// when masked with CpuidProductMask.
941986func MaskedCpuid1EaxFromSevProduct (product * pb.SevProduct ) uint32 {
942- var stepping uint32
987+ if product == nil {
988+ return 0
989+ }
990+ var family , model , stepping byte
943991 if product .MachineStepping != nil {
944- stepping = product .MachineStepping .Value & 0xf
992+ stepping = byte ( product .MachineStepping .Value & 0xf )
945993 }
946- extendedFamily := uint32 (sevExtendedFamily ) << extendedFamilyShift
947- family := uint32 (sevFamily ) << familyShift
948-
949- var extendedModel uint32
950994 switch product .Name {
951995 case pb .SevProduct_SEV_PRODUCT_MILAN :
952- extendedModel = milanExtendedModel
996+ family = zen3zen4Family
997+ model = milanModel
953998 case pb .SevProduct_SEV_PRODUCT_GENOA :
954- extendedModel = genoaExtendedModel
999+ family = zen3zen4Family
1000+ model = genoaModel
1001+ case pb .SevProduct_SEV_PRODUCT_TURIN :
1002+ family = zen5Family
1003+ model = turinModel
9551004 default :
9561005 return 0
9571006 }
958- return extendedFamily | family | stepping | ( extendedModel << extendedModelShift )
1007+ return FmsToCpuid1Eax ( family , model , stepping )
9591008}
9601009
9611010// SevProduct returns the SEV product enum for the CPU that runs this
0 commit comments