@@ -322,7 +322,8 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
322322 u8 type , void * req_buf , size_t req_sz , void * resp_buf ,
323323 u32 resp_sz , __u64 * fw_err )
324324{
325- unsigned long err ;
325+ unsigned long err , override_err = 0 ;
326+ unsigned int override_npages = 0 ;
326327 u64 seqno ;
327328 int rc ;
328329
@@ -338,6 +339,7 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
338339 if (rc )
339340 return rc ;
340341
342+ retry_request :
341343 /*
342344 * Call firmware to process the request. In this function the encrypted
343345 * message enters shared memory with the host. So after this call the
@@ -346,17 +348,24 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
346348 */
347349 rc = snp_issue_guest_request (exit_code , & snp_dev -> input , & err );
348350
349- /*
350- * If the extended guest request fails due to having too small of a
351- * certificate data buffer, retry the same guest request without the
352- * extended data request in order to increment the sequence number
353- * and thus avoid IV reuse.
354- */
355- if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
356- err == SNP_GUEST_REQ_INVALID_LEN ) {
357- const unsigned int certs_npages = snp_dev -> input .data_npages ;
351+ switch (rc ) {
352+ case - ENOSPC :
353+ /*
354+ * If the extended guest request fails due to having too
355+ * small of a certificate data buffer, retry the same
356+ * guest request without the extended data request in
357+ * order to increment the sequence number and thus avoid
358+ * IV reuse.
359+ */
360+ override_npages = snp_dev -> input .data_npages ;
361+ exit_code = SVM_VMGEXIT_GUEST_REQUEST ;
358362
359- exit_code = SVM_VMGEXIT_GUEST_REQUEST ;
363+ /*
364+ * Override the error to inform callers the given extended
365+ * request buffer size was too small and give the caller the
366+ * required buffer size.
367+ */
368+ override_err = SNP_GUEST_REQ_INVALID_LEN ;
360369
361370 /*
362371 * If this call to the firmware succeeds, the sequence number can
@@ -366,15 +375,7 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
366375 * of the VMPCK and the error code being propagated back to the
367376 * user as an ioctl() return code.
368377 */
369- rc = snp_issue_guest_request (exit_code , & snp_dev -> input , & err );
370-
371- /*
372- * Override the error to inform callers the given extended
373- * request buffer size was too small and give the caller the
374- * required buffer size.
375- */
376- err = SNP_GUEST_REQ_INVALID_LEN ;
377- snp_dev -> input .data_npages = certs_npages ;
378+ goto retry_request ;
378379 }
379380
380381 /*
@@ -386,15 +387,18 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
386387 snp_inc_msg_seqno (snp_dev );
387388
388389 if (fw_err )
389- * fw_err = err ;
390+ * fw_err = override_err ?: err ;
391+
392+ if (override_npages )
393+ snp_dev -> input .data_npages = override_npages ;
390394
391395 /*
392396 * If an extended guest request was issued and the supplied certificate
393397 * buffer was not large enough, a standard guest request was issued to
394398 * prevent IV reuse. If the standard request was successful, return -EIO
395399 * back to the caller as would have originally been returned.
396400 */
397- if (!rc && err == SNP_GUEST_REQ_INVALID_LEN )
401+ if (!rc && override_err == SNP_GUEST_REQ_INVALID_LEN )
398402 return - EIO ;
399403
400404 if (rc ) {
0 commit comments