| 
 | 1 | +From: Shivansh Vij < [email protected]>  | 
 | 2 | +Subject: feat: implement CPUID query  | 
 | 3 | +---  | 
 | 4 | +diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c  | 
 | 5 | +index 2bc9a7b07..b9caace4f 100644  | 
 | 6 | +--- a/arch/x86/kvm/pvm/pvm.c  | 
 | 7 | ++++ b/arch/x86/kvm/pvm/pvm.c  | 
 | 8 | +@@ -2193,6 +2193,19 @@ static int handle_exit_breakpoint(struct kvm_vcpu *vcpu)  | 
 | 9 | + 	return 1;  | 
 | 10 | + }  | 
 | 11 | +   | 
 | 12 | ++static void handle_cpuid(struct kvm_vcpu *vcpu)  | 
 | 13 | ++{  | 
 | 14 | ++	u32 eax, ebx, ecx, edx;  | 
 | 15 | ++  | 
 | 16 | ++	eax = kvm_rax_read(vcpu);  | 
 | 17 | ++	ecx = kvm_rcx_read(vcpu);  | 
 | 18 | ++	kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, false);  | 
 | 19 | ++	kvm_rax_write(vcpu, eax);  | 
 | 20 | ++	kvm_rbx_write(vcpu, ebx);  | 
 | 21 | ++	kvm_rcx_write(vcpu, ecx);  | 
 | 22 | ++	kvm_rdx_write(vcpu, edx);  | 
 | 23 | ++}  | 
 | 24 | ++  | 
 | 25 | + static bool handle_synthetic_instruction_pvm_cpuid(struct kvm_vcpu *vcpu)  | 
 | 26 | + {  | 
 | 27 | + 	/* invlpg 0xffffffffff4d5650; cpuid; */  | 
 | 28 | +@@ -2203,19 +2216,10 @@ static bool handle_synthetic_instruction_pvm_cpuid(struct kvm_vcpu *vcpu)  | 
 | 29 | + 	if (kvm_read_guest_virt(vcpu, kvm_get_linear_rip(vcpu),  | 
 | 30 | + 				insns, sizeof(insns), &e) == 0 &&  | 
 | 31 | + 	    memcmp(insns, pvm_synthetic_cpuid_insns, sizeof(insns)) == 0) {  | 
 | 32 | +-		u32 eax, ebx, ecx, edx;  | 
 | 33 | +-  | 
 | 34 | + 		if (unlikely(pvm_guest_allowed_va(vcpu, PVM_SYNTHETIC_CPUID_ADDRESS)))  | 
 | 35 | + 			kvm_mmu_invlpg(vcpu, PVM_SYNTHETIC_CPUID_ADDRESS);  | 
 | 36 | +   | 
 | 37 | +-		eax = kvm_rax_read(vcpu);  | 
 | 38 | +-		ecx = kvm_rcx_read(vcpu);  | 
 | 39 | +-		kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, false);  | 
 | 40 | +-		kvm_rax_write(vcpu, eax);  | 
 | 41 | +-		kvm_rbx_write(vcpu, ebx);  | 
 | 42 | +-		kvm_rcx_write(vcpu, ecx);  | 
 | 43 | +-		kvm_rdx_write(vcpu, edx);  | 
 | 44 | +-  | 
 | 45 | ++		handle_cpuid(vcpu);  | 
 | 46 | + 		kvm_rip_write(vcpu, kvm_rip_read(vcpu) + sizeof(insns));  | 
 | 47 | + 		return true;  | 
 | 48 | + 	}  | 
 | 49 | +@@ -2223,6 +2227,28 @@ static bool handle_synthetic_instruction_pvm_cpuid(struct kvm_vcpu *vcpu)  | 
 | 50 | + 	return false;  | 
 | 51 | + }  | 
 | 52 | +   | 
 | 53 | ++/*  | 
 | 54 | ++ * Handle the guest initiated #VE.  | 
 | 55 | ++ *  | 
 | 56 | ++ * Only EXIT_REASON_CPUID is allowed for now, see virt_exception_user()  | 
 | 57 | ++ * in arch/x86/coco/tdx/tdx.c.  | 
 | 58 | ++ */  | 
 | 59 | ++static void handle_exit_virtual_exception(struct kvm_vcpu *vcpu)  | 
 | 60 | ++{  | 
 | 61 | ++	struct vcpu_pvm *pvm = to_pvm(vcpu);  | 
 | 62 | ++  | 
 | 63 | ++	switch (pvm->exit_ve.exit_reason) {  | 
 | 64 | ++	case EXIT_REASON_CPUID:  | 
 | 65 | ++		handle_cpuid(vcpu);  | 
 | 66 | ++		kvm_rip_write(vcpu, kvm_rip_read(vcpu) + pvm->exit_ve.instr_len);  | 
 | 67 | ++		break;  | 
 | 68 | ++	default:  | 
 | 69 | ++		pr_warn("Unexpected #VE: %lld\n", pvm->exit_ve.exit_reason);  | 
 | 70 | ++		kvm_queue_exception_e(vcpu, GP_VECTOR, 0);  | 
 | 71 | ++		break;  | 
 | 72 | ++	}  | 
 | 73 | ++}  | 
 | 74 | ++  | 
 | 75 | + static int handle_exit_exception(struct kvm_vcpu *vcpu)  | 
 | 76 | + {  | 
 | 77 | + 	struct vcpu_pvm *pvm = to_pvm(vcpu);  | 
 | 78 | +@@ -2296,8 +2322,8 @@ static int handle_exit_exception(struct kvm_vcpu *vcpu)  | 
 | 79 | + 		// NMI is handled by pvm_vcpu_run_noinstr().  | 
 | 80 | + 		return 1;  | 
 | 81 | + 	case VE_VECTOR:  | 
 | 82 | +-		// TODO: tdx_handle_virt_exception(regs, &pvm->exit_ve); break;  | 
 | 83 | +-		goto unknown_exit_reason;  | 
 | 84 | ++		handle_exit_virtual_exception(vcpu);  | 
 | 85 | ++		return 1;  | 
 | 86 | + 	case X86_TRAP_VC:  | 
 | 87 | + 		// TODO: handle the second part for #VC.  | 
 | 88 | + 		goto unknown_exit_reason;  | 
0 commit comments