From nobody Fri Nov 14 19:44:01 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1761630967; cv=none; d=zohomail.com; s=zohoarc; b=KnVlQcck/N2sqns71IAws+8bc/BBAw9BuPqlzLDFxoUx4v4pBuAPQOWsUK4kvcuk/GetpcERljj5LifG3EvIxz/fMxwUb1RbZWK3zJ4iwig8XRl/vhje+5GeK/9SiCB7cYO27Qmrn+MGpSLUzLd6e5FNm59KU64GgRXueFAd31o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1761630967; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GNN09nikcz59h/+aSBzafHW4AR3HBWle7qRThHgLUuc=; b=ViBeZsi5qePj4DqVeGBxvt6vOdqEwq03484Zz9uB3/g4pRg4AjoeWi2PG7CBvDCADMwwtzN/sHZhyv+HSMPPlv84mXApD4J485k1QEbLKEclaEmHrefIiVXT87FY1rwzI6Ebyy6xcDS2Fi+z78NWh8+XwGd2fXlXzT6wIf1/T4Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1761630967415130.25031905920775; Mon, 27 Oct 2025 22:56:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vDcgM-0005Qv-GO; Tue, 28 Oct 2025 01:55:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vDcgF-0005KT-4j for qemu-devel@nongnu.org; Tue, 28 Oct 2025 01:55:42 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vDcg8-000501-Ju for qemu-devel@nongnu.org; Tue, 28 Oct 2025 01:55:38 -0400 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-3ece1102998so3933396f8f.2 for ; Mon, 27 Oct 2025 22:55:30 -0700 (PDT) Received: from localhost.localdomain (88-187-86-199.subs.proxad.net. [88.187.86.199]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-429952b7a7csm18287752f8f.8.2025.10.27.22.55.27 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 27 Oct 2025 22:55:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1761630929; x=1762235729; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GNN09nikcz59h/+aSBzafHW4AR3HBWle7qRThHgLUuc=; b=E9dKO2XnglyrQWSfW4FdUAdS6SVOvGpUeuQVONowExJ7aDI/Cl4VeCRfJeCpVJI7ik z0veohY4SZzbAX+pYOkbgS9VfclxZY7ZWgJ7TQtVInWIlnq7NMgnugwjCwrpePKK//wh YCcEw9Ca3sPTIgxC+1CBcDAeDyJYOWxC7CbwsR/sX/cGhYVSn3hcK7zm9zwCkV63rhAi X65Hb/b4ARmyPJCNJYtQ8uzW0tFAYd3Fy+DnOl1HbamrsSfFpircMjhsmpoX/IEMetBh C8MLsIg2vjiOLJnCmM1pAYFeuq6VlT8M6c6snAPGOEXBgLVgHeCRaMeo47nXPIfpZoSH FINQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761630929; x=1762235729; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GNN09nikcz59h/+aSBzafHW4AR3HBWle7qRThHgLUuc=; b=WzgG/EFy10a1GQXG2KXMWc/DlPqhw+WmmoOpjpWUxoMGk4/PNEL//LlNULD0HWCIYU MUO+k+ubheSQMv/tUP0uYO1cLLWtWNcPvUwLDeG3XQynk6WZpCLwP36uv7wc2h77a98q tT4YpgB/dzWcVAgP61cuM58oiXgLueb28cJEnb+YRLrmR0ifEIv31EgOrlvpXdk+sDNq 3GYQOfk5dPCUl5Dg6oRF/wc9PvM3dyvWCKJVIIghFqc0rFUPHVX3hNqIP8NR2cmGj++A +kf2kWqCo/bRwKqtSUtrBASYN9L+3AYbfFtWukDzvMokjattEJtmrTJhxcH6qneseo3E SLPA== X-Gm-Message-State: AOJu0Ywj+1zhTCaF2lRKyH9wG2z+zgku7A2V5jrsRP2SBOrB5cb1hqHw rAga9GCpRRRs5u0agGzZOEZegHbmmNcSwhoVFhZuYautmI7Q1ohdM0SWnxOmW34eWR/zfeICRHq mZvL8jgM= X-Gm-Gg: ASbGnctEcBo92FzotQCddhWoPyspVrhO2kcYe6XQYWAdTSA0MDo434imrhfCPXXjMWo MqVKmUMEcJOcoJUiVUOG151rsPPTrIQN8bX3R7+gTIOqLMlwJ8eRZ06WZ9xljVeclNQfP56fjdN qw1QUJknK4dkA1YT5csyIb34lMwM6LPtLvskulA3G5MU2Kd7ngpEBI33URHlgKUFLtirAR8FpSc geTNnKo2sguJgJu7ypXwOTvSaMTuevHpUuvsphT1+Ju4/FF0sX4V82W3sNzXMkejB6zfX/glpNp vKySso2SBFTgJEUvRWt0Itcxup700nav7euuyXah7IwScl/k7RMhc2uAQfUN63CCiQ2E5fXTwK1 2IhVy3s2GjUB736aLU2K/b+AjX3P8nouMk1VafdYLudoaXu5Z00izE0t/KiALsC7xlolFXnjTCA O3GzlABsdP71mTR9fcKxJX5ex57Nyzo0Of46N0yK9lwJluxzKzs+d/d/0= X-Google-Smtp-Source: AGHT+IEZrj/HQuARSscCPMuD6ISRIB/7wuGRHKn024Yyz4w+QemOtbjTLJ+khnZqOKjVAf03tv/cHQ== X-Received: by 2002:a05:6000:26ce:b0:427:5e6:c0e5 with SMTP id ffacd0b85a97d-429a7e75aaamr1632320f8f.39.1761630928856; Mon, 27 Oct 2025 22:55:28 -0700 (PDT) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Mads Ynddal , Cameron Esfahani , qemu-arm@nongnu.org, Roman Bolshakov , Akihiko Odaki , Phil Dennis-Jordan , Mohamed Mediouni , Peter Collingbourne , Peter Maydell , Alexander Graf , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v3 18/59] target/i386/hvf: Factor hvf_handle_vmexit() out Date: Tue, 28 Oct 2025 06:41:54 +0100 Message-ID: <20251028054238.14949-19-philmd@linaro.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251028054238.14949-1-philmd@linaro.org> References: <20251028054238.14949-1-philmd@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=philmd@linaro.org; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1761630968367154100 Factor hvf_handle_vmexit() out of hvf_arch_vcpu_exec(). Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Peter Maydell --- target/i386/hvf/hvf.c | 478 +++++++++++++++++++++--------------------- 1 file changed, 244 insertions(+), 234 deletions(-) diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 76a58cb0350..28d98659ec2 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -721,6 +721,249 @@ void hvf_simulate_wrmsr(CPUState *cs) printf("write msr %llx\n", RCX(cs));*/ } =20 +static int hvf_handle_vmexit(CPUState *cpu) +{ + X86CPU *x86_cpu =3D env_archcpu(cpu_env(cpu)); + uint64_t exit_reason =3D rvmcs(cpu->accel->fd, VMCS_EXIT_REASON); + uint64_t exit_qual =3D rvmcs(cpu->accel->fd, VMCS_EXIT_QUALIFICATION); + uint32_t ins_len =3D (uint32_t)rvmcs(cpu->accel->fd, + VMCS_EXIT_INSTRUCTION_LENGTH); + + uint64_t idtvec_info =3D rvmcs(cpu->accel->fd, VMCS_IDT_VECTORING_INFO= ); + int ret =3D 0; + + hvf_store_events(cpu, ins_len, idtvec_info); + rip =3D rreg(cpu->accel->fd, HV_X86_RIP); + env->eflags =3D rreg(cpu->accel->fd, HV_X86_RFLAGS); + + bql_lock(); + + update_apic_tpr(cpu); + current_cpu =3D cpu; + + switch (exit_reason) { + case EXIT_REASON_HLT: { + macvm_set_rip(cpu, rip + ins_len); + if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) + && (env->eflags & IF_MASK)) + && !cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI) + && !(idtvec_info & VMCS_IDT_VEC_VALID)) { + cpu->halted =3D 1; + ret =3D EXCP_HLT; + break; + } + ret =3D EXCP_INTERRUPT; + break; + } + case EXIT_REASON_MWAIT: { + ret =3D EXCP_INTERRUPT; + break; + } + /* Need to check if MMIO or unmapped fault */ + case EXIT_REASON_EPT_FAULT: + { + hvf_slot *slot; + uint64_t gpa =3D rvmcs(cpu->accel->fd, VMCS_GUEST_PHYSICAL_ADDRESS= ); + + if (((idtvec_info & VMCS_IDT_VEC_VALID) =3D=3D 0) && + ((exit_qual & EXIT_QUAL_NMIUDTI) !=3D 0)) { + vmx_set_nmi_blocking(cpu); + } + + slot =3D hvf_find_overlap_slot(gpa, 1); + /* mmio */ + if (ept_emulation_fault(slot, gpa, exit_qual)) { + struct x86_decode decode; + + hvf_load_regs(cpu); + decode_instruction(env, &decode); + exec_instruction(env, &decode); + hvf_store_regs(cpu); + break; + } + break; + } + case EXIT_REASON_INOUT: + { + uint32_t in =3D (exit_qual & 8) !=3D 0; + uint32_t size =3D (exit_qual & 7) + 1; + uint32_t string =3D (exit_qual & 16) !=3D 0; + uint32_t port =3D exit_qual >> 16; + /*uint32_t rep =3D (exit_qual & 0x20) !=3D 0;*/ + struct x86_decode decode; + + if (!string && in) { + uint64_t val =3D 0; + + hvf_load_regs(cpu); + hvf_handle_io(env_cpu(env), port, &val, 0, size, 1); + if (size =3D=3D 1) { + AL(env) =3D val; + } else if (size =3D=3D 2) { + AX(env) =3D val; + } else if (size =3D=3D 4) { + RAX(env) =3D (uint32_t)val; + } else { + RAX(env) =3D (uint64_t)val; + } + env->eip +=3D ins_len; + hvf_store_regs(cpu); + break; + } else if (!string && !in) { + RAX(env) =3D rreg(cpu->accel->fd, HV_X86_RAX); + hvf_handle_io(env_cpu(env), port, &RAX(env), 1, size, 1); + macvm_set_rip(cpu, rip + ins_len); + break; + } + + hvf_load_regs(cpu); + decode_instruction(env, &decode); + assert(ins_len =3D=3D decode.len); + exec_instruction(env, &decode); + hvf_store_regs(cpu); + + break; + } + case EXIT_REASON_CPUID: { + uint32_t rax =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RAX); + uint32_t rbx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RBX); + uint32_t rcx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RCX); + uint32_t rdx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RDX); + + if (rax =3D=3D 1) { + /* CPUID1.ecx.OSXSAVE needs to know CR4 */ + env->cr[4] =3D rvmcs(cpu->accel->fd, VMCS_GUEST_CR4); + } + hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx); + + wreg(cpu->accel->fd, HV_X86_RAX, rax); + wreg(cpu->accel->fd, HV_X86_RBX, rbx); + wreg(cpu->accel->fd, HV_X86_RCX, rcx); + wreg(cpu->accel->fd, HV_X86_RDX, rdx); + + macvm_set_rip(cpu, rip + ins_len); + break; + } + case EXIT_REASON_XSETBV: { + uint32_t eax =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RAX); + uint32_t ecx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RCX); + uint32_t edx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RDX); + + if (ecx) { + macvm_set_rip(cpu, rip + ins_len); + break; + } + env->xcr0 =3D ((uint64_t)edx << 32) | eax; + wreg(cpu->accel->fd, HV_X86_XCR0, env->xcr0 | 1); + macvm_set_rip(cpu, rip + ins_len); + break; + } + case EXIT_REASON_INTR_WINDOW: + vmx_clear_int_window_exiting(cpu); + ret =3D EXCP_INTERRUPT; + break; + case EXIT_REASON_NMI_WINDOW: + vmx_clear_nmi_window_exiting(cpu); + ret =3D EXCP_INTERRUPT; + break; + case EXIT_REASON_EXT_INTR: + /* force exit and allow io handling */ + ret =3D EXCP_INTERRUPT; + break; + case EXIT_REASON_RDMSR: + case EXIT_REASON_WRMSR: + { + hvf_load_regs(cpu); + if (exit_reason =3D=3D EXIT_REASON_RDMSR) { + hvf_simulate_rdmsr(cpu); + } else { + hvf_simulate_wrmsr(cpu); + } + env->eip +=3D ins_len; + hvf_store_regs(cpu); + break; + } + case EXIT_REASON_CR_ACCESS: { + int cr; + int reg; + + hvf_load_regs(cpu); + cr =3D exit_qual & 15; + reg =3D (exit_qual >> 8) & 15; + + switch (cr) { + case 0x0: { + macvm_set_cr0(cpu->accel->fd, RRX(env, reg)); + break; + } + case 4: { + macvm_set_cr4(cpu->accel->fd, RRX(env, reg)); + break; + } + case 8: { + if (exit_qual & 0x10) { + RRX(env, reg) =3D cpu_get_apic_tpr(x86_cpu->apic_state); + } else { + int tpr =3D RRX(env, reg); + cpu_set_apic_tpr(x86_cpu->apic_state, tpr); + ret =3D EXCP_INTERRUPT; + } + break; + } + default: + error_report("Unrecognized CR %d", cr); + abort(); + } + env->eip +=3D ins_len; + hvf_store_regs(cpu); + break; + } + case EXIT_REASON_APIC_ACCESS: { /* TODO */ + struct x86_decode decode; + + hvf_load_regs(cpu); + decode_instruction(env, &decode); + exec_instruction(env, &decode); + hvf_store_regs(cpu); + break; + } + case EXIT_REASON_TPR: { + ret =3D 1; + break; + } + case EXIT_REASON_TASK_SWITCH: { + uint64_t vinfo =3D rvmcs(cpu->accel->fd, VMCS_IDT_VECTORING_INFO); + x86_segment_selector sel =3D {.sel =3D exit_qual & 0xffff}; + + vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3, + vinfo & VMCS_INTR_VALID, + vinfo & VECTORING_INFO_VECTOR_MASK, + vinfo & VMCS_INTR_T_MASK); + break; + } + case EXIT_REASON_TRIPLE_FAULT: { + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + ret =3D EXCP_INTERRUPT; + break; + } + case EXIT_REASON_RDPMC: + wreg(cpu->accel->fd, HV_X86_RAX, 0); + wreg(cpu->accel->fd, HV_X86_RDX, 0); + macvm_set_rip(cpu, rip + ins_len); + break; + case VMX_REASON_VMCALL: + env->exception_nr =3D EXCP0D_GPF; + env->exception_injected =3D 1; + env->has_error_code =3D true; + env->error_code =3D 0; + break; + default: + error_report("%llx: unhandled exit %llx", rip, exit_reason); + } + + return ret; +} + int hvf_arch_vcpu_exec(CPUState *cpu) { X86CPU *x86_cpu =3D X86_CPU(cpu); @@ -752,240 +995,7 @@ int hvf_arch_vcpu_exec(CPUState *cpu) hv_return_t r =3D hv_vcpu_run_until(cpu->accel->fd, HV_DEADLINE_FO= REVER); assert_hvf_ok(r); =20 - /* handle VMEXIT */ - uint64_t exit_reason =3D rvmcs(cpu->accel->fd, VMCS_EXIT_REASON); - uint64_t exit_qual =3D rvmcs(cpu->accel->fd, VMCS_EXIT_QUALIFICATI= ON); - uint32_t ins_len =3D (uint32_t)rvmcs(cpu->accel->fd, - VMCS_EXIT_INSTRUCTION_LENGTH); - - uint64_t idtvec_info =3D rvmcs(cpu->accel->fd, VMCS_IDT_VECTORING_= INFO); - - hvf_store_events(cpu, ins_len, idtvec_info); - rip =3D rreg(cpu->accel->fd, HV_X86_RIP); - env->eflags =3D rreg(cpu->accel->fd, HV_X86_RFLAGS); - - bql_lock(); - - update_apic_tpr(cpu); - current_cpu =3D cpu; - - ret =3D 0; - switch (exit_reason) { - case EXIT_REASON_HLT: { - macvm_set_rip(cpu, rip + ins_len); - if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK)) - && !cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI) && - !(idtvec_info & VMCS_IDT_VEC_VALID)) { - cpu->halted =3D 1; - ret =3D EXCP_HLT; - break; - } - ret =3D EXCP_INTERRUPT; - break; - } - case EXIT_REASON_MWAIT: { - ret =3D EXCP_INTERRUPT; - break; - } - /* Need to check if MMIO or unmapped fault */ - case EXIT_REASON_EPT_FAULT: - { - hvf_slot *slot; - uint64_t gpa =3D rvmcs(cpu->accel->fd, VMCS_GUEST_PHYSICAL_ADD= RESS); - - if (((idtvec_info & VMCS_IDT_VEC_VALID) =3D=3D 0) && - ((exit_qual & EXIT_QUAL_NMIUDTI) !=3D 0)) { - vmx_set_nmi_blocking(cpu); - } - - slot =3D hvf_find_overlap_slot(gpa, 1); - /* mmio */ - if (ept_emulation_fault(slot, gpa, exit_qual)) { - struct x86_decode decode; - - hvf_load_regs(cpu); - decode_instruction(env, &decode); - exec_instruction(env, &decode); - hvf_store_regs(cpu); - break; - } - break; - } - case EXIT_REASON_INOUT: - { - uint32_t in =3D (exit_qual & 8) !=3D 0; - uint32_t size =3D (exit_qual & 7) + 1; - uint32_t string =3D (exit_qual & 16) !=3D 0; - uint32_t port =3D exit_qual >> 16; - /*uint32_t rep =3D (exit_qual & 0x20) !=3D 0;*/ - - if (!string && in) { - uint64_t val =3D 0; - hvf_load_regs(cpu); - hvf_handle_io(env_cpu(env), port, &val, 0, size, 1); - if (size =3D=3D 1) { - AL(env) =3D val; - } else if (size =3D=3D 2) { - AX(env) =3D val; - } else if (size =3D=3D 4) { - RAX(env) =3D (uint32_t)val; - } else { - RAX(env) =3D (uint64_t)val; - } - env->eip +=3D ins_len; - hvf_store_regs(cpu); - break; - } else if (!string && !in) { - RAX(env) =3D rreg(cpu->accel->fd, HV_X86_RAX); - hvf_handle_io(env_cpu(env), port, &RAX(env), 1, size, 1); - macvm_set_rip(cpu, rip + ins_len); - break; - } - struct x86_decode decode; - - hvf_load_regs(cpu); - decode_instruction(env, &decode); - assert(ins_len =3D=3D decode.len); - exec_instruction(env, &decode); - hvf_store_regs(cpu); - - break; - } - case EXIT_REASON_CPUID: { - uint32_t rax =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RAX); - uint32_t rbx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RBX); - uint32_t rcx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RCX); - uint32_t rdx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RDX); - - if (rax =3D=3D 1) { - /* CPUID1.ecx.OSXSAVE needs to know CR4 */ - env->cr[4] =3D rvmcs(cpu->accel->fd, VMCS_GUEST_CR4); - } - hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx); - - wreg(cpu->accel->fd, HV_X86_RAX, rax); - wreg(cpu->accel->fd, HV_X86_RBX, rbx); - wreg(cpu->accel->fd, HV_X86_RCX, rcx); - wreg(cpu->accel->fd, HV_X86_RDX, rdx); - - macvm_set_rip(cpu, rip + ins_len); - break; - } - case EXIT_REASON_XSETBV: { - uint32_t eax =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RAX); - uint32_t ecx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RCX); - uint32_t edx =3D (uint32_t)rreg(cpu->accel->fd, HV_X86_RDX); - - if (ecx) { - macvm_set_rip(cpu, rip + ins_len); - break; - } - env->xcr0 =3D ((uint64_t)edx << 32) | eax; - wreg(cpu->accel->fd, HV_X86_XCR0, env->xcr0 | 1); - macvm_set_rip(cpu, rip + ins_len); - break; - } - case EXIT_REASON_INTR_WINDOW: - vmx_clear_int_window_exiting(cpu); - ret =3D EXCP_INTERRUPT; - break; - case EXIT_REASON_NMI_WINDOW: - vmx_clear_nmi_window_exiting(cpu); - ret =3D EXCP_INTERRUPT; - break; - case EXIT_REASON_EXT_INTR: - /* force exit and allow io handling */ - ret =3D EXCP_INTERRUPT; - break; - case EXIT_REASON_RDMSR: - case EXIT_REASON_WRMSR: - { - hvf_load_regs(cpu); - if (exit_reason =3D=3D EXIT_REASON_RDMSR) { - hvf_simulate_rdmsr(cpu); - } else { - hvf_simulate_wrmsr(cpu); - } - env->eip +=3D ins_len; - hvf_store_regs(cpu); - break; - } - case EXIT_REASON_CR_ACCESS: { - int cr; - int reg; - - hvf_load_regs(cpu); - cr =3D exit_qual & 15; - reg =3D (exit_qual >> 8) & 15; - - switch (cr) { - case 0x0: { - macvm_set_cr0(cpu->accel->fd, RRX(env, reg)); - break; - } - case 4: { - macvm_set_cr4(cpu->accel->fd, RRX(env, reg)); - break; - } - case 8: { - if (exit_qual & 0x10) { - RRX(env, reg) =3D cpu_get_apic_tpr(x86_cpu->apic_state= ); - } else { - int tpr =3D RRX(env, reg); - cpu_set_apic_tpr(x86_cpu->apic_state, tpr); - ret =3D EXCP_INTERRUPT; - } - break; - } - default: - error_report("Unrecognized CR %d", cr); - abort(); - } - env->eip +=3D ins_len; - hvf_store_regs(cpu); - break; - } - case EXIT_REASON_APIC_ACCESS: { /* TODO */ - struct x86_decode decode; - - hvf_load_regs(cpu); - decode_instruction(env, &decode); - exec_instruction(env, &decode); - hvf_store_regs(cpu); - break; - } - case EXIT_REASON_TPR: { - ret =3D 1; - break; - } - case EXIT_REASON_TASK_SWITCH: { - uint64_t vinfo =3D rvmcs(cpu->accel->fd, VMCS_IDT_VECTORING_IN= FO); - x86_segment_selector sel =3D {.sel =3D exit_qual & 0xffff}; - vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3, - vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, = vinfo - & VMCS_INTR_T_MASK); - break; - } - case EXIT_REASON_TRIPLE_FAULT: { - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); - ret =3D EXCP_INTERRUPT; - break; - } - case EXIT_REASON_RDPMC: - wreg(cpu->accel->fd, HV_X86_RAX, 0); - wreg(cpu->accel->fd, HV_X86_RDX, 0); - macvm_set_rip(cpu, rip + ins_len); - break; - case VMX_REASON_VMCALL: - env->exception_nr =3D EXCP0D_GPF; - env->exception_injected =3D 1; - env->has_error_code =3D true; - env->error_code =3D 0; - break; - default: - error_report("%llx: unhandled exit %llx", rip, exit_reason); - } + ret =3D hvf_handle_vmexit(cpu); } while (ret =3D=3D 0); =20 return ret; --=20 2.51.0