|
@@ -1678,20 +1678,25 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
|
|
|
params.regval |= vcpu_get_reg(vcpu, Rt2) << 32;
|
|
|
}
|
|
|
|
|
|
- if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific))
|
|
|
- goto out;
|
|
|
- if (!emulate_cp(vcpu, ¶ms, global, nr_global))
|
|
|
- goto out;
|
|
|
-
|
|
|
- unhandled_cp_access(vcpu, ¶ms);
|
|
|
+ /*
|
|
|
+ * Try to emulate the coprocessor access using the target
|
|
|
+ * specific table first, and using the global table afterwards.
|
|
|
+ * If either of the tables contains a handler, handle the
|
|
|
+ * potential register operation in the case of a read and return
|
|
|
+ * with success.
|
|
|
+ */
|
|
|
+ if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific) ||
|
|
|
+ !emulate_cp(vcpu, ¶ms, global, nr_global)) {
|
|
|
+ /* Split up the value between registers for the read side */
|
|
|
+ if (!params.is_write) {
|
|
|
+ vcpu_set_reg(vcpu, Rt, lower_32_bits(params.regval));
|
|
|
+ vcpu_set_reg(vcpu, Rt2, upper_32_bits(params.regval));
|
|
|
+ }
|
|
|
|
|
|
-out:
|
|
|
- /* Split up the value between registers for the read side */
|
|
|
- if (!params.is_write) {
|
|
|
- vcpu_set_reg(vcpu, Rt, lower_32_bits(params.regval));
|
|
|
- vcpu_set_reg(vcpu, Rt2, upper_32_bits(params.regval));
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
+ unhandled_cp_access(vcpu, ¶ms);
|
|
|
return 1;
|
|
|
}
|
|
|
|