Message ID | 20220221160850.1484364-1-dovmurik@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | qapi, target/i386/sev: Add cpu0-id to query-sev-capabilities | expand |
On Mon, Feb 21, 2022 at 04:08:50PM +0000, Dov Murik wrote: > Add a new field 'cpu0-id' to the response of query-sev-capabilities > QMP command. The value of the field is the hex-encoded 64-byte unique > ID of the CPU0 (socket 0), which can be used to retrieve the signed CEK > of the CPU from AMD's Key Distribution Service (KDS). > > Signed-off-by: Dov Murik <dovmurik@linux.ibm.com> > --- > qapi/misc-target.json | 4 ++++ > target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+) > > diff --git a/qapi/misc-target.json b/qapi/misc-target.json > index 4bc45d2474..d9b4991c86 100644 > --- a/qapi/misc-target.json > +++ b/qapi/misc-target.json > @@ -177,6 +177,8 @@ > # > # @cert-chain: PDH certificate chain (base64 encoded) > # > +# @cpu0-id: 64-byte unique ID of CPU0 (hex encoded) (since 7.0) For binary data in QAPI we've pretty much standardized on using base64 encoding. I think we should stick with that encoding. > +# > # @cbitpos: C-bit location in page table entry > # > # @reduced-phys-bits: Number of physical Address bit reduction when SEV is > @@ -187,6 +189,7 @@ > { 'struct': 'SevCapability', > 'data': { 'pdh': 'str', > 'cert-chain': 'str', > + 'cpu0-id': 'str', > 'cbitpos': 'int', > 'reduced-phys-bits': 'int'}, > 'if': 'TARGET_I386' } > @@ -205,6 +208,7 @@ > # > # -> { "execute": "query-sev-capabilities" } > # <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE", > +# "cpu0-id": "5ea2e1...90ea39", > # "cbitpos": 47, "reduced-phys-bits": 5}} > # > ## Regards, Daniel
Thanks Daniel for reviewing. On 21/02/2022 18:24, Daniel P. Berrangé wrote: > On Mon, Feb 21, 2022 at 04:08:50PM +0000, Dov Murik wrote: >> Add a new field 'cpu0-id' to the response of query-sev-capabilities >> QMP command. The value of the field is the hex-encoded 64-byte unique >> ID of the CPU0 (socket 0), which can be used to retrieve the signed CEK >> of the CPU from AMD's Key Distribution Service (KDS). >> >> Signed-off-by: Dov Murik <dovmurik@linux.ibm.com> >> --- >> qapi/misc-target.json | 4 ++++ >> target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 47 insertions(+) >> >> diff --git a/qapi/misc-target.json b/qapi/misc-target.json >> index 4bc45d2474..d9b4991c86 100644 >> --- a/qapi/misc-target.json >> +++ b/qapi/misc-target.json >> @@ -177,6 +177,8 @@ >> # >> # @cert-chain: PDH certificate chain (base64 encoded) >> # >> +# @cpu0-id: 64-byte unique ID of CPU0 (hex encoded) (since 7.0) > > For binary data in QAPI we've pretty much standardized on using > base64 encoding. I think we should stick with that encoding. > OK, I'll change that to base64. I thought about the cpu0-id as some kind of "address string", like mac addresses or IPv6 addresses which are usually represented as hex strings and not as base64-encoded. But I guess that the AMD CPU unique ID doesn't have the same legacy (and accepted notation) as mac addresses or IPv6 addresses, so we might as well treat it as "regular" binary data. Going with base64 also saves some code because QEMU doesn't have a ready-made hex_encode() function (I copied mine from a static function in crypto/hash.c). -Dov >> +# >> # @cbitpos: C-bit location in page table entry >> # >> # @reduced-phys-bits: Number of physical Address bit reduction when SEV is >> @@ -187,6 +189,7 @@ >> { 'struct': 'SevCapability', >> 'data': { 'pdh': 'str', >> 'cert-chain': 'str', >> + 'cpu0-id': 'str', >> 'cbitpos': 'int', >> 'reduced-phys-bits': 'int'}, >> 'if': 'TARGET_I386' } >> @@ -205,6 +208,7 @@ >> # >> # -> { "execute": "query-sev-capabilities" } >> # <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE", >> +# "cpu0-id": "5ea2e1...90ea39", >> # "cbitpos": 47, "reduced-phys-bits": 5}} >> # >> ## > > Regards, > Daniel
diff --git a/qapi/misc-target.json b/qapi/misc-target.json index 4bc45d2474..d9b4991c86 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -177,6 +177,8 @@ # # @cert-chain: PDH certificate chain (base64 encoded) # +# @cpu0-id: 64-byte unique ID of CPU0 (hex encoded) (since 7.0) +# # @cbitpos: C-bit location in page table entry # # @reduced-phys-bits: Number of physical Address bit reduction when SEV is @@ -187,6 +189,7 @@ { 'struct': 'SevCapability', 'data': { 'pdh': 'str', 'cert-chain': 'str', + 'cpu0-id': 'str', 'cbitpos': 'int', 'reduced-phys-bits': 'int'}, 'if': 'TARGET_I386' } @@ -205,6 +208,7 @@ # # -> { "execute": "query-sev-capabilities" } # <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE", +# "cpu0-id": "5ea2e1...90ea39", # "cbitpos": 47, "reduced-phys-bits": 5}} # ## diff --git a/target/i386/sev.c b/target/i386/sev.c index 025ff7a6f8..c87c69b2f3 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -82,6 +82,8 @@ struct SevGuestState { #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ #define DEFAULT_SEV_DEVICE "/dev/sev" +#define SEV_UNIQUE_ID_LEN 64 + #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e" typedef struct __attribute__((__packed__)) SevInfoBlock { /* SEV-ES Reset Vector Address */ @@ -531,11 +533,47 @@ e_free: return 1; } +static int +sev_get_id(int fd, guchar *id_buf, size_t id_buf_len, Error **errp) +{ + struct sev_user_data_get_id2 id = { + .address = (unsigned long)id_buf, + .length = id_buf_len + }; + int err, r; + + r = sev_platform_ioctl(fd, SEV_GET_ID2, &id, &err); + if (r < 0) { + error_setg(errp, "SEV: Failed to get ID ret=%d fw_err=%d (%s)", + r, err, fw_error_to_str(err)); + return 1; + } + + return 0; +} + +static const char hex[] = "0123456789abcdef"; + +static gchar *hex_encode(guchar *buf, size_t len) +{ + gchar *str = g_new0(gchar, (len * 2) + 1); + size_t i; + + for (i = 0; i < len; i++) { + str[(i * 2)] = hex[(buf[i] >> 4) & 0xf]; + str[(i * 2) + 1] = hex[buf[i] & 0xf]; + } + str[len * 2] = '\0'; + + return str; +} + static SevCapability *sev_get_capabilities(Error **errp) { SevCapability *cap = NULL; guchar *pdh_data = NULL; guchar *cert_chain_data = NULL; + guchar cpu0_id[SEV_UNIQUE_ID_LEN]; size_t pdh_len = 0, cert_chain_len = 0; uint32_t ebx; int fd; @@ -561,9 +599,14 @@ static SevCapability *sev_get_capabilities(Error **errp) goto out; } + if (sev_get_id(fd, cpu0_id, sizeof(cpu0_id), errp)) { + goto out; + } + cap = g_new0(SevCapability, 1); cap->pdh = g_base64_encode(pdh_data, pdh_len); cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len); + cap->cpu0_id = hex_encode(cpu0_id, sizeof(cpu0_id)); host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); cap->cbitpos = ebx & 0x3f;
Add a new field 'cpu0-id' to the response of query-sev-capabilities QMP command. The value of the field is the hex-encoded 64-byte unique ID of the CPU0 (socket 0), which can be used to retrieve the signed CEK of the CPU from AMD's Key Distribution Service (KDS). Signed-off-by: Dov Murik <dovmurik@linux.ibm.com> --- qapi/misc-target.json | 4 ++++ target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+)