mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	KVM: SVM: install RSM intercept
RSM instruction is used by the SMM handler to return from SMM mode. Currently, rsm causes a #UD - which results in instruction fetch, decode, and emulate. By installing the RSM intercept we can avoid the instruction fetch since we know that #VMEXIT was due to rsm. The patch is required for the SEV guest, because in case of SEV guest memory is encrypted with guest-specific key and hypervisor will not able to fetch the instruction bytes from the guest memory. Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Borislav Petkov <bp@suse.de> Cc: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									3e233385ef
								
							
						
					
					
						commit
						7607b71744
					
				
					 1 changed files with 10 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -300,6 +300,8 @@ module_param(vgif, int, 0444);
 | 
			
		|||
static int sev = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT);
 | 
			
		||||
module_param(sev, int, 0444);
 | 
			
		||||
 | 
			
		||||
static u8 rsm_ins_bytes[] = "\x0f\xaa";
 | 
			
		||||
 | 
			
		||||
static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
 | 
			
		||||
static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 | 
			
		||||
static void svm_complete_interrupts(struct vcpu_svm *svm);
 | 
			
		||||
| 
						 | 
				
			
			@ -1383,6 +1385,7 @@ static void init_vmcb(struct vcpu_svm *svm)
 | 
			
		|||
	set_intercept(svm, INTERCEPT_SKINIT);
 | 
			
		||||
	set_intercept(svm, INTERCEPT_WBINVD);
 | 
			
		||||
	set_intercept(svm, INTERCEPT_XSETBV);
 | 
			
		||||
	set_intercept(svm, INTERCEPT_RSM);
 | 
			
		||||
 | 
			
		||||
	if (!kvm_mwait_in_guest()) {
 | 
			
		||||
		set_intercept(svm, INTERCEPT_MONITOR);
 | 
			
		||||
| 
						 | 
				
			
			@ -3699,6 +3702,12 @@ static int emulate_on_interception(struct vcpu_svm *svm)
 | 
			
		|||
	return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int rsm_interception(struct vcpu_svm *svm)
 | 
			
		||||
{
 | 
			
		||||
	return x86_emulate_instruction(&svm->vcpu, 0, 0,
 | 
			
		||||
				       rsm_ins_bytes, 2) == EMULATE_DONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int rdpmc_interception(struct vcpu_svm *svm)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
| 
						 | 
				
			
			@ -4541,7 +4550,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
 | 
			
		|||
	[SVM_EXIT_MWAIT]			= mwait_interception,
 | 
			
		||||
	[SVM_EXIT_XSETBV]			= xsetbv_interception,
 | 
			
		||||
	[SVM_EXIT_NPF]				= npf_interception,
 | 
			
		||||
	[SVM_EXIT_RSM]                          = emulate_on_interception,
 | 
			
		||||
	[SVM_EXIT_RSM]                          = rsm_interception,
 | 
			
		||||
	[SVM_EXIT_AVIC_INCOMPLETE_IPI]		= avic_incomplete_ipi_interception,
 | 
			
		||||
	[SVM_EXIT_AVIC_UNACCELERATED_ACCESS]	= avic_unaccelerated_access_interception,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue