From: Avi Kivity <avi@redhat.com>
To: "Nadav Har'El" <nyh@il.ibm.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 19/24] Deciding if L0 or L1 should handle an L2 exit
Date: Mon, 14 Jun 2010 15:24:02 +0300 [thread overview]
Message-ID: <4C161F62.9070506@redhat.com> (raw)
In-Reply-To: <201006131232.o5DCWIHl013120@rice.haifa.ibm.com>
On 06/13/2010 03:32 PM, Nadav Har'El wrote:
> This patch contains the logic of whether an L2 exit should be handled by L0
> and then L2 should be resumed, or whether L1 should be run to handle this
> exit (using the nested_vmx_vmexit() function of the previous patch).
>
> The basic idea is to let L1 handle the exit only if it actually asked to
> trap this sort of event. For example, when L2 exits on a change to CR0,
> we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
> bit which changed; If it did, we exit to L1. But if it didn't it means that
> it is we (L0) that wished to trap this event, so we handle it ourselves.
>
> The next two patches add additional logic of what to do when an interrupt or
> exception is injected: Does L0 need to do it, should we exit to L1 to do it,
> or should we resume L2 and keep the exception to be injected later.
>
> We keep a new flag, "nested_run_pending", which can override the decision of
> which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
> L2 next, not L1. This is necessary in several situations where had L1 run on
> bare metal it would not have expected to be resumed at this stage. One
> example is when L1 did a VMLAUNCH of L2 and therefore expects L2 to be run.
> Another examples is when L2 exits on an #NM exception that L0 asked for
> (because of lazy FPU loading), and L0 must deal with the exception and resume
> L2 which was in a middle of an instruction, and not resume L1 which does not
> expect to see an exit from L2 at this point. nested_run_pending is especially
> intended to avoid switching to L1 in the injection decision-point described
> above.
>
> @@ -3819,6 +3841,8 @@ static int handle_exception(struct kvm_v
>
> if (is_no_device(intr_info)) {
> vmx_fpu_activate(vcpu);
> + if (vmx->nested.nested_mode)
> + vmx->nested.nested_run_pending = 1;
> return 1;
> }
>
Isn't this true for many other exceptions? #UD which we emulate (but
the guest doesn't trap), page faults which we handle completely...
>
> +
> +/* Return 1 if we should exit from L2 to L1 to handle a CR access exit,
> + * rather than handle it ourselves in L0. I.e., check if L1 wanted to
> + * intercept (via guest_host_mask etc.) the current event.
> + */
> +static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
> + struct shadow_vmcs *l2svmcs)
> +{
> + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
> + int cr = exit_qualification& 15;
> + int reg = (exit_qualification>> 8)& 15;
> + unsigned long val = kvm_register_read(vcpu, reg);
> +
> + switch ((exit_qualification>> 4)& 3) {
> + case 0: /* mov to cr */
> + switch (cr) {
> + case 0:
> + if (l2svmcs->cr0_guest_host_mask&
> + (val ^ l2svmcs->cr0_read_shadow))
> + return 1;
> + break;
> + case 3:
> + if (l2svmcs->cpu_based_vm_exec_control&
> + CPU_BASED_CR3_LOAD_EXITING)
> + return 1;
> + break;
> + case 4:
> + if (l2svmcs->cr4_guest_host_mask&
> + (l2svmcs->cr4_read_shadow ^ val))
> + return 1;
> + break;
> + case 8:
> + if (l2svmcs->cpu_based_vm_exec_control&
> + CPU_BASED_CR8_LOAD_EXITING)
> + return 1;
>
Should check TPR threshold here too if enabled.
> + case 3: /* lmsw */
> + if (l2svmcs->cr0_guest_host_mask&
> + (val ^ l2svmcs->cr0_read_shadow))
> + return 1;
>
Need to mask off bit 0 (cr0.pe) of val, since lmsw can't clear it.
> + break;
> + }
> + return 0;
> +}
> +
> +/* Return 1 if we should exit from L2 to L1 to handle an exit, or 0 if we
> + * should handle it ourselves in L0. Only call this when in nested_mode (L2).
> + */
> +static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu, bool afterexit)
> +{
> + u32 exit_code = vmcs_read32(VM_EXIT_REASON);
> + struct vcpu_vmx *vmx = to_vmx(vcpu);
> + u32 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
> + struct shadow_vmcs *l2svmcs;
> + int r = 0;
> +
> + if (vmx->nested.nested_run_pending)
> + return 0;
> +
> + if (unlikely(vmx->fail)) {
> + printk(KERN_INFO "%s failed vm entry %x\n",
> + __func__, vmcs_read32(VM_INSTRUCTION_ERROR));
> + return 1;
> + }
> +
> + if (afterexit) {
> + /* There are some cases where we should let L1 handle certain
> + * events when these are injected (afterexit==0) but we should
> + * handle them in L0 on an exit (afterexit==1).
> + */
> + switch (exit_code) {
> + case EXIT_REASON_EXTERNAL_INTERRUPT:
> + return 0;
> + case EXIT_REASON_EXCEPTION_NMI:
> + if (!is_exception(intr_info))
> + return 0;
> + if (is_page_fault(intr_info)&& (!enable_ept))
> + return 0;
>
Some page faults do need a l2->l1 transition. Maybe I'll see this later.
> + break;
> + case EXIT_REASON_EPT_VIOLATION:
> + if (enable_ept)
> + return 0;
> + break;
> + }
> + }
> +
> + if (!nested_map_current(vcpu))
> + return 0;
> + l2svmcs = get_shadow_vmcs(vcpu);
> +
> + switch (exit_code) {
> + case EXIT_REASON_INVLPG:
> + if (l2svmcs->cpu_based_vm_exec_control&
> + CPU_BASED_INVLPG_EXITING)
> + r = 1;
> + break;
> + case EXIT_REASON_MSR_READ:
> + case EXIT_REASON_MSR_WRITE:
> + r = nested_vmx_exit_handled_msr(vcpu, l2svmcs, exit_code);
> + break;
> + case EXIT_REASON_CR_ACCESS:
> + r = nested_vmx_exit_handled_cr(vcpu, l2svmcs);
> + break;
> + case EXIT_REASON_DR_ACCESS:
> + if (l2svmcs->cpu_based_vm_exec_control&
> + CPU_BASED_MOV_DR_EXITING)
> + r = 1;
> + break;
> + case EXIT_REASON_EXCEPTION_NMI:
> + if (is_external_interrupt(intr_info)&&
> + (l2svmcs->pin_based_vm_exec_control&
> + PIN_BASED_EXT_INTR_MASK))
> + r = 1;
>
A real external interrupt should never be handled by the guest, only a
virtual external interrupt.
> + else if (is_nmi(intr_info)&&
> + (l2svmcs->pin_based_vm_exec_control&
> + PIN_BASED_NMI_EXITING))
> + r = 1;
>
Ditto for nmi.
> + else if (is_exception(intr_info)&&
> + (l2svmcs->exception_bitmap&
> + (1u<< (intr_info& INTR_INFO_VECTOR_MASK))))
> + r = 1;
>
Bit 14 of the exception bitmap is special, need special treatment.
> + else if (is_page_fault(intr_info))
> + r = 1;
>
Still looking for magic page fault handling...
> + break;
> + case EXIT_REASON_EXTERNAL_INTERRUPT:
> + if (l2svmcs->pin_based_vm_exec_control&
> + PIN_BASED_EXT_INTR_MASK)
> + r = 1;
> + break;
> + default:
> + r = 1;
> + }
> + nested_unmap_current(vcpu);
> +
> + return r;
> +}
> +
> /*
> * The guest has exited. See if we can fix it or if we need userspace
> * assistance.
>
--
error compiling committee.c: too many arguments to function
next prev parent reply other threads:[~2010-06-14 12:24 UTC|newest]
Thread overview: 147+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-13 12:22 [PATCH 0/24] Nested VMX, v5 Nadav Har'El
2010-06-13 12:23 ` [PATCH 1/24] Move nested option from svm.c to x86.c Nadav Har'El
2010-06-14 8:11 ` Avi Kivity
2010-06-15 14:27 ` Nadav Har'El
2010-06-13 12:23 ` [PATCH 2/24] Add VMX and SVM to list of supported cpuid features Nadav Har'El
2010-06-14 8:13 ` Avi Kivity
2010-06-15 14:31 ` Nadav Har'El
2010-06-13 12:24 ` [PATCH 3/24] Implement VMXON and VMXOFF Nadav Har'El
2010-06-14 8:21 ` Avi Kivity
2010-06-16 11:14 ` Nadav Har'El
2010-06-16 11:26 ` Avi Kivity
2010-06-15 20:18 ` Marcelo Tosatti
2010-06-16 7:50 ` Nadav Har'El
2010-06-13 12:24 ` [PATCH 4/24] Allow setting the VMXE bit in CR4 Nadav Har'El
2010-06-15 11:09 ` Gleb Natapov
2010-06-15 14:44 ` Nadav Har'El
2010-06-13 12:25 ` [PATCH 5/24] Introduce vmcs12: a VMCS structure for L1 Nadav Har'El
2010-06-14 8:33 ` Avi Kivity
2010-06-14 8:49 ` Nadav Har'El
2010-06-14 12:35 ` Avi Kivity
2010-06-16 12:24 ` Nadav Har'El
2010-06-16 13:10 ` Avi Kivity
2010-06-22 14:54 ` Nadav Har'El
2010-06-22 16:53 ` Nadav Har'El
2010-06-23 8:07 ` Avi Kivity
2010-08-08 15:09 ` Nadav Har'El
2010-08-10 3:24 ` Avi Kivity
2010-06-23 7:57 ` Avi Kivity
2010-06-23 9:15 ` Alexander Graf
2010-06-23 9:24 ` Avi Kivity
2010-06-23 12:07 ` Nadav Har'El
2010-06-23 12:13 ` Avi Kivity
2010-06-13 12:25 ` [PATCH 6/24] Implement reading and writing of VMX MSRs Nadav Har'El
2010-06-14 8:42 ` Avi Kivity
2010-06-23 8:13 ` Nadav Har'El
2010-06-23 8:24 ` Avi Kivity
2010-06-13 12:26 ` [PATCH 7/24] Understanding guest pointers to vmcs12 structures Nadav Har'El
2010-06-14 8:48 ` Avi Kivity
2010-08-02 12:25 ` Nadav Har'El
2010-08-02 13:38 ` Avi Kivity
2010-06-15 12:14 ` Gleb Natapov
2010-08-01 15:16 ` Nadav Har'El
2010-08-01 15:25 ` Gleb Natapov
2010-08-02 8:57 ` Nadav Har'El
2010-06-13 12:26 ` [PATCH 8/24] Hold a vmcs02 for each vmcs12 Nadav Har'El
2010-06-14 8:57 ` Avi Kivity
2010-07-06 9:50 ` Dong, Eddie
2010-08-02 13:38 ` Nadav Har'El
2010-06-13 12:27 ` [PATCH 9/24] Implement VMCLEAR Nadav Har'El
2010-06-14 9:03 ` Avi Kivity
2010-06-15 13:47 ` Gleb Natapov
2010-06-15 13:50 ` Avi Kivity
2010-06-15 13:54 ` Gleb Natapov
2010-08-05 11:50 ` Nadav Har'El
2010-08-05 11:53 ` Gleb Natapov
2010-08-05 12:01 ` Nadav Har'El
2010-08-05 12:05 ` Avi Kivity
2010-08-05 12:10 ` Nadav Har'El
2010-08-05 12:13 ` Avi Kivity
2010-08-05 12:29 ` Nadav Har'El
2010-08-05 12:03 ` Avi Kivity
2010-07-06 2:56 ` Dong, Eddie
2010-08-03 12:12 ` Nadav Har'El
2010-06-13 12:27 ` [PATCH 10/24] Implement VMPTRLD Nadav Har'El
2010-06-14 9:07 ` Avi Kivity
2010-08-05 11:13 ` Nadav Har'El
2010-06-16 13:36 ` Gleb Natapov
2010-07-06 3:09 ` Dong, Eddie
2010-08-05 11:35 ` Nadav Har'El
2010-06-13 12:28 ` [PATCH 11/24] Implement VMPTRST Nadav Har'El
2010-06-14 9:15 ` Avi Kivity
2010-06-16 13:53 ` Gleb Natapov
2010-06-16 15:33 ` Nadav Har'El
2010-06-13 12:28 ` [PATCH 12/24] Add VMCS fields to the vmcs12 Nadav Har'El
2010-06-14 9:24 ` Avi Kivity
2010-06-16 14:18 ` Gleb Natapov
2010-06-13 12:29 ` [PATCH 13/24] Implement VMREAD and VMWRITE Nadav Har'El
2010-06-14 9:36 ` Avi Kivity
2010-06-16 14:48 ` Gleb Natapov
2010-08-04 13:42 ` Nadav Har'El
2010-08-04 16:09 ` Nadav Har'El
2010-08-04 16:41 ` Avi Kivity
2010-06-16 15:03 ` Gleb Natapov
2010-08-04 11:46 ` Nadav Har'El
2010-06-13 12:29 ` [PATCH 14/24] Prepare vmcs02 from vmcs01 and vmcs12 Nadav Har'El
2010-06-14 11:11 ` Avi Kivity
2010-06-17 8:50 ` Gleb Natapov
2010-07-06 6:25 ` Dong, Eddie
2010-06-13 12:30 ` [PATCH 15/24] Move register-syncing to a function Nadav Har'El
2010-06-13 12:30 ` [PATCH 16/24] Implement VMLAUNCH and VMRESUME Nadav Har'El
2010-06-14 11:41 ` Avi Kivity
2010-09-26 11:14 ` Nadav Har'El
2010-09-26 12:56 ` Avi Kivity
2010-09-26 13:06 ` Nadav Har'El
2010-09-26 13:51 ` Avi Kivity
2010-06-17 10:59 ` Gleb Natapov
2010-09-16 16:06 ` Nadav Har'El
2010-06-13 12:31 ` [PATCH 17/24] No need for handle_vmx_insn function any more Nadav Har'El
2010-06-13 12:31 ` [PATCH 18/24] Exiting from L2 to L1 Nadav Har'El
2010-06-14 12:04 ` Avi Kivity
2010-09-12 14:05 ` Nadav Har'El
2010-09-12 14:29 ` Avi Kivity
2010-09-12 17:05 ` Nadav Har'El
2010-09-12 17:21 ` Avi Kivity
2010-09-12 19:51 ` Nadav Har'El
2010-09-13 8:48 ` Avi Kivity
2010-09-13 5:53 ` Sheng Yang
2010-09-13 8:52 ` Avi Kivity
2010-09-13 9:01 ` Nadav Har'El
2010-09-13 9:34 ` Avi Kivity
2010-09-14 13:07 ` Nadav Har'El
2010-06-13 12:32 ` [PATCH 19/24] Deciding if L0 or L1 should handle an L2 exit Nadav Har'El
2010-06-14 12:24 ` Avi Kivity [this message]
2010-09-16 14:42 ` Nadav Har'El
2010-06-13 12:32 ` [PATCH 20/24] Correct handling of interrupt injection Nadav Har'El
2010-06-14 12:29 ` Avi Kivity
2010-06-14 12:48 ` Avi Kivity
2010-09-16 15:25 ` Nadav Har'El
2010-06-13 12:33 ` [PATCH 21/24] Correct handling of exception injection Nadav Har'El
2010-06-13 12:33 ` [PATCH 22/24] Correct handling of idt vectoring info Nadav Har'El
2010-06-17 11:58 ` Gleb Natapov
2010-09-20 6:37 ` Nadav Har'El
2010-09-20 9:34 ` Gleb Natapov
2010-09-20 10:03 ` Nadav Har'El
2010-09-20 10:11 ` Avi Kivity
2010-09-22 23:15 ` Nadav Har'El
2010-09-26 15:14 ` Avi Kivity
2010-09-26 15:18 ` Gleb Natapov
2010-09-20 10:20 ` Gleb Natapov
2010-06-13 12:34 ` [PATCH 23/24] Handling of CR0.TS and #NM for Lazy FPU loading Nadav Har'El
2010-06-13 12:34 ` [PATCH 24/24] Miscellenous small corrections Nadav Har'El
2010-06-14 12:34 ` [PATCH 0/24] Nested VMX, v5 Avi Kivity
2010-06-14 13:03 ` Nadav Har'El
2010-06-15 10:00 ` Avi Kivity
2010-10-17 12:03 ` Nadav Har'El
2010-10-17 12:10 ` Avi Kivity
2010-10-17 12:39 ` Nadav Har'El
2010-10-17 13:35 ` Avi Kivity
2010-07-09 8:59 ` Dong, Eddie
2010-07-11 8:27 ` Nadav Har'El
2010-07-11 11:05 ` Alexander Graf
2010-07-11 12:49 ` Nadav Har'El
2010-07-11 13:12 ` Avi Kivity
2010-07-11 15:39 ` Nadav Har'El
2010-07-11 15:45 ` Avi Kivity
2010-07-11 13:20 ` Avi Kivity
2010-07-15 3:27 ` Sheng Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C161F62.9070506@redhat.com \
--to=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=nyh@il.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).