In many places of x86 HVM code, constants integer are used to indicate in what mode is
running the CPU (real, vm86, 16-bits, 32-bits, 64-bits). However, these constants are
are written directly as integer which hides the actual meaning of these modes.
This patch introduces X86_MODE_* macros and replace those occurences with it.
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
switch ( mode )
{
- case 8:
+ case X86_MODE_64BIT:
fpu_ctxt->fip.addr = aux->ip;
if ( dval )
fpu_ctxt->fdp.addr = aux->dp;
fpu_ctxt->x[FPU_WORD_SIZE_OFFSET] = 8;
break;
- case 4: case 2:
+ case X86_MODE_32BIT:
+ case X86_MODE_16BIT:
fpu_ctxt->fip.offs = aux->ip;
fpu_ctxt->fip.sel = aux->cs;
if ( dval )
fpu_ctxt->x[FPU_WORD_SIZE_OFFSET] = mode;
break;
- case 0: case 1:
+ case X86_MODE_REAL:
+ case X86_MODE_VM86:
fpu_ctxt->fip.addr = aux->ip | (aux->cs << 4);
if ( dval )
fpu_ctxt->fdp.addr = aux->dp | (aux->ds << 4);
{
switch ( mode )
{
- case 0: return "Real";
- case 1: return "v86";
- case 2: return "16bit";
- case 4: return "32bit";
- case 8: return "64bit";
+ case X86_MODE_REAL: return "Real";
+ case X86_MODE_VM86: return "vm86";
+ case X86_MODE_16BIT: return "16bit";
+ case X86_MODE_32BIT: return "32bit";
+ case X86_MODE_64BIT: return "64bit";
default: return "Unknown";
}
}
*/
if ( current->domain == d )
{
- d->arch.has_32bit_shinfo = (hvm_guest_x86_mode(current) != 8);
+ d->arch.has_32bit_shinfo =
+ hvm_guest_x86_mode(current) != X86_MODE_64BIT;
+
/*
* Make sure that the timebase in the shared info structure is correct.
*
switch ( mode )
{
- case 8:
+ case X86_MODE_64BIT:
eax = regs->rax;
fallthrough;
- case 4:
- case 2:
+ case X86_MODE_32BIT:
+ case X86_MODE_16BIT:
if ( currd->arch.monitor.guest_request_userspace_enabled &&
- eax == __HYPERVISOR_hvm_op &&
- (mode == 8 ? regs->rdi : regs->ebx) == HVMOP_guest_request_vm_event )
+ eax == __HYPERVISOR_hvm_op &&
+ (mode == X86_MODE_64BIT ? regs->rdi : regs->ebx) ==
+ HVMOP_guest_request_vm_event )
break;
if ( likely(!hvm_get_cpl(curr)) )
break;
fallthrough;
- default:
+ case X86_MODE_VM86:
regs->rax = -EPERM;
return HVM_HCALL_completed;
- case 0:
+ case X86_MODE_REAL:
break;
}
{
struct vcpu *curr = current;
- if ( hvm_guest_x86_mode(curr) == 8 )
+ if ( hvm_guest_x86_mode(curr) == X86_MODE_64BIT )
{
struct multicall_entry *call = &state->call;
struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
if ( unlikely(!(v->arch.hvm.guest_cr[0] & X86_CR0_PE)) )
- return 0;
+ return X86_MODE_REAL;
if ( unlikely(guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) )
- return 1;
+ return X86_MODE_VM86;
if ( hvm_long_mode_active(v) && likely(vmcb->cs.l) )
- return 8;
- return likely(vmcb->cs.db) ? 4 : 2;
+ return X86_MODE_64BIT;
+ return vmcb->cs.db ? X86_MODE_32BIT : X86_MODE_16BIT;
}
static void cf_check svm_cpuid_policy_changed(struct vcpu *v)
switch ( mode )
{
- case 8:
+ case X86_MODE_64BIT:
input.raw = regs->rcx;
input_params_gpa = regs->rdx;
output_params_gpa = regs->r8;
break;
- case 4:
+ case X86_MODE_32BIT:
input.raw = (regs->rdx << 32) | regs->eax;
input_params_gpa = (regs->rbx << 32) | regs->ecx;
output_params_gpa = (regs->rdi << 32) | regs->esi;
switch ( mode )
{
- case 8:
+ case X86_MODE_64BIT:
regs->rax = output.raw;
break;
- case 4:
+ case X86_MODE_32BIT:
regs->rdx = output.raw >> 32;
regs->rax = (uint32_t)output.raw;
break;
unsigned long cs_ar_bytes;
if ( unlikely(!(v->arch.hvm.guest_cr[0] & X86_CR0_PE)) )
- return 0;
+ return X86_MODE_REAL;
if ( unlikely(guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) )
- return 1;
+ return X86_MODE_VM86;
__vmread(GUEST_CS_AR_BYTES, &cs_ar_bytes);
if ( hvm_long_mode_active(v) &&
likely(cs_ar_bytes & X86_SEG_AR_CS_LM_ACTIVE) )
- return 8;
- return (likely(cs_ar_bytes & X86_SEG_AR_DEF_OP_SIZE) ? 4 : 2);
+ return X86_MODE_64BIT;
+ return (likely(cs_ar_bytes & X86_SEG_AR_DEF_OP_SIZE)
+ ? X86_MODE_32BIT : X86_MODE_16BIT);
}
static void vmx_save_dr(struct vcpu *v)
}
else
{
- bool mode_64bit = (vmx_guest_x86_mode(v) == 8);
+ bool mode_64bit = vmx_guest_x86_mode(v) == X86_MODE_64BIT;
decode->type = VMX_INST_MEMREG_TYPE_MEMORY;
if ( !(curr->arch.hvm.guest_cr[4] & X86_CR4_VMXE) ||
!nestedhvm_enabled(curr->domain) ||
- (vmx_guest_x86_mode(curr) < (hvm_long_mode_active(curr) ? 8 : 2)) ||
+ (vmx_guest_x86_mode(curr) <
+ (hvm_long_mode_active(curr) ? X86_MODE_64BIT : X86_MODE_16BIT)) ||
(exit_reason != EXIT_REASON_VMXON && !nvmx_vcpu_in_vmx(curr)) )
{
hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC);
#define opt_hvm_fep 0
#endif
+/*
+ * Results for hvm_guest_x86_mode().
+ *
+ * Note, some callers depend on the order of these constants.
+ *
+ * TODO: Rework hvm_guest_x86_mode() to avoid mixing the architectural
+ * concepts of mode and operand size.
+ */
+#define X86_MODE_REAL 0
+#define X86_MODE_VM86 1
+#define X86_MODE_16BIT 2
+#define X86_MODE_32BIT 4
+#define X86_MODE_64BIT 8
+
/* Interrupt acknowledgement sources. */
enum hvm_intsrc {
hvm_intsrc_none,
switch ( hvm_guest_x86_mode(curr) )
{
- case 0: /* real mode */
+ case X86_MODE_REAL:
return 1;
- case 1: /* vm86 mode */
+ case X86_MODE_VM86:
return 0;
- default:
+ default: /* 16BIT | 32BIT | 64BIT */
return hvm_get_cpl(curr) != 3;
}
}