|
@@ -1571,6 +1571,22 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void perform_access(struct kvm_vcpu *vcpu,
|
|
|
|
+ struct sys_reg_params *params,
|
|
|
|
+ const struct sys_reg_desc *r)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * Not having an accessor means that we have configured a trap
|
|
|
|
+ * that we don't know how to handle. This certainly qualifies
|
|
|
|
+ * as a gross bug that should be fixed right away.
|
|
|
|
+ */
|
|
|
|
+ BUG_ON(!r->access);
|
|
|
|
+
|
|
|
|
+ /* Skip instruction if instructed so */
|
|
|
|
+ if (likely(r->access(vcpu, params, r)))
|
|
|
|
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* emulate_cp -- tries to match a sys_reg access in a handling table, and
|
|
* emulate_cp -- tries to match a sys_reg access in a handling table, and
|
|
* call the corresponding trap handler.
|
|
* call the corresponding trap handler.
|
|
@@ -1594,20 +1610,8 @@ static int emulate_cp(struct kvm_vcpu *vcpu,
|
|
r = find_reg(params, table, num);
|
|
r = find_reg(params, table, num);
|
|
|
|
|
|
if (r) {
|
|
if (r) {
|
|
- /*
|
|
|
|
- * Not having an accessor means that we have
|
|
|
|
- * configured a trap that we don't know how to
|
|
|
|
- * handle. This certainly qualifies as a gross bug
|
|
|
|
- * that should be fixed right away.
|
|
|
|
- */
|
|
|
|
- BUG_ON(!r->access);
|
|
|
|
-
|
|
|
|
- if (likely(r->access(vcpu, params, r))) {
|
|
|
|
- /* Skip instruction, since it was emulated */
|
|
|
|
- kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
|
|
|
- /* Handled */
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ perform_access(vcpu, params, r);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* Not handled */
|
|
/* Not handled */
|
|
@@ -1777,26 +1781,13 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
|
|
r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
|
|
r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
|
|
|
|
|
|
if (likely(r)) {
|
|
if (likely(r)) {
|
|
- /*
|
|
|
|
- * Not having an accessor means that we have
|
|
|
|
- * configured a trap that we don't know how to
|
|
|
|
- * handle. This certainly qualifies as a gross bug
|
|
|
|
- * that should be fixed right away.
|
|
|
|
- */
|
|
|
|
- BUG_ON(!r->access);
|
|
|
|
-
|
|
|
|
- if (likely(r->access(vcpu, params, r))) {
|
|
|
|
- /* Skip instruction, since it was emulated */
|
|
|
|
- kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
- /* If access function fails, it should complain. */
|
|
|
|
|
|
+ perform_access(vcpu, params, r);
|
|
} else {
|
|
} else {
|
|
kvm_err("Unsupported guest sys_reg access at: %lx\n",
|
|
kvm_err("Unsupported guest sys_reg access at: %lx\n",
|
|
*vcpu_pc(vcpu));
|
|
*vcpu_pc(vcpu));
|
|
print_sys_reg_instr(params);
|
|
print_sys_reg_instr(params);
|
|
|
|
+ kvm_inject_undefined(vcpu);
|
|
}
|
|
}
|
|
- kvm_inject_undefined(vcpu);
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|