KVM: x86: Hypercall handling does not considers opsize correctly
Currently, the hypercall handling routine only considers LME as an indication to whether the guest uses 32/64-bit mode. This is incosistent with hyperv hypercalls handling and against the common sense of considering cs.l as well. This patch uses is_64_bit_mode instead of is_long_mode for that matter. In addition, the result is masked in respect to the guest execution mode. Last, it changes kvm_hv_hypercall to use is_64_bit_mode as well to simplify the code. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
5777392e83
Коммит
a449c7aa51
|
@ -5669,7 +5669,6 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
|
|||
u64 param, ingpa, outgpa, ret;
|
||||
uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
|
||||
bool fast, longmode;
|
||||
int cs_db, cs_l;
|
||||
|
||||
/*
|
||||
* hypercall generates UD from non zero cpl and real mode
|
||||
|
@ -5680,8 +5679,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
|
||||
longmode = is_long_mode(vcpu) && cs_l == 1;
|
||||
longmode = is_64_bit_mode(vcpu);
|
||||
|
||||
if (!longmode) {
|
||||
param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
|
||||
|
@ -5746,7 +5744,7 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
|
|||
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long nr, a0, a1, a2, a3, ret;
|
||||
int r = 1;
|
||||
int op_64_bit, r = 1;
|
||||
|
||||
if (kvm_hv_hypercall_enabled(vcpu->kvm))
|
||||
return kvm_hv_hypercall(vcpu);
|
||||
|
@ -5759,7 +5757,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
|
|||
|
||||
trace_kvm_hypercall(nr, a0, a1, a2, a3);
|
||||
|
||||
if (!is_long_mode(vcpu)) {
|
||||
op_64_bit = is_64_bit_mode(vcpu);
|
||||
if (!op_64_bit) {
|
||||
nr &= 0xFFFFFFFF;
|
||||
a0 &= 0xFFFFFFFF;
|
||||
a1 &= 0xFFFFFFFF;
|
||||
|
@ -5785,6 +5784,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
|
|||
break;
|
||||
}
|
||||
out:
|
||||
if (!op_64_bit)
|
||||
ret = (u32)ret;
|
||||
kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
|
||||
++vcpu->stat.hypercalls;
|
||||
return r;
|
||||
|
|
Загрузка…
Ссылка в новой задаче