[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Query regarding x86_emulate_memop() function

  • To: "Abhinav Srivastava" <abhinavs_iitkgp@xxxxxxxxxxx>
  • From: "Grzegorz Miłoś" <gm281@xxxxxxxxx>
  • Date: Fri, 6 Jun 2008 21:08:36 +0100
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
  • Delivery-date: Fri, 06 Jun 2008 13:08:57 -0700
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references:x-google-sender-auth; b=ITDS7UHg8v65VWwed6CZaH5tcRs1CQSOIZCW3gQqDLFytiKIZilC1vAoz4SQLXVVgz OJOk6fTP9+uaBzBFkjBzzXmCM0/AuSHE7/lA0ST3Je/rmmj6yikmbtCRO4CQiQcQkdL/ 2oLCOviqrVssbbyhDPCKhA7S6EZl4zHhMfYt0=
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

> Hi there,
> I have a question regarding the functionality of x86_emulate_memop (Xen 3.1) 
> or x86_emulate (Xen 3.2) function. This function gets called from 
> sh_page_fault() function which is invoked when Xen receives a page fault.

Correct. But not only from sh_page_fault, also:
- ptwr_do_page_fault() (in xen/arch/x86/mm.c)
- vmx_realmode() (in xen/arch/x86/hvm/vmx/realmode.c, indirectly
through realmode_emulate_one() and hvm_emulate_one())
- handle_mmio() (in xen/arch/x86/hvm/io.c, indirectly through

> Since I am not clear completely about the emulation operation performed by 
> Xen, I have following questions with a below mentioned scenario?
> 1) Suppose I have a memory location that I need to protect it from being 
> written by a guest OS. Since a page table protection works at a page level, 
> we have to mark that complete page read-only inside the shadow page table. 
> So, whenever a guest tries to write on that page, writes are propagated to 
> shadow page table. Due to read only page this would create a page-fault and 
> sh_page_fault code would be invoked. In the sh_page_fault code, we can check 
> whether on this page the memory location which is being written (using CR2 
> register) is protected or not. If not, my goal is to let this operation go 
> through. And, I heard here this emulation thing comes into the picture.

Well, sh_page_fault() _may_ be invoked when handling a page fault (if
the shadow page tables are interested in this fault), but the
top-level page fault handler is do_page_fault(). By default the page
fault is propagated to the guest, unless it is "fixed up" by the
hypervisor (because it was a result of page shadowing, writable page
tables writes, mmio emulation or somesuch).

> After checking and deciding this operation should go through, i call "goto 
> emulate" from sh_page_fault code assuming it would emulate that operation and 
> update the eip to the next instruction.

> Question: Is this understanding correct?

As far as I know x86_emulate() is not a full x86 emulator, its only
capable of emulating certain instruction (mostly related to page table
writes) that the hypervisor is interested in. You cannot emulate an
arbitrary instruction with it.
The reason why emulation is used in the first place, is that the
hypervisor write protects certain memory areas (e.g. guest pagetables)
because it wants to know about any changes to these areas (e.g. in
order to update it's shadows). The side effect is that any instruction
that writes to these memory areas must be emulated, as if the extra
write protection wasn't there.

> The reason why I am asking is that since page is write-protected, it means 
> while emulating it should again fault. Then, how does this emulation work? 
> And, what is the use of this function? In what context it should be used and 
> in what context it is invoked from sh_page_fault().

I've already explained what the emulation is for.
The reason why you don't get another page fault when emulating, is
that the hypervisor is capable of mapping any memory page with
arbitrary protection. For example, if the x86_emulate() decides that
it's supposed to emulate a write, it will (most likely) call
hvm_emulate_write() -> sh_x86_emulate_write(). This last function maps
the correct destination memory page by invoking emulate_map_dest()).

> And, if I have to achieve above-mentioned (scenario) functionality which part 
> of the code I should lookinto/change to achieve that.

To tell you the truth I didn't quite get what you want to do, assuming
that you just want to trap writes to certain memory locations you have
two options:
a) write protect first, unprotect in page fault handler if you decide
that the write should go ahead, then restart the write (i.e. return
from the page fault handler). Note that you wouldn't catch further
writes to this memory page, unless you write protected it again
b) write protect, emulate in page fault handler (just as the shadow
code does). It's possible though, that you'll have to extend
x86_emulate, as it is liable to fail for some instructions.


Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.