target/i386: Refactored intercept checks into cpu_svm_has_intercept

Added cpu_svm_has_intercept to reduce duplication when checking the
corresponding intercept bit outside of cpu_svm_check_intercept_param

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-2-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Lara Lazier 2021-06-16 14:39:04 +02:00 committed by Paolo Bonzini
parent f8bb7e1c25
commit 813c6459ee
2 changed files with 76 additions and 61 deletions

View File

@ -2149,9 +2149,13 @@ static inline void
cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
uint64_t param, uintptr_t retaddr) uint64_t param, uintptr_t retaddr)
{ /* no-op */ } { /* no-op */ }
static inline bool
cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
{ return false; }
#else #else
void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
uint64_t param, uintptr_t retaddr); uint64_t param, uintptr_t retaddr);
bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type);
#endif #endif
/* apic.c */ /* apic.c */

View File

@ -412,6 +412,43 @@ void helper_clgi(CPUX86State *env)
env->hflags2 &= ~HF2_GIF_MASK; env->hflags2 &= ~HF2_GIF_MASK;
} }
bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
{
switch (type) {
case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
return true;
}
break;
case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
return true;
}
break;
case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
return true;
}
break;
case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
return true;
}
break;
case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
return true;
}
break;
default:
if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
return true;
}
break;
}
return false;
}
void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
uint64_t param, uintptr_t retaddr) uint64_t param, uintptr_t retaddr)
{ {
@ -420,72 +457,46 @@ void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
if (likely(!(env->hflags & HF_GUEST_MASK))) { if (likely(!(env->hflags & HF_GUEST_MASK))) {
return; return;
} }
switch (type) {
case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
cpu_vmexit(env, type, param, retaddr);
}
break;
case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
cpu_vmexit(env, type, param, retaddr);
}
break;
case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
cpu_vmexit(env, type, param, retaddr);
}
break;
case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
cpu_vmexit(env, type, param, retaddr);
}
break;
case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
cpu_vmexit(env, type, param, retaddr);
}
break;
case SVM_EXIT_MSR:
if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
/* FIXME: this should be read in at vmrun (faster this way?) */
uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
offsetof(struct vmcb,
control.msrpm_base_pa));
uint32_t t0, t1;
switch ((uint32_t)env->regs[R_ECX]) { if (!cpu_svm_has_intercept(env, type)) {
case 0 ... 0x1fff: return;
t0 = (env->regs[R_ECX] * 2) % 8; }
t1 = (env->regs[R_ECX] * 2) / 8;
break; if (type == SVM_EXIT_MSR) {
case 0xc0000000 ... 0xc0001fff: /* FIXME: this should be read in at vmrun (faster this way?) */
t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2; uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
t1 = (t0 / 8); offsetof(struct vmcb,
t0 %= 8; control.msrpm_base_pa));
break; uint32_t t0, t1;
case 0xc0010000 ... 0xc0011fff:
t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2; switch ((uint32_t)env->regs[R_ECX]) {
t1 = (t0 / 8); case 0 ... 0x1fff:
t0 %= 8; t0 = (env->regs[R_ECX] * 2) % 8;
break; t1 = (env->regs[R_ECX] * 2) / 8;
default: break;
cpu_vmexit(env, type, param, retaddr); case 0xc0000000 ... 0xc0001fff:
t0 = 0; t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
t1 = 0; t1 = (t0 / 8);
break; t0 %= 8;
} break;
if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) { case 0xc0010000 ... 0xc0011fff:
cpu_vmexit(env, type, param, retaddr); t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
} t1 = (t0 / 8);
t0 %= 8;
break;
default:
cpu_vmexit(env, type, param, retaddr);
t0 = 0;
t1 = 0;
break;
} }
break; if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
default:
if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
cpu_vmexit(env, type, param, retaddr); cpu_vmexit(env, type, param, retaddr);
} }
break; return;
} }
cpu_vmexit(env, type, param, retaddr);
} }
void helper_svm_check_intercept(CPUX86State *env, uint32_t type) void helper_svm_check_intercept(CPUX86State *env, uint32_t type)