0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/kernel.h>
0012 #include <linux/types.h>
0013 #include <linux/mutex.h>
0014 #include <linux/io.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/miscdevice.h>
0017 #include <linux/set_memory.h>
0018 #include <linux/fs.h>
0019 #include <crypto/aead.h>
0020 #include <linux/scatterlist.h>
0021 #include <linux/psp-sev.h>
0022 #include <uapi/linux/sev-guest.h>
0023 #include <uapi/linux/psp-sev.h>
0024
0025 #include <asm/svm.h>
0026 #include <asm/sev.h>
0027
0028 #include "sev-guest.h"
0029
0030 #define DEVICE_NAME "sev-guest"
0031 #define AAD_LEN 48
0032 #define MSG_HDR_VER 1
0033
0034 struct snp_guest_crypto {
0035 struct crypto_aead *tfm;
0036 u8 *iv, *authtag;
0037 int iv_len, a_len;
0038 };
0039
0040 struct snp_guest_dev {
0041 struct device *dev;
0042 struct miscdevice misc;
0043
0044 void *certs_data;
0045 struct snp_guest_crypto *crypto;
0046 struct snp_guest_msg *request, *response;
0047 struct snp_secrets_page_layout *layout;
0048 struct snp_req_data input;
0049 u32 *os_area_msg_seqno;
0050 u8 *vmpck;
0051 };
0052
0053 static u32 vmpck_id;
0054 module_param(vmpck_id, uint, 0444);
0055 MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");
0056
0057
0058 static DEFINE_MUTEX(snp_cmd_mutex);
0059
0060 static bool is_vmpck_empty(struct snp_guest_dev *snp_dev)
0061 {
0062 char zero_key[VMPCK_KEY_LEN] = {0};
0063
0064 if (snp_dev->vmpck)
0065 return !memcmp(snp_dev->vmpck, zero_key, VMPCK_KEY_LEN);
0066
0067 return true;
0068 }
0069
0070 static void snp_disable_vmpck(struct snp_guest_dev *snp_dev)
0071 {
0072 memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN);
0073 snp_dev->vmpck = NULL;
0074 }
0075
0076 static inline u64 __snp_get_msg_seqno(struct snp_guest_dev *snp_dev)
0077 {
0078 u64 count;
0079
0080 lockdep_assert_held(&snp_cmd_mutex);
0081
0082
0083 count = *snp_dev->os_area_msg_seqno;
0084
0085 return count + 1;
0086 }
0087
0088
0089 static u64 snp_get_msg_seqno(struct snp_guest_dev *snp_dev)
0090 {
0091 u64 count = __snp_get_msg_seqno(snp_dev);
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 if (count >= UINT_MAX) {
0102 dev_err(snp_dev->dev, "request message sequence counter overflow\n");
0103 return 0;
0104 }
0105
0106 return count;
0107 }
0108
0109 static void snp_inc_msg_seqno(struct snp_guest_dev *snp_dev)
0110 {
0111
0112
0113
0114
0115 *snp_dev->os_area_msg_seqno += 2;
0116 }
0117
0118 static inline struct snp_guest_dev *to_snp_dev(struct file *file)
0119 {
0120 struct miscdevice *dev = file->private_data;
0121
0122 return container_of(dev, struct snp_guest_dev, misc);
0123 }
0124
0125 static struct snp_guest_crypto *init_crypto(struct snp_guest_dev *snp_dev, u8 *key, size_t keylen)
0126 {
0127 struct snp_guest_crypto *crypto;
0128
0129 crypto = kzalloc(sizeof(*crypto), GFP_KERNEL_ACCOUNT);
0130 if (!crypto)
0131 return NULL;
0132
0133 crypto->tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
0134 if (IS_ERR(crypto->tfm))
0135 goto e_free;
0136
0137 if (crypto_aead_setkey(crypto->tfm, key, keylen))
0138 goto e_free_crypto;
0139
0140 crypto->iv_len = crypto_aead_ivsize(crypto->tfm);
0141 crypto->iv = kmalloc(crypto->iv_len, GFP_KERNEL_ACCOUNT);
0142 if (!crypto->iv)
0143 goto e_free_crypto;
0144
0145 if (crypto_aead_authsize(crypto->tfm) > MAX_AUTHTAG_LEN) {
0146 if (crypto_aead_setauthsize(crypto->tfm, MAX_AUTHTAG_LEN)) {
0147 dev_err(snp_dev->dev, "failed to set authsize to %d\n", MAX_AUTHTAG_LEN);
0148 goto e_free_iv;
0149 }
0150 }
0151
0152 crypto->a_len = crypto_aead_authsize(crypto->tfm);
0153 crypto->authtag = kmalloc(crypto->a_len, GFP_KERNEL_ACCOUNT);
0154 if (!crypto->authtag)
0155 goto e_free_auth;
0156
0157 return crypto;
0158
0159 e_free_auth:
0160 kfree(crypto->authtag);
0161 e_free_iv:
0162 kfree(crypto->iv);
0163 e_free_crypto:
0164 crypto_free_aead(crypto->tfm);
0165 e_free:
0166 kfree(crypto);
0167
0168 return NULL;
0169 }
0170
0171 static void deinit_crypto(struct snp_guest_crypto *crypto)
0172 {
0173 crypto_free_aead(crypto->tfm);
0174 kfree(crypto->iv);
0175 kfree(crypto->authtag);
0176 kfree(crypto);
0177 }
0178
0179 static int enc_dec_message(struct snp_guest_crypto *crypto, struct snp_guest_msg *msg,
0180 u8 *src_buf, u8 *dst_buf, size_t len, bool enc)
0181 {
0182 struct snp_guest_msg_hdr *hdr = &msg->hdr;
0183 struct scatterlist src[3], dst[3];
0184 DECLARE_CRYPTO_WAIT(wait);
0185 struct aead_request *req;
0186 int ret;
0187
0188 req = aead_request_alloc(crypto->tfm, GFP_KERNEL);
0189 if (!req)
0190 return -ENOMEM;
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 sg_init_table(src, 3);
0201 sg_set_buf(&src[0], &hdr->algo, AAD_LEN);
0202 sg_set_buf(&src[1], src_buf, hdr->msg_sz);
0203 sg_set_buf(&src[2], hdr->authtag, crypto->a_len);
0204
0205 sg_init_table(dst, 3);
0206 sg_set_buf(&dst[0], &hdr->algo, AAD_LEN);
0207 sg_set_buf(&dst[1], dst_buf, hdr->msg_sz);
0208 sg_set_buf(&dst[2], hdr->authtag, crypto->a_len);
0209
0210 aead_request_set_ad(req, AAD_LEN);
0211 aead_request_set_tfm(req, crypto->tfm);
0212 aead_request_set_callback(req, 0, crypto_req_done, &wait);
0213
0214 aead_request_set_crypt(req, src, dst, len, crypto->iv);
0215 ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req), &wait);
0216
0217 aead_request_free(req);
0218 return ret;
0219 }
0220
0221 static int __enc_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg,
0222 void *plaintext, size_t len)
0223 {
0224 struct snp_guest_crypto *crypto = snp_dev->crypto;
0225 struct snp_guest_msg_hdr *hdr = &msg->hdr;
0226
0227 memset(crypto->iv, 0, crypto->iv_len);
0228 memcpy(crypto->iv, &hdr->msg_seqno, sizeof(hdr->msg_seqno));
0229
0230 return enc_dec_message(crypto, msg, plaintext, msg->payload, len, true);
0231 }
0232
0233 static int dec_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg,
0234 void *plaintext, size_t len)
0235 {
0236 struct snp_guest_crypto *crypto = snp_dev->crypto;
0237 struct snp_guest_msg_hdr *hdr = &msg->hdr;
0238
0239
0240 memset(crypto->iv, 0, crypto->iv_len);
0241 memcpy(crypto->iv, &hdr->msg_seqno, sizeof(hdr->msg_seqno));
0242
0243 return enc_dec_message(crypto, msg, msg->payload, plaintext, len, false);
0244 }
0245
0246 static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, u32 sz)
0247 {
0248 struct snp_guest_crypto *crypto = snp_dev->crypto;
0249 struct snp_guest_msg *resp = snp_dev->response;
0250 struct snp_guest_msg *req = snp_dev->request;
0251 struct snp_guest_msg_hdr *req_hdr = &req->hdr;
0252 struct snp_guest_msg_hdr *resp_hdr = &resp->hdr;
0253
0254 dev_dbg(snp_dev->dev, "response [seqno %lld type %d version %d sz %d]\n",
0255 resp_hdr->msg_seqno, resp_hdr->msg_type, resp_hdr->msg_version, resp_hdr->msg_sz);
0256
0257
0258 if (unlikely(resp_hdr->msg_seqno != (req_hdr->msg_seqno + 1)))
0259 return -EBADMSG;
0260
0261
0262 if (resp_hdr->msg_type != (req_hdr->msg_type + 1) ||
0263 resp_hdr->msg_version != req_hdr->msg_version)
0264 return -EBADMSG;
0265
0266
0267
0268
0269
0270 if (unlikely((resp_hdr->msg_sz + crypto->a_len) > sz))
0271 return -EBADMSG;
0272
0273
0274 return dec_payload(snp_dev, resp, payload, resp_hdr->msg_sz + crypto->a_len);
0275 }
0276
0277 static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type,
0278 void *payload, size_t sz)
0279 {
0280 struct snp_guest_msg *req = snp_dev->request;
0281 struct snp_guest_msg_hdr *hdr = &req->hdr;
0282
0283 memset(req, 0, sizeof(*req));
0284
0285 hdr->algo = SNP_AEAD_AES_256_GCM;
0286 hdr->hdr_version = MSG_HDR_VER;
0287 hdr->hdr_sz = sizeof(*hdr);
0288 hdr->msg_type = type;
0289 hdr->msg_version = version;
0290 hdr->msg_seqno = seqno;
0291 hdr->msg_vmpck = vmpck_id;
0292 hdr->msg_sz = sz;
0293
0294
0295 if (!hdr->msg_seqno)
0296 return -ENOSR;
0297
0298 dev_dbg(snp_dev->dev, "request [seqno %lld type %d version %d sz %d]\n",
0299 hdr->msg_seqno, hdr->msg_type, hdr->msg_version, hdr->msg_sz);
0300
0301 return __enc_payload(snp_dev, req, payload, sz);
0302 }
0303
0304 static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver,
0305 u8 type, void *req_buf, size_t req_sz, void *resp_buf,
0306 u32 resp_sz, __u64 *fw_err)
0307 {
0308 unsigned long err;
0309 u64 seqno;
0310 int rc;
0311
0312
0313 seqno = snp_get_msg_seqno(snp_dev);
0314 if (!seqno)
0315 return -EIO;
0316
0317 memset(snp_dev->response, 0, sizeof(struct snp_guest_msg));
0318
0319
0320 rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz);
0321 if (rc)
0322 return rc;
0323
0324
0325 rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
0326 if (fw_err)
0327 *fw_err = err;
0328
0329 if (rc)
0330 return rc;
0331
0332
0333
0334
0335
0336
0337
0338
0339 rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz);
0340 if (rc) {
0341 dev_alert(snp_dev->dev,
0342 "Detected unexpected decode failure, disabling the vmpck_id %d\n",
0343 vmpck_id);
0344 snp_disable_vmpck(snp_dev);
0345 return rc;
0346 }
0347
0348
0349 snp_inc_msg_seqno(snp_dev);
0350
0351 return 0;
0352 }
0353
0354 static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
0355 {
0356 struct snp_guest_crypto *crypto = snp_dev->crypto;
0357 struct snp_report_resp *resp;
0358 struct snp_report_req req;
0359 int rc, resp_len;
0360
0361 lockdep_assert_held(&snp_cmd_mutex);
0362
0363 if (!arg->req_data || !arg->resp_data)
0364 return -EINVAL;
0365
0366 if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req)))
0367 return -EFAULT;
0368
0369
0370
0371
0372
0373
0374 resp_len = sizeof(resp->data) + crypto->a_len;
0375 resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
0376 if (!resp)
0377 return -ENOMEM;
0378
0379 rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version,
0380 SNP_MSG_REPORT_REQ, &req, sizeof(req), resp->data,
0381 resp_len, &arg->fw_err);
0382 if (rc)
0383 goto e_free;
0384
0385 if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp)))
0386 rc = -EFAULT;
0387
0388 e_free:
0389 kfree(resp);
0390 return rc;
0391 }
0392
0393 static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
0394 {
0395 struct snp_guest_crypto *crypto = snp_dev->crypto;
0396 struct snp_derived_key_resp resp = {0};
0397 struct snp_derived_key_req req;
0398 int rc, resp_len;
0399
0400 u8 buf[64 + 16];
0401
0402 lockdep_assert_held(&snp_cmd_mutex);
0403
0404 if (!arg->req_data || !arg->resp_data)
0405 return -EINVAL;
0406
0407
0408
0409
0410
0411
0412 resp_len = sizeof(resp.data) + crypto->a_len;
0413 if (sizeof(buf) < resp_len)
0414 return -ENOMEM;
0415
0416 if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req)))
0417 return -EFAULT;
0418
0419 rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version,
0420 SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len,
0421 &arg->fw_err);
0422 if (rc)
0423 return rc;
0424
0425 memcpy(resp.data, buf, sizeof(resp.data));
0426 if (copy_to_user((void __user *)arg->resp_data, &resp, sizeof(resp)))
0427 rc = -EFAULT;
0428
0429
0430 memzero_explicit(buf, sizeof(buf));
0431 memzero_explicit(&resp, sizeof(resp));
0432 return rc;
0433 }
0434
0435 static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
0436 {
0437 struct snp_guest_crypto *crypto = snp_dev->crypto;
0438 struct snp_ext_report_req req;
0439 struct snp_report_resp *resp;
0440 int ret, npages = 0, resp_len;
0441
0442 lockdep_assert_held(&snp_cmd_mutex);
0443
0444 if (!arg->req_data || !arg->resp_data)
0445 return -EINVAL;
0446
0447 if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req)))
0448 return -EFAULT;
0449
0450
0451 if (!req.certs_len || !req.certs_address)
0452 goto cmd;
0453
0454 if (req.certs_len > SEV_FW_BLOB_MAX_SIZE ||
0455 !IS_ALIGNED(req.certs_len, PAGE_SIZE))
0456 return -EINVAL;
0457
0458 if (!access_ok((const void __user *)req.certs_address, req.certs_len))
0459 return -EFAULT;
0460
0461
0462
0463
0464
0465
0466
0467 memset(snp_dev->certs_data, 0, req.certs_len);
0468 npages = req.certs_len >> PAGE_SHIFT;
0469 cmd:
0470
0471
0472
0473
0474
0475 resp_len = sizeof(resp->data) + crypto->a_len;
0476 resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
0477 if (!resp)
0478 return -ENOMEM;
0479
0480 snp_dev->input.data_npages = npages;
0481 ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version,
0482 SNP_MSG_REPORT_REQ, &req.data,
0483 sizeof(req.data), resp->data, resp_len, &arg->fw_err);
0484
0485
0486 if (arg->fw_err == SNP_GUEST_REQ_INVALID_LEN) {
0487 req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT;
0488
0489 if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req)))
0490 ret = -EFAULT;
0491 }
0492
0493 if (ret)
0494 goto e_free;
0495
0496 if (npages &&
0497 copy_to_user((void __user *)req.certs_address, snp_dev->certs_data,
0498 req.certs_len)) {
0499 ret = -EFAULT;
0500 goto e_free;
0501 }
0502
0503 if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp)))
0504 ret = -EFAULT;
0505
0506 e_free:
0507 kfree(resp);
0508 return ret;
0509 }
0510
0511 static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
0512 {
0513 struct snp_guest_dev *snp_dev = to_snp_dev(file);
0514 void __user *argp = (void __user *)arg;
0515 struct snp_guest_request_ioctl input;
0516 int ret = -ENOTTY;
0517
0518 if (copy_from_user(&input, argp, sizeof(input)))
0519 return -EFAULT;
0520
0521 input.fw_err = 0xff;
0522
0523
0524 if (!input.msg_version)
0525 return -EINVAL;
0526
0527 mutex_lock(&snp_cmd_mutex);
0528
0529
0530 if (is_vmpck_empty(snp_dev)) {
0531 dev_err_ratelimited(snp_dev->dev, "VMPCK is disabled\n");
0532 mutex_unlock(&snp_cmd_mutex);
0533 return -ENOTTY;
0534 }
0535
0536 switch (ioctl) {
0537 case SNP_GET_REPORT:
0538 ret = get_report(snp_dev, &input);
0539 break;
0540 case SNP_GET_DERIVED_KEY:
0541 ret = get_derived_key(snp_dev, &input);
0542 break;
0543 case SNP_GET_EXT_REPORT:
0544 ret = get_ext_report(snp_dev, &input);
0545 break;
0546 default:
0547 break;
0548 }
0549
0550 mutex_unlock(&snp_cmd_mutex);
0551
0552 if (input.fw_err && copy_to_user(argp, &input, sizeof(input)))
0553 return -EFAULT;
0554
0555 return ret;
0556 }
0557
0558 static void free_shared_pages(void *buf, size_t sz)
0559 {
0560 unsigned int npages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
0561 int ret;
0562
0563 if (!buf)
0564 return;
0565
0566 ret = set_memory_encrypted((unsigned long)buf, npages);
0567 if (ret) {
0568 WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n");
0569 return;
0570 }
0571
0572 __free_pages(virt_to_page(buf), get_order(sz));
0573 }
0574
0575 static void *alloc_shared_pages(struct device *dev, size_t sz)
0576 {
0577 unsigned int npages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
0578 struct page *page;
0579 int ret;
0580
0581 page = alloc_pages(GFP_KERNEL_ACCOUNT, get_order(sz));
0582 if (!page)
0583 return NULL;
0584
0585 ret = set_memory_decrypted((unsigned long)page_address(page), npages);
0586 if (ret) {
0587 dev_err(dev, "failed to mark page shared, ret=%d\n", ret);
0588 __free_pages(page, get_order(sz));
0589 return NULL;
0590 }
0591
0592 return page_address(page);
0593 }
0594
0595 static const struct file_operations snp_guest_fops = {
0596 .owner = THIS_MODULE,
0597 .unlocked_ioctl = snp_guest_ioctl,
0598 };
0599
0600 static u8 *get_vmpck(int id, struct snp_secrets_page_layout *layout, u32 **seqno)
0601 {
0602 u8 *key = NULL;
0603
0604 switch (id) {
0605 case 0:
0606 *seqno = &layout->os_area.msg_seqno_0;
0607 key = layout->vmpck0;
0608 break;
0609 case 1:
0610 *seqno = &layout->os_area.msg_seqno_1;
0611 key = layout->vmpck1;
0612 break;
0613 case 2:
0614 *seqno = &layout->os_area.msg_seqno_2;
0615 key = layout->vmpck2;
0616 break;
0617 case 3:
0618 *seqno = &layout->os_area.msg_seqno_3;
0619 key = layout->vmpck3;
0620 break;
0621 default:
0622 break;
0623 }
0624
0625 return key;
0626 }
0627
0628 static int __init sev_guest_probe(struct platform_device *pdev)
0629 {
0630 struct snp_secrets_page_layout *layout;
0631 struct sev_guest_platform_data *data;
0632 struct device *dev = &pdev->dev;
0633 struct snp_guest_dev *snp_dev;
0634 struct miscdevice *misc;
0635 void __iomem *mapping;
0636 int ret;
0637
0638 if (!dev->platform_data)
0639 return -ENODEV;
0640
0641 data = (struct sev_guest_platform_data *)dev->platform_data;
0642 mapping = ioremap_encrypted(data->secrets_gpa, PAGE_SIZE);
0643 if (!mapping)
0644 return -ENODEV;
0645
0646 layout = (__force void *)mapping;
0647
0648 ret = -ENOMEM;
0649 snp_dev = devm_kzalloc(&pdev->dev, sizeof(struct snp_guest_dev), GFP_KERNEL);
0650 if (!snp_dev)
0651 goto e_unmap;
0652
0653 ret = -EINVAL;
0654 snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno);
0655 if (!snp_dev->vmpck) {
0656 dev_err(dev, "invalid vmpck id %d\n", vmpck_id);
0657 goto e_unmap;
0658 }
0659
0660
0661 if (is_vmpck_empty(snp_dev)) {
0662 dev_err(dev, "vmpck id %d is null\n", vmpck_id);
0663 goto e_unmap;
0664 }
0665
0666 platform_set_drvdata(pdev, snp_dev);
0667 snp_dev->dev = dev;
0668 snp_dev->layout = layout;
0669
0670
0671 snp_dev->request = alloc_shared_pages(dev, sizeof(struct snp_guest_msg));
0672 if (!snp_dev->request)
0673 goto e_unmap;
0674
0675 snp_dev->response = alloc_shared_pages(dev, sizeof(struct snp_guest_msg));
0676 if (!snp_dev->response)
0677 goto e_free_request;
0678
0679 snp_dev->certs_data = alloc_shared_pages(dev, SEV_FW_BLOB_MAX_SIZE);
0680 if (!snp_dev->certs_data)
0681 goto e_free_response;
0682
0683 ret = -EIO;
0684 snp_dev->crypto = init_crypto(snp_dev, snp_dev->vmpck, VMPCK_KEY_LEN);
0685 if (!snp_dev->crypto)
0686 goto e_free_cert_data;
0687
0688 misc = &snp_dev->misc;
0689 misc->minor = MISC_DYNAMIC_MINOR;
0690 misc->name = DEVICE_NAME;
0691 misc->fops = &snp_guest_fops;
0692
0693
0694 snp_dev->input.req_gpa = __pa(snp_dev->request);
0695 snp_dev->input.resp_gpa = __pa(snp_dev->response);
0696 snp_dev->input.data_gpa = __pa(snp_dev->certs_data);
0697
0698 ret = misc_register(misc);
0699 if (ret)
0700 goto e_free_cert_data;
0701
0702 dev_info(dev, "Initialized SEV guest driver (using vmpck_id %d)\n", vmpck_id);
0703 return 0;
0704
0705 e_free_cert_data:
0706 free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE);
0707 e_free_response:
0708 free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg));
0709 e_free_request:
0710 free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg));
0711 e_unmap:
0712 iounmap(mapping);
0713 return ret;
0714 }
0715
0716 static int __exit sev_guest_remove(struct platform_device *pdev)
0717 {
0718 struct snp_guest_dev *snp_dev = platform_get_drvdata(pdev);
0719
0720 free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE);
0721 free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg));
0722 free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg));
0723 deinit_crypto(snp_dev->crypto);
0724 misc_deregister(&snp_dev->misc);
0725
0726 return 0;
0727 }
0728
0729
0730
0731
0732
0733
0734 static struct platform_driver sev_guest_driver = {
0735 .remove = __exit_p(sev_guest_remove),
0736 .driver = {
0737 .name = "sev-guest",
0738 },
0739 };
0740
0741 module_platform_driver_probe(sev_guest_driver, sev_guest_probe);
0742
0743 MODULE_AUTHOR("Brijesh Singh <brijesh.singh@amd.com>");
0744 MODULE_LICENSE("GPL");
0745 MODULE_VERSION("1.0.0");
0746 MODULE_DESCRIPTION("AMD SEV Guest Driver");