Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: ccp - Initialize PSP when reading psp data file failed

Currently the OS fails the PSP initialization when the file specified at
'init_ex_path' does not exist or has invalid content. However the SEV
spec just requires users to allocate 32KB of 0xFF in the file, which can
be taken care of by the OS easily.

To improve the robustness during the PSP init, leverage the retry
mechanism and continue the init process:

Before the first INIT_EX call, if the content is invalid or missing,
continue the process by feeding those contents into PSP instead of
aborting. PSP will then override it with 32KB 0xFF and return
SEV_RET_SECURE_DATA_INVALID status code. In the second INIT_EX call,
this 32KB 0xFF content will then be fed and PSP will write the valid
data to the file.

In order to do this, sev_read_init_ex_file should only be called once
for the first INIT_EX call. Calling it again for the second INIT_EX call
will cause the invalid file content overwriting the valid 32KB 0xFF data
provided by PSP in the first INIT_EX call.

Co-developed-by: Peter Gonda <pgonda@google.com>
Signed-off-by: Peter Gonda <pgonda@google.com>
Signed-off-by: Jacky Li <jackyli@google.com>
Reported-by: Alper Gun <alpergun@google.com>
Acked-by: David Rientjes <rientjes@google.com>
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Jacky Li and committed by
Herbert Xu
d8da2da2 d5eb916d

+24 -17
+2 -3
Documentation/virt/kvm/x86/amd-memory-encryption.rst
··· 89 89 90 90 The firmware can be initialized either by using its own non-volatile storage or 91 91 the OS can manage the NV storage for the firmware using the module parameter 92 - ``init_ex_path``. The file specified by ``init_ex_path`` must exist. To create 93 - a new NV storage file allocate the file with 32KB bytes of 0xFF as required by 94 - the SEV spec. 92 + ``init_ex_path``. If the file specified by ``init_ex_path`` does not exist or 93 + is invalid, the OS will create or override the file with output from PSP. 95 94 96 95 Returns: 0 on success, -negative on error 97 96
+22 -14
drivers/crypto/ccp/sev-dev.c
··· 211 211 if (IS_ERR(fp)) { 212 212 int ret = PTR_ERR(fp); 213 213 214 - dev_err(sev->dev, 215 - "SEV: could not open %s for read, error %d\n", 216 - init_ex_path, ret); 214 + if (ret == -ENOENT) { 215 + dev_info(sev->dev, 216 + "SEV: %s does not exist and will be created later.\n", 217 + init_ex_path); 218 + ret = 0; 219 + } else { 220 + dev_err(sev->dev, 221 + "SEV: could not open %s for read, error %d\n", 222 + init_ex_path, ret); 223 + } 217 224 return ret; 218 225 } 219 226 220 227 nread = kernel_read(fp, sev_init_ex_buffer, NV_LENGTH, NULL); 221 228 if (nread != NV_LENGTH) { 222 - dev_err(sev->dev, 223 - "SEV: failed to read %u bytes to non volatile memory area, ret %ld\n", 229 + dev_info(sev->dev, 230 + "SEV: could not read %u bytes to non volatile memory area, ret %ld\n", 224 231 NV_LENGTH, nread); 225 - return -EIO; 226 232 } 227 233 228 234 dev_dbg(sev->dev, "SEV: read %ld bytes from NV file\n", nread); ··· 416 410 static int __sev_init_ex_locked(int *error) 417 411 { 418 412 struct sev_data_init_ex data; 419 - int ret; 420 413 421 414 memset(&data, 0, sizeof(data)); 422 415 data.length = sizeof(data); 423 416 data.nv_address = __psp_pa(sev_init_ex_buffer); 424 417 data.nv_len = NV_LENGTH; 425 - 426 - ret = sev_read_init_ex_file(); 427 - if (ret) 428 - return ret; 429 418 430 419 if (sev_es_tmr) { 431 420 /* ··· 440 439 { 441 440 struct psp_device *psp = psp_master; 442 441 struct sev_device *sev; 443 - int rc, psp_ret = -1; 442 + int rc = 0, psp_ret = -1; 444 443 int (*init_function)(int *error); 445 444 446 445 if (!psp || !psp->sev_data) ··· 451 450 if (sev->state == SEV_STATE_INIT) 452 451 return 0; 453 452 454 - init_function = sev_init_ex_buffer ? __sev_init_ex_locked : 455 - __sev_init_locked; 453 + if (sev_init_ex_buffer) { 454 + init_function = __sev_init_ex_locked; 455 + rc = sev_read_init_ex_file(); 456 + if (rc) 457 + return rc; 458 + } else { 459 + init_function = __sev_init_locked; 460 + } 461 + 456 462 rc = init_function(&psp_ret); 457 463 if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { 458 464 /*