@@ -487,7 +487,7 @@ Capability: basic (vcpu), KVM_CAP_GET_MSR_FEATURES (system)
Architectures: x86
Type: system ioctl, vcpu ioctl
Parameters: struct kvm_msrs (in/out)
-Returns: number of msrs successfully returned;
+Returns: number of msrs successfully read;
-1 on error
When used as a system ioctl:
@@ -500,9 +500,12 @@ When used as a vcpu ioctl:
Reads model-specific registers from the vcpu. Supported msr indices can
be obtained using KVM_GET_MSR_INDEX_LIST in a system ioctl.
+If return value is non-negative and < kvm_msrs.nmsrs, then kvm_msrs.errno
+contains a (positive) value from errno.h for first MSR access that failed.
+
struct kvm_msrs {
__u32 nmsrs; /* number of msrs in entries */
- __u32 pad;
+ __u32 errno; /* error from 1st failed MSR access */
struct kvm_msr_entry entries[0];
};
@@ -524,7 +527,8 @@ Capability: basic
Architectures: x86
Type: vcpu ioctl
Parameters: struct kvm_msrs (in)
-Returns: 0 on success, -1 on error
+Returns: number of msrs successfully written;
+ -1 on error
Writes model-specific registers to the vcpu. See KVM_GET_MSRS for the
data structures.
@@ -533,6 +537,8 @@ Application code should set the 'nmsrs' member (which indicates the
size of the entries array), and the 'index' and 'data' members of each
array entry.
+If return value is non-negative and < kvm_msrs.nmsrs, then kvm_msrs.errno
+contains a (positive) value from errno.h for first MSR access that failed.
4.20 KVM_SET_CPUID
@@ -181,7 +181,7 @@ struct kvm_msr_entry {
/* for KVM_GET_MSRS and KVM_SET_MSRS */
struct kvm_msrs {
__u32 nmsrs; /* number of msrs in entries */
- __u32 pad;
+ __u32 errno; /* error from 1st failed MSR access */
struct kvm_msr_entry entries[0];
};
@@ -2209,10 +2209,10 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
*/
if ((offset & 0x3) == 0 &&
data != 0 && (data | (1 << 10)) != ~(u64)0)
- return -1;
+ return 1;
if (!msr_info->host_initiated &&
(offset & 0x3) == 1 && data != 0)
- return -1;
+ return 1;
vcpu->arch.mce_banks[offset] = data;
break;
}
@@ -2807,18 +2807,23 @@ EXPORT_SYMBOL_GPL(kvm_get_msr_common);
/*
* Read or write a bunch of msrs. All parameters are kernel addresses.
*
- * @return number of msrs set successfully.
+ * @return number of msrs accessed successfully.
*/
static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
struct kvm_msr_entry *entries,
int (*do_msr)(struct kvm_vcpu *vcpu,
unsigned index, u64 *data))
{
- int i;
+ int i, r;
- for (i = 0; i < msrs->nmsrs; ++i)
- if (do_msr(vcpu, entries[i].index, &entries[i].data))
+ for (i = 0; i < msrs->nmsrs; ++i) {
+ r = do_msr(vcpu, entries[i].index, &entries[i].data);
+ if (r) {
+ /* Convert non-standard returns to generic error */
+ msrs->errno = r > 0 ? EINVAL : -r;
break;
+ }
+ }
return i;
}
@@ -2853,11 +2858,14 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
goto out;
}
- r = n = __msr_io(vcpu, &msrs, entries, do_msr);
- if (r < 0)
- goto out_free;
+ msrs.errno = 0;
+ n = __msr_io(vcpu, &msrs, entries, do_msr);
r = -EFAULT;
+ if (copy_to_user(&user_msrs->errno, &msrs.errno,
+ sizeof user_msrs->errno))
+ goto out_free;
+
if (writeback && copy_to_user(user_msrs->entries, entries, size))
goto out_free;