diff options
Diffstat (limited to 'arch/arm64/kvm/guest.c')
| -rw-r--r-- | arch/arm64/kvm/guest.c | 39 | 
1 files changed, 25 insertions, 14 deletions
| diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 07444fa22888..20280a5233f6 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -590,11 +590,16 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)  	return copy_core_reg_indices(vcpu, NULL);  } -/** - * ARM64 versions of the TIMER registers, always available on arm64 - */ +static const u64 timer_reg_list[] = { +	KVM_REG_ARM_TIMER_CTL, +	KVM_REG_ARM_TIMER_CNT, +	KVM_REG_ARM_TIMER_CVAL, +	KVM_REG_ARM_PTIMER_CTL, +	KVM_REG_ARM_PTIMER_CNT, +	KVM_REG_ARM_PTIMER_CVAL, +}; -#define NUM_TIMER_REGS 3 +#define NUM_TIMER_REGS ARRAY_SIZE(timer_reg_list)  static bool is_timer_reg(u64 index)  { @@ -602,6 +607,9 @@ static bool is_timer_reg(u64 index)  	case KVM_REG_ARM_TIMER_CTL:  	case KVM_REG_ARM_TIMER_CNT:  	case KVM_REG_ARM_TIMER_CVAL: +	case KVM_REG_ARM_PTIMER_CTL: +	case KVM_REG_ARM_PTIMER_CNT: +	case KVM_REG_ARM_PTIMER_CVAL:  		return true;  	}  	return false; @@ -609,14 +617,11 @@ static bool is_timer_reg(u64 index)  static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)  { -	if (put_user(KVM_REG_ARM_TIMER_CTL, uindices)) -		return -EFAULT; -	uindices++; -	if (put_user(KVM_REG_ARM_TIMER_CNT, uindices)) -		return -EFAULT; -	uindices++; -	if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices)) -		return -EFAULT; +	for (int i = 0; i < NUM_TIMER_REGS; i++) { +		if (put_user(timer_reg_list[i], uindices)) +			return -EFAULT; +		uindices++; +	}  	return 0;  } @@ -957,7 +962,9 @@ int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,  	switch (attr->group) {  	case KVM_ARM_VCPU_PMU_V3_CTRL: +		mutex_lock(&vcpu->kvm->arch.config_lock);  		ret = kvm_arm_pmu_v3_set_attr(vcpu, attr); +		mutex_unlock(&vcpu->kvm->arch.config_lock);  		break;  	case KVM_ARM_VCPU_TIMER_CTRL:  		ret = kvm_arm_timer_set_attr(vcpu, attr); @@ -1019,8 +1026,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,  	return ret;  } -long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, -				struct kvm_arm_copy_mte_tags *copy_tags) +int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, +			       struct kvm_arm_copy_mte_tags *copy_tags)  {  	gpa_t guest_ipa = copy_tags->guest_ipa;  	size_t length = copy_tags->length; @@ -1041,6 +1048,10 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,  	if (length & ~PAGE_MASK || guest_ipa & ~PAGE_MASK)  		return -EINVAL; +	/* Lengths above INT_MAX cannot be represented in the return value */ +	if (length > INT_MAX) +		return -EINVAL; +  	gfn = gpa_to_gfn(guest_ipa);  	mutex_lock(&kvm->slots_lock); | 
