linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@suse.de>
To: Brijesh Singh <brijesh.singh@amd.com>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
	kvm@vger.kernel.org, "Thomas Gleixner" <tglx@linutronix.de>,
	"Joerg Roedel" <joro@8bytes.org>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"\\\"Radim Krčmář\\\"" <rkrcmar@redhat.com>,
	"Tom Lendacky" <thomas.lendacky@amd.com>
Subject: Re: [RFC Part2 PATCH v3 13/26] KVM: SVM: Add KVM_SEV_INIT command
Date: Wed, 13 Sep 2017 17:06:36 +0200	[thread overview]
Message-ID: <20170913150636.fcjhbg7wdf2whmy2@pd.tnic> (raw)
In-Reply-To: <20170724200303.12197-14-brijesh.singh@amd.com>

On Mon, Jul 24, 2017 at 03:02:50PM -0500, Brijesh Singh wrote:
> The command initializes the SEV firmware and allocate a new ASID for

					       allocates

> this guest from SEV ASID pool. The firmware must be initialized before

	     from the

> we issue guest launch command to create a new encryption context.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  arch/x86/kvm/svm.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 187 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 2a5a03a..e99a572 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -37,6 +37,8 @@
>  #include <linux/amd-iommu.h>
>  #include <linux/hashtable.h>
>  #include <linux/frame.h>
> +#include <linux/psp-sev.h>
> +#include <linux/file.h>
>  
>  #include <asm/apic.h>
>  #include <asm/perf_event.h>
> @@ -321,6 +323,14 @@ enum {
>  
>  /* Secure Encrypted Virtualization */
>  static unsigned int max_sev_asid;
> +static unsigned long *sev_asid_bitmap;
> +static int sev_asid_new(void);

This forward declaration is superfluous.

> +static void sev_asid_free(int asid);

You can move the sev_asid* code up and thus get rid of this forward
declaration too.

And also, svm.c is really huge. We probably should think about splitting
it in logical pieces... But that's for another day.

> +
> +static bool svm_sev_enabled(void)
> +{
> +	return !!max_sev_asid;

You don't need the "!!".

> +}
>  
>  static inline struct kvm_sev_info *to_sev_info(struct kvm *kvm)
>  {
> @@ -1093,6 +1103,12 @@ static __init void sev_hardware_setup(void)
>  	if (!nguests)
>  		return;
>  
> +	/* Initialize SEV ASID bitmap */
> +	sev_asid_bitmap = kcalloc(BITS_TO_LONGS(nguests),
> +				  sizeof(unsigned long), GFP_KERNEL);
> +	if (IS_ERR(sev_asid_bitmap))
> +		return;
> +
>  	max_sev_asid = nguests;
>  }
>  
> @@ -1184,10 +1200,18 @@ static __init int svm_hardware_setup(void)
>  	return r;
>  }
>  
> +static __exit void sev_hardware_unsetup(void)
> +{
> +	kfree(sev_asid_bitmap);
> +}
> +
>  static __exit void svm_hardware_unsetup(void)

"unsetup" - oh my. :)

>  	int cpu;
>  
> +	if (svm_sev_enabled())
> +		sev_hardware_unsetup();
> +
>  	for_each_possible_cpu(cpu)
>  		svm_cpu_uninit(cpu);
>  
> @@ -1373,6 +1397,9 @@ static void init_vmcb(struct vcpu_svm *svm)
>  		svm->vmcb->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK;
>  	}
>  
> +	if (sev_guest(svm->vcpu.kvm))
> +		svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE;
> +
>  	mark_all_dirty(svm->vmcb);
>  
>  	enable_gif(svm);
> @@ -1483,6 +1510,51 @@ static inline int avic_free_vm_id(int id)
>  	return 0;
>  }
>  
> +static int sev_platform_get_state(int *state, int *error)
> +{
> +	int ret;
> +	struct sev_data_status *data;
> +
> +	data = kzalloc(sizeof(*data), GFP_KERNEL);

It's a bit silly to do the allocation only for the duration of
sev_platform_status() - just allocate "data" on the stack.

> +	if (!data)
> +		return -ENOMEM;
> +
> +	ret = sev_platform_status(data, error);
> +	if (!ret)
> +		*state = data->state;
> +
> +	kfree(data);
> +	return ret;
> +}
> +
> +static void sev_firmware_uninit(void)

I guess sev_firmware_exit() or so.

> +{
> +	int rc, state, error;
> +
> +	rc = sev_platform_get_state(&state, &error);
> +	if (rc) {
> +		pr_err("SEV: failed to get firmware state (%#x)\n",
> +				error);

error fits on the same line.

> +		return;
> +	}
> +
> +	/* If we are in initialized state then uninitialize it */
> +	if (state == SEV_STATE_INIT)
> +		sev_platform_shutdown(&error);
> +
> +}
> +
> +static void sev_vm_destroy(struct kvm *kvm)
> +{
> +	int state, error;

arch/x86/kvm/svm.c: In function ‘sev_vm_destroy’:
arch/x86/kvm/svm.c:1548:13: warning: unused variable ‘error’ [-Wunused-variable]
  int state, error;
             ^~~~~
arch/x86/kvm/svm.c:1548:6: warning: unused variable ‘state’ [-Wunused-variable]
  int state, error;
      ^~~~~

> +
> +	if (!sev_guest(kvm))
> +		return;
> +
> +	sev_asid_free(sev_get_asid(kvm));
> +	sev_firmware_uninit();

I think you want to destroy the firmware context first and then free the
asid.

> +}
> +
>  static void avic_vm_destroy(struct kvm *kvm)
>  {
>  	unsigned long flags;
> @@ -1503,6 +1575,12 @@ static void avic_vm_destroy(struct kvm *kvm)
>  	spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags);
>  }
>  
> +static void svm_vm_destroy(struct kvm *kvm)
> +{
> +	avic_vm_destroy(kvm);
> +	sev_vm_destroy(kvm);
> +}
> +
>  static int avic_vm_init(struct kvm *kvm)
>  {
>  	unsigned long flags;
> @@ -5428,6 +5506,112 @@ static void svm_setup_mce(struct kvm_vcpu *vcpu)
>  	vcpu->arch.mcg_cap &= 0x1ff;
>  }
>  
> +static int sev_asid_new(void)
> +{
> +	int pos;
> +
> +	if (!max_sev_asid)

	if (!svm_sev_enabled())

since you have an accessor.

> +		return -EINVAL;
> +
> +	pos = find_first_zero_bit(sev_asid_bitmap, max_sev_asid);
> +	if (pos >= max_sev_asid)
> +		return -EBUSY;
> +
> +	set_bit(pos, sev_asid_bitmap);
> +	return pos + 1;
> +}
> +
> +static void sev_asid_free(int asid)
> +{
> +	int pos;

	if (!svm_sev_enabled())
		return;
> +
> +	pos = asid - 1;
> +	clear_bit(pos, sev_asid_bitmap);
> +}
> +
> +static int sev_firmware_init(int *error)
> +{
> +	int ret, state;
> +
> +	ret = sev_platform_get_state(&state, error);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * If SEV firmware is in uninitialized state, lets initialize the
> +	 * firmware before issuing guest commands.
> +	 */
> +	if (state == SEV_STATE_UNINIT) {
> +		struct sev_data_init *data;

Same note as above - allocate data on the stack.

> +
> +		data = kzalloc(sizeof(*data), GFP_KERNEL);
> +		if (!data)
> +			return -ENOMEM;
> +
> +		ret = sev_platform_init(data, error);
> +		kfree(data);
> +	}
> +
> +	return ret;
> +}
> +
> +static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
> +{
> +	int asid, ret;
> +	struct fd f;
> +
> +	f = fdget(argp->sev_fd);
> +	if (!f.file)
> +		return -EBADF;
> +
> +	/* initialize the SEV firmware */
> +	ret = sev_firmware_init(&argp->error);
> +	if (ret)
> +		goto e_err;
> +
> +	/* allocate asid from SEV pool */
> +	ret = -ENOTTY;
> +	asid = sev_asid_new();
> +	if (asid < 0) {
> +		pr_err("SEV: failed to get free asid\n");
> +		sev_platform_shutdown(&argp->error);
> +		goto e_err;
> +	}
> +
> +	sev_set_active(kvm);

I think that should be the last thing you execute before returning.

> +	sev_set_asid(kvm, asid);
> +	sev_set_fd(kvm, argp->sev_fd);
> +	ret = 0;
> +e_err:
> +	fdput(f);
> +	return ret;
> +}
> +
> +static int svm_memory_encryption_op(struct kvm *kvm, void __user *argp)
> +{
> +	struct kvm_sev_cmd sev_cmd;
> +	int r = -ENOTTY;
> +
> +	if (copy_from_user(&sev_cmd, argp, sizeof(struct kvm_sev_cmd)))
> +		return -EFAULT;

Sanity-check that sev_cmd.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

  reply	other threads:[~2017-09-13 15:06 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-24 20:02 [RFC Part2 PATCH v3 00/26] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-07-24 20:02 ` [RFC Part2 PATCH v3 01/26] Documentation/virtual/kvm: Add AMD Secure Encrypted Virtualization (SEV) Brijesh Singh
2017-09-05 17:21   ` Borislav Petkov
2017-09-05 21:39     ` Brijesh Singh
2017-09-05 22:06       ` Borislav Petkov
2017-09-06 16:41       ` Borislav Petkov
2017-09-06 20:54         ` Brijesh Singh
2017-07-24 20:02 ` [RFC Part2 PATCH v3 02/26] crypto: ccp: Add Platform Security Processor (PSP) device support Brijesh Singh
2017-07-25  8:29   ` Kamil Konieczny
2017-07-25 15:00     ` Brijesh Singh
2017-09-06 17:00   ` Borislav Petkov
2017-09-06 20:38     ` Brijesh Singh
2017-09-06 20:46       ` Borislav Petkov
2017-09-06 21:26         ` Gary R Hook
2017-09-07 10:34           ` Borislav Petkov
2017-09-07 14:27   ` Borislav Petkov
2017-09-07 22:19     ` Brijesh Singh
2017-09-07 23:15       ` Gary R Hook
2017-09-08  8:22         ` Borislav Petkov
2017-09-08  8:40       ` Borislav Petkov
2017-09-08 13:54         ` Brijesh Singh
2017-09-08 16:06         ` Brijesh Singh
2017-07-24 20:02 ` [RFC Part2 PATCH v3 03/26] crypto: ccp: Add Secure Encrypted Virtualization (SEV) " Brijesh Singh
2017-09-12 14:02   ` Borislav Petkov
2017-09-12 15:32     ` Brijesh Singh
2017-09-12 16:29       ` Borislav Petkov
2017-09-13 14:17   ` Borislav Petkov
2017-09-13 15:18     ` Brijesh Singh
2017-07-24 20:02 ` [RFC Part2 PATCH v3 04/26] KVM: SVM: Prepare to reserve asid for SEV guest Brijesh Singh
2017-09-12 19:54   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 05/26] KVM: SVM: Reserve ASID range " Brijesh Singh
2017-09-12 20:04   ` Borislav Petkov
2017-09-12 20:24     ` Brijesh Singh
2017-09-12 20:28       ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 06/26] KVM: SVM: Prepare for new bit definition in nested_ctl Brijesh Singh
2017-09-12 20:06   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 07/26] KVM: SVM: Add SEV feature definitions to KVM Brijesh Singh
2017-09-12 20:08   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 08/26] KVM: X86: Extend CPUID range to include new leaf Brijesh Singh
2017-09-12 20:12   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 09/26] KVM: Introduce KVM_MEMORY_ENCRYPT_OP ioctl Brijesh Singh
2017-09-12 20:19   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 10/26] KVM: Introduce KVM_MEMORY_ENCRYPT_REGISTER/UNREGISTER_RAM ioctl Brijesh Singh
2017-09-12 20:29   ` Borislav Petkov
2017-09-12 20:50     ` Brijesh Singh
2017-09-12 21:08       ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 11/26] KVM: X86: Extend struct kvm_arch to include SEV information Brijesh Singh
2017-09-13 13:37   ` Borislav Petkov
2017-09-13 15:14     ` Brijesh Singh
2017-09-13 15:21       ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 12/26] KVM: Define SEV key management command id Brijesh Singh
2017-09-13 13:45   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 13/26] KVM: SVM: Add KVM_SEV_INIT command Brijesh Singh
2017-09-13 15:06   ` Borislav Petkov [this message]
2017-09-13 16:23     ` Brijesh Singh
2017-09-13 16:37       ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 14/26] KVM: SVM: VMRUN should use assosiated ASID when SEV is enabled Brijesh Singh
2017-09-13 15:37   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 15/26] KVM: SVM: Add support for SEV LAUNCH_START command Brijesh Singh
2017-09-13 17:25   ` Borislav Petkov
2017-09-13 18:23     ` Brijesh Singh
2017-09-13 18:37       ` Borislav Petkov
2017-09-13 18:58         ` Brijesh Singh
2017-09-13 21:02           ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 16/26] KVM: SVM: Add support for SEV LAUNCH_UPDATE_DATA command Brijesh Singh
2017-09-13 17:55   ` Borislav Petkov
2017-09-13 19:45     ` Brijesh Singh
2017-09-13 21:07       ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 17/26] KVM: SVM: Add support for SEV LAUNCH_MEASURE command Brijesh Singh
2017-09-14 10:20   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 18/26] KVM: SVM: Add support for SEV LAUNCH_FINISH command Brijesh Singh
2017-09-14 10:24   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 19/26] KVM: svm: Add support for SEV GUEST_STATUS command Brijesh Singh
2017-09-14 10:35   ` Borislav Petkov
2017-09-14 11:25     ` Brijesh Singh
2017-07-24 20:02 ` [RFC Part2 PATCH v3 20/26] KVM: SVM: Add support for SEV DEBUG_DECRYPT command Brijesh Singh
2017-09-14 11:08   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 21/26] KVM: SVM: Add support for SEV DEBUG_ENCRYPT command Brijesh Singh
2017-09-14 13:32   ` Borislav Petkov
2017-07-24 20:02 ` [RFC Part2 PATCH v3 22/26] KVM: SVM: Pin guest memory when SEV is active Brijesh Singh
2017-09-14 14:00   ` Borislav Petkov
2017-07-24 20:03 ` [RFC Part2 PATCH v3 23/26] KVM: X86: Add memory encryption enabled ops Brijesh Singh
2017-09-14 14:09   ` Borislav Petkov
2017-07-24 20:03 ` [RFC Part2 PATCH v3 24/26] KVM: SVM: Clear C-bit from the page fault address Brijesh Singh
2017-09-14 14:35   ` Borislav Petkov
2017-07-24 20:03 ` [RFC Part2 PATCH v3 25/26] KVM: SVM: Do not install #UD intercept when SEV is enabled Brijesh Singh
2017-09-14 14:56   ` Borislav Petkov
2017-07-24 20:03 ` [RFC Part2 PATCH v3 26/26] KVM: X86: Restart the guest when insn_len is zero and " Brijesh Singh
2017-09-14 15:40   ` Borislav Petkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170913150636.fcjhbg7wdf2whmy2@pd.tnic \
    --to=bp@suse.de \
    --cc=brijesh.singh@amd.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).