On Sun, Apr 21, 2013 at 02:12:21PM +0530, [email protected] wrote:
> From: Prasad Joshi <[email protected]>
> 
> Write only SVM_KEY can be used to create a password protected mechanism
> to clear VM_CR.LOCK.
> 
> This key can only be set when VM_CR.LOCK is unset. Once this key is set,
> a write to it compares the written value with already set key. The
> VM_CR.LOCK is unset only if the key matches. All reads from this MSR
> must return 0.
> 
> Signed-off-by: Prasad Joshi <[email protected]>
> ---
>  arch/x86/include/uapi/asm/msr-index.h |    1 +
>  arch/x86/kvm/svm.c                    |   31 +++++++++++++++++++++++++++++++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/arch/x86/include/uapi/asm/msr-index.h 
> b/arch/x86/include/uapi/asm/msr-index.h
> index 892ce40..eda8346 100644
> --- a/arch/x86/include/uapi/asm/msr-index.h
> +++ b/arch/x86/include/uapi/asm/msr-index.h
> @@ -170,6 +170,7 @@
>  
>  #define MSR_AMD64_PATCH_LEVEL                0x0000008b
>  #define MSR_AMD64_TSC_RATIO          0xc0000104
> +#define MSR_AMD64_SVM_KEY            0xc0010118
>  #define MSR_AMD64_NB_CFG             0xc001001f
>  #define MSR_AMD64_PATCH_LOADER               0xc0010020
>  #define MSR_AMD64_OSVW_ID_LENGTH     0xc0010140
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index fcdfdea..73b2dc2 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -150,6 +150,8 @@ struct vcpu_svm {
>  
>       struct nested_state nested;
>  
> +     u64 svm_key; /* Write only SVM Key */
> +
>       bool nmi_singlestep;
>  
>       unsigned int3_injected;
> @@ -3079,6 +3081,13 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned 
> ecx, u64 *data)
>       case MSR_VM_CR:
>               *data = svm->nested.vm_cr_msr;
>               break;
> +     case MSR_AMD64_SVM_KEY:
> +             /*
> +              * SVM Key is password protected mechanism to manage
> +              * VM_CR.LOCK and therefore reading it must always return 0.
> +              */
> +             *data = 0;
> +             break;
>       case MSR_IA32_UCODE_REV:
>               *data = 0x01000065;
>               break;
> @@ -3132,6 +3141,26 @@ static int svm_set_vm_cr(struct kvm_vcpu *vcpu, u64 
> data)
>       return 0;
>  }
>  
> +static int svm_set_svm_key(struct kvm_vcpu *vcpu, u64 data)
> +{
> +     struct vcpu_svm *svm = to_svm(vcpu);
> +
> +     if (!boot_cpu_has(X86_FEATURE_SVML))
> +             return 1;
> +
Since the feature is emulated why do you care if host cpu supports it?

> +     if (!(svm->nested.vm_cr_msr & SVM_VM_CR_SVM_LOCK_MASK) && data) {
> +             /* vm_cr.lock not set: set the password key */
> +             svm->svm_key = data;
> +     } else {
> +             /* vm_cr.lock is set */
> +             if (data && svm->svm_key == data) {
> +                     /* password key matched: reset the lock */
> +                     svm->nested.vm_cr_msr &= ~SVM_VM_CR_SVM_LOCK_MASK;
> +             }
> +     }
That's not enough. First of all KVM does not currently checks
SVMDIS before allowing setting of EFER_SVME. Second svm_set_vm_cr() erroneously
ignores writes into VM_CR SVMDIS/LOCK if SVMDIS is set, while it should
check LOCK. Third when write is done by a userspace during reset the
key check should be ignored.


> +     return 0;
> +}
> +
>  static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
>  {
>       struct vcpu_svm *svm = to_svm(vcpu);
> @@ -3191,6 +3220,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct 
> msr_data *msr)
>               break;
>       case MSR_VM_CR:
>               return svm_set_vm_cr(vcpu, data);
> +        case MSR_AMD64_SVM_KEY:
> +             return svm_set_svm_key(vcpu, data);
>       case MSR_VM_IGNNE:
>               vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", 
> ecx, data);
>               break;
> -- 
> 1.7.10.4

--
                        Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to