diff options
| author | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
| commit | 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e (patch) | |
| tree | d57f3a63479a07b4e0cece029886e76e04feb984 /arch/x86/kvm/hyperv.c | |
| parent | 5dc63e56a9cf8df0b59c234a505a1653f1bdf885 (diff) | |
| parent | 53bea86b5712c7491bb3dae12e271666df0a308c (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.4 merge window.
Diffstat (limited to 'arch/x86/kvm/hyperv.c')
| -rw-r--r-- | arch/x86/kvm/hyperv.c | 85 | 
1 files changed, 63 insertions, 22 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index e8296942a868..b28fd020066f 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -17,6 +17,7 @@   *   Ben-Ami Yassour <[email protected]>   *   Andrey Smetanin <[email protected]>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt  #include "x86.h"  #include "lapic.h" @@ -43,6 +44,24 @@  #define KVM_HV_MAX_SPARSE_VCPU_SET_BITS DIV_ROUND_UP(KVM_MAX_VCPUS, HV_VCPUS_PER_SPARSE_BANK) +/* + * As per Hyper-V TLFS, extended hypercalls start from 0x8001 + * (HvExtCallQueryCapabilities). Response of this hypercalls is a 64 bit value + * where each bit tells which extended hypercall is available besides + * HvExtCallQueryCapabilities. + * + * 0x8001 - First extended hypercall, HvExtCallQueryCapabilities, no bit + * assigned. + * + * 0x8002 - Bit 0 + * 0x8003 - Bit 1 + * .. + * 0x8041 - Bit 63 + * + * Therefore, HV_EXT_CALL_MAX = 0x8001 + 64 + */ +#define HV_EXT_CALL_MAX (HV_EXT_CALL_QUERY_CAPABILITIES + 64) +  static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,  				bool vcpu_kick); @@ -999,6 +1018,7 @@ static bool kvm_hv_msr_partition_wide(u32 msr)  	case HV_X64_MSR_REENLIGHTENMENT_CONTROL:  	case HV_X64_MSR_TSC_EMULATION_CONTROL:  	case HV_X64_MSR_TSC_EMULATION_STATUS: +	case HV_X64_MSR_TSC_INVARIANT_CONTROL:  	case HV_X64_MSR_SYNDBG_OPTIONS:  	case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER:  		r = true; @@ -1283,6 +1303,9 @@ static bool hv_check_msr_access(struct kvm_vcpu_hv *hv_vcpu, u32 msr)  	case HV_X64_MSR_TSC_EMULATION_STATUS:  		return hv_vcpu->cpuid_cache.features_eax &  			HV_ACCESS_REENLIGHTENMENT; +	case HV_X64_MSR_TSC_INVARIANT_CONTROL: +		return hv_vcpu->cpuid_cache.features_eax & +			HV_ACCESS_TSC_INVARIANT;  	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:  	case HV_X64_MSR_CRASH_CTL:  		return hv_vcpu->cpuid_cache.features_edx & @@ -1410,12 +1433,22 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,  		if (!host)  			return 1;  		break; +	case HV_X64_MSR_TSC_INVARIANT_CONTROL: +		/* Only bit 0 is supported */ +		if (data & ~HV_EXPOSE_INVARIANT_TSC) +			return 1; + +		/* The feature can't be disabled from the guest */ +		if (!host && hv->hv_invtsc_control && !data) +			return 1; + +		hv->hv_invtsc_control = data; +		break;  	case HV_X64_MSR_SYNDBG_OPTIONS:  	case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER:  		return syndbg_set_msr(vcpu, msr, data, host);  	default: -		vcpu_unimpl(vcpu, "Hyper-V unhandled wrmsr: 0x%x data 0x%llx\n", -			    msr, data); +		kvm_pr_unimpl_wrmsr(vcpu, msr, data);  		return 1;  	}  	return 0; @@ -1536,8 +1569,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)  			return 1;  		break;  	default: -		vcpu_unimpl(vcpu, "Hyper-V unhandled wrmsr: 0x%x data 0x%llx\n", -			    msr, data); +		kvm_pr_unimpl_wrmsr(vcpu, msr, data);  		return 1;  	} @@ -1585,11 +1617,14 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,  	case HV_X64_MSR_TSC_EMULATION_STATUS:  		data = hv->hv_tsc_emulation_status;  		break; +	case HV_X64_MSR_TSC_INVARIANT_CONTROL: +		data = hv->hv_invtsc_control; +		break;  	case HV_X64_MSR_SYNDBG_OPTIONS:  	case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER:  		return syndbg_get_msr(vcpu, msr, pdata, host);  	default: -		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); +		kvm_pr_unimpl_rdmsr(vcpu, msr);  		return 1;  	} @@ -1654,7 +1689,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,  		data = APIC_BUS_FREQUENCY;  		break;  	default: -		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); +		kvm_pr_unimpl_rdmsr(vcpu, msr);  		return 1;  	}  	*pdata = data; @@ -2420,6 +2455,9 @@ static bool hv_check_hypercall_access(struct kvm_vcpu_hv *hv_vcpu, u16 code)  	case HVCALL_SEND_IPI:  		return hv_vcpu->cpuid_cache.enlightenments_eax &  			HV_X64_CLUSTER_IPI_RECOMMENDED; +	case HV_EXT_CALL_QUERY_CAPABILITIES ... HV_EXT_CALL_MAX: +		return hv_vcpu->cpuid_cache.features_ebx & +			HV_ENABLE_EXTENDED_HYPERCALLS;  	default:  		break;  	} @@ -2512,14 +2550,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)  			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;  			break;  		} -		vcpu->run->exit_reason = KVM_EXIT_HYPERV; -		vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; -		vcpu->run->hyperv.u.hcall.input = hc.param; -		vcpu->run->hyperv.u.hcall.params[0] = hc.ingpa; -		vcpu->run->hyperv.u.hcall.params[1] = hc.outgpa; -		vcpu->arch.complete_userspace_io = -				kvm_hv_hypercall_complete_userspace; -		return 0; +		goto hypercall_userspace_exit;  	case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:  		if (unlikely(hc.var_cnt)) {  			ret = HV_STATUS_INVALID_HYPERCALL_INPUT; @@ -2578,15 +2609,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)  			ret = HV_STATUS_OPERATION_DENIED;  			break;  		} -		vcpu->run->exit_reason = KVM_EXIT_HYPERV; -		vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; -		vcpu->run->hyperv.u.hcall.input = hc.param; -		vcpu->run->hyperv.u.hcall.params[0] = hc.ingpa; -		vcpu->run->hyperv.u.hcall.params[1] = hc.outgpa; -		vcpu->arch.complete_userspace_io = -				kvm_hv_hypercall_complete_userspace; -		return 0; +		goto hypercall_userspace_exit;  	} +	case HV_EXT_CALL_QUERY_CAPABILITIES ... HV_EXT_CALL_MAX: +		if (unlikely(hc.fast)) { +			ret = HV_STATUS_INVALID_PARAMETER; +			break; +		} +		goto hypercall_userspace_exit;  	default:  		ret = HV_STATUS_INVALID_HYPERCALL_CODE;  		break; @@ -2594,6 +2624,15 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)  hypercall_complete:  	return kvm_hv_hypercall_complete(vcpu, ret); + +hypercall_userspace_exit: +	vcpu->run->exit_reason = KVM_EXIT_HYPERV; +	vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; +	vcpu->run->hyperv.u.hcall.input = hc.param; +	vcpu->run->hyperv.u.hcall.params[0] = hc.ingpa; +	vcpu->run->hyperv.u.hcall.params[1] = hc.outgpa; +	vcpu->arch.complete_userspace_io = kvm_hv_hypercall_complete_userspace; +	return 0;  }  void kvm_hv_init_vm(struct kvm *kvm) @@ -2733,9 +2772,11 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,  			ent->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE;  			ent->eax |= HV_ACCESS_FREQUENCY_MSRS;  			ent->eax |= HV_ACCESS_REENLIGHTENMENT; +			ent->eax |= HV_ACCESS_TSC_INVARIANT;  			ent->ebx |= HV_POST_MESSAGES;  			ent->ebx |= HV_SIGNAL_EVENTS; +			ent->ebx |= HV_ENABLE_EXTENDED_HYPERCALLS;  			ent->edx |= HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE;  			ent->edx |= HV_FEATURE_FREQUENCY_MSRS_AVAILABLE;  |