From mboxrd@z Thu Jan 1 00:00:00 1970 From: Razvan Cojocaru Subject: Re: [PATCH RFC 6/9] xen, libxc: Request page fault injection via libxc Date: Wed, 02 Jul 2014 19:06:05 +0300 Message-ID: <53B42DED.1000406@bitdefender.com> References: <1404308041-15461-1-git-send-email-rcojocaru@bitdefender.com> <1404308041-15461-6-git-send-email-rcojocaru@bitdefender.com> <53B4468D020000780001FB40@mail.emea.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <53B4468D020000780001FB40@mail.emea.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich Cc: tim@xen.org, xen-devel@lists.xen.org List-Id: xen-devel@lists.xenproject.org On 07/02/2014 06:51 PM, Jan Beulich wrote: >>>> On 02.07.14 at 15:33, wrote: >> Added new XEN_DOMCTL_set_pagefault_info hypercall, used by libxc's >> new xc_domain_set_pagefault_info() function to set per-domain page >> fault injection information. This information is then used to call >> hvm_inject_page_fault() at the first VMENTRY where the guest status >> matches and there are no other pending traps. > > So the first question that strikes me here: What good can it do to be > able to inject arbitrary page faults, possibly at times where the guest > OS is absolutely not expecting them? The guest, as Andrew Cooper said, is waiting for a mem_event reply. >> @@ -430,6 +431,9 @@ static void vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c) >> __vmread(GUEST_SYSENTER_CS, &c->sysenter_cs); >> __vmread(GUEST_SYSENTER_ESP, &c->sysenter_esp); >> __vmread(GUEST_SYSENTER_EIP, &c->sysenter_eip); >> + __vmread(GUEST_CS_AR_BYTES, &cs_arbytes); >> + >> + c->cs_arbytes = (uint32_t)cs_arbytes; > > This again looks like an unrelated change without any explanation. It's used here, to check if we're in user mode before injecting the page fault: 92 +static void check_pf_injection(void) 93 +{ 94 + struct vcpu *curr = current; 95 + struct domain *d = curr->domain; 96 + struct hvm_hw_cpu ctxt; 97 + uint32_t cs_dpl; 98 + 99 + if ( !is_hvm_domain(d) || d->fault_info.virtual_address == 0 ) 100 + return; 101 + 102 + memset(&ctxt, 0, sizeof(struct hvm_hw_cpu)); 103 + hvm_funcs.save_cpu_ctxt(curr, &ctxt); 104 + 105 + cs_dpl = (ctxt.cs_arbytes >> 5) & 3; 106 + 107 + if ( cs_dpl == 3 /* Guest is in user mode */ 108 + && !ctxt.pending_event 109 + && ctxt.cr3 == d->fault_info.address_space ) 110 + { 111 + /* Cache */ 112 + uint64_t virtual_address = d->fault_info.virtual_address; 113 + uint32_t write_access = d->fault_info.write_access; 114 + 115 + /* Reset */ 116 + d->fault_info.address_space = 0; 117 + d->fault_info.virtual_address = 0; 118 + d->fault_info.write_access = 0; 119 + 120 + hvm_inject_page_fault((write_access << 1) | PFEC_user_mode, 121 + virtual_address); 122 + } 123 +} Thanks, Razvan Cojocaru