mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
KVM: x86: hyperv: do rep check for each hypercall separately
Prepare to support TLB flush hypercalls, some of which are REP hypercalls. Also, return HV_STATUS_INVALID_HYPERCALL_INPUT as it seems more appropriate. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
This commit is contained in:
parent
142c95da92
commit
56b9ae7830
@ -1311,7 +1311,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 param, ingpa, outgpa, ret = HV_STATUS_SUCCESS;
|
||||
uint16_t code, rep_idx, rep_cnt;
|
||||
bool fast, longmode;
|
||||
bool fast, longmode, rep;
|
||||
|
||||
/*
|
||||
* hypercall generates UD from non zero cpl and real mode
|
||||
@ -1344,28 +1344,31 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
|
||||
fast = !!(param & HV_HYPERCALL_FAST_BIT);
|
||||
rep_cnt = (param >> HV_HYPERCALL_REP_COMP_OFFSET) & 0xfff;
|
||||
rep_idx = (param >> HV_HYPERCALL_REP_START_OFFSET) & 0xfff;
|
||||
rep = !!(rep_cnt || rep_idx);
|
||||
|
||||
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
|
||||
|
||||
/* Hypercall continuation is not supported yet */
|
||||
if (rep_cnt || rep_idx) {
|
||||
ret = HV_STATUS_INVALID_HYPERCALL_CODE;
|
||||
goto set_result;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case HVCALL_NOTIFY_LONG_SPIN_WAIT:
|
||||
if (unlikely(rep)) {
|
||||
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
break;
|
||||
}
|
||||
kvm_vcpu_on_spin(vcpu, true);
|
||||
break;
|
||||
case HVCALL_SIGNAL_EVENT:
|
||||
if (unlikely(rep)) {
|
||||
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
break;
|
||||
}
|
||||
ret = kvm_hvcall_signal_event(vcpu, fast, ingpa);
|
||||
if (ret != HV_STATUS_INVALID_PORT_ID)
|
||||
break;
|
||||
/* maybe userspace knows this conn_id: fall through */
|
||||
case HVCALL_POST_MESSAGE:
|
||||
/* don't bother userspace if it has no way to handle it */
|
||||
if (!vcpu_to_synic(vcpu)->active) {
|
||||
ret = HV_STATUS_INVALID_HYPERCALL_CODE;
|
||||
if (unlikely(rep || !vcpu_to_synic(vcpu)->active)) {
|
||||
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
break;
|
||||
}
|
||||
vcpu->run->exit_reason = KVM_EXIT_HYPERV;
|
||||
|
Loading…
Reference in New Issue
Block a user