Commit 3f83ab6f authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Borislav Petkov (AMD)
Browse files

virt: sev-guest: Contain snp_guest_request_ioctl in sev-guest



SNP Guest Request uses only exitinfo2 which is a return value from GHCB, has
meaning beyond ioctl and therefore belongs to struct snp_guest_req.

Move exitinfo2 there and remove snp_guest_request_ioctl from the SEV platform
code.

No functional change intended.

Signed-off-by: default avatarAlexey Kardashevskiy <aik@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: default avatarDionna Glaze <dionnaglaze@google.com>
Link: https://lore.kernel.org/20250611040842.2667262-2-aik@amd.com
parent e04c78d8
Loading
Loading
Loading
Loading
+13 −23
Original line number Diff line number Diff line
@@ -1389,8 +1389,7 @@ int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call,
}
EXPORT_SYMBOL_GPL(snp_issue_svsm_attest_req);

static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_data *input,
				   struct snp_guest_request_ioctl *rio)
static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_data *input)
{
	struct ghcb_state state;
	struct es_em_ctxt ctxt;
@@ -1398,7 +1397,7 @@ static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_dat
	struct ghcb *ghcb;
	int ret;

	rio->exitinfo2 = SEV_RET_NO_FW_CALL;
	req->exitinfo2 = SEV_RET_NO_FW_CALL;

	/*
	 * __sev_get_ghcb() needs to run with IRQs disabled because it is using
@@ -1423,8 +1422,8 @@ static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_dat
	if (ret)
		goto e_put;

	rio->exitinfo2 = ghcb->save.sw_exit_info_2;
	switch (rio->exitinfo2) {
	req->exitinfo2 = ghcb->save.sw_exit_info_2;
	switch (req->exitinfo2) {
	case 0:
		break;

@@ -1919,8 +1918,7 @@ static int enc_payload(struct snp_msg_desc *mdesc, u64 seqno, struct snp_guest_r
	return 0;
}

static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
				  struct snp_guest_request_ioctl *rio)
static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req)
{
	unsigned long req_start = jiffies;
	unsigned int override_npages = 0;
@@ -1934,7 +1932,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
	 * sequence number must be incremented or the VMPCK must be deleted to
	 * prevent reuse of the IV.
	 */
	rc = snp_issue_guest_request(req, &req->input, rio);
	rc = snp_issue_guest_request(req, &req->input);
	switch (rc) {
	case -ENOSPC:
		/*
@@ -1987,7 +1985,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
	snp_inc_msg_seqno(mdesc);

	if (override_err) {
		rio->exitinfo2 = override_err;
		req->exitinfo2 = override_err;

		/*
		 * If an extended guest request was issued and the supplied certificate
@@ -2005,8 +2003,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
	return rc;
}

int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
			   struct snp_guest_request_ioctl *rio)
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req)
{
	u64 seqno;
	int rc;
@@ -2043,14 +2040,14 @@ int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req
	req->input.resp_gpa = __pa(mdesc->response);
	req->input.data_gpa = req->certs_data ? __pa(req->certs_data) : 0;

	rc = __handle_guest_request(mdesc, req, rio);
	rc = __handle_guest_request(mdesc, req);
	if (rc) {
		if (rc == -EIO &&
		    rio->exitinfo2 == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN))
		    req->exitinfo2 == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN))
			return rc;

		pr_alert("Detected error from ASP request. rc: %d, exitinfo2: 0x%llx\n",
			 rc, rio->exitinfo2);
			 rc, req->exitinfo2);

		snp_disable_vmpck(mdesc);
		return rc;
@@ -2069,7 +2066,6 @@ EXPORT_SYMBOL_GPL(snp_send_guest_request);

static int __init snp_get_tsc_info(void)
{
	struct snp_guest_request_ioctl *rio;
	struct snp_tsc_info_resp *tsc_resp;
	struct snp_tsc_info_req *tsc_req;
	struct snp_msg_desc *mdesc;
@@ -2093,13 +2089,9 @@ static int __init snp_get_tsc_info(void)
	if (!req)
		goto e_free_tsc_resp;

	rio = kzalloc(sizeof(*rio), GFP_KERNEL);
	if (!rio)
		goto e_free_req;

	mdesc = snp_msg_alloc();
	if (IS_ERR_OR_NULL(mdesc))
		goto e_free_rio;
		goto e_free_req;

	rc = snp_msg_init(mdesc, snp_vmpl);
	if (rc)
@@ -2114,7 +2106,7 @@ static int __init snp_get_tsc_info(void)
	req->resp_sz = sizeof(*tsc_resp) + AUTHTAG_LEN;
	req->exit_code = SVM_VMGEXIT_GUEST_REQUEST;

	rc = snp_send_guest_request(mdesc, req, rio);
	rc = snp_send_guest_request(mdesc, req);
	if (rc)
		goto e_request;

@@ -2135,8 +2127,6 @@ static int __init snp_get_tsc_info(void)
	memzero_explicit(tsc_resp, sizeof(*tsc_resp) + AUTHTAG_LEN);
e_free_mdesc:
	snp_msg_free(mdesc);
e_free_rio:
	kfree(rio);
e_free_req:
	kfree(req);
 e_free_tsc_resp:
+4 −6
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ struct snp_guest_req {
	size_t resp_sz;

	u64 exit_code;
	u64 exitinfo2;
	unsigned int vmpck_id;
	u8 msg_version;
	u8 msg_type;
@@ -486,8 +487,6 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
	return rc;
}

struct snp_guest_request_ioctl;

void setup_ghcb(void);
void early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
				  unsigned long npages);
@@ -513,8 +512,7 @@ void snp_kexec_begin(void);
int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id);
struct snp_msg_desc *snp_msg_alloc(void);
void snp_msg_free(struct snp_msg_desc *mdesc);
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
			   struct snp_guest_request_ioctl *rio);
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req);

int snp_svsm_vtpm_send_command(u8 *buffer);

@@ -587,8 +585,8 @@ static inline void snp_kexec_begin(void) { }
static inline int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id) { return -1; }
static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
					 struct snp_guest_request_ioctl *rio) { return -ENODEV; }
static inline int snp_send_guest_request(struct snp_msg_desc *mdesc,
					 struct snp_guest_req *req) { return -ENODEV; }
static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
static inline void __init snp_secure_tsc_prepare(void) { }
static inline void __init snp_secure_tsc_init(void) { }
+6 −3
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
	req.resp_sz = resp_len;
	req.exit_code = SVM_VMGEXIT_GUEST_REQUEST;

	rc = snp_send_guest_request(mdesc, &req, arg);
	rc = snp_send_guest_request(mdesc, &req);
	arg->exitinfo2 = req.exitinfo2;
	if (rc)
		goto e_free;

@@ -152,7 +153,8 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
	req.resp_sz = resp_len;
	req.exit_code = SVM_VMGEXIT_GUEST_REQUEST;

	rc = snp_send_guest_request(mdesc, &req, arg);
	rc = snp_send_guest_request(mdesc, &req);
	arg->exitinfo2 = req.exitinfo2;
	if (rc)
		return rc;

@@ -249,7 +251,8 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
	req.resp_sz = resp_len;
	req.exit_code = SVM_VMGEXIT_EXT_GUEST_REQUEST;

	ret = snp_send_guest_request(mdesc, &req, arg);
	ret = snp_send_guest_request(mdesc, &req);
	arg->exitinfo2 = req.exitinfo2;

	/* If certs length is invalid then copy the returned length */
	if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {