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

Re: [Xen-devel] [PATCH RFC v2 1/4] x86/mm: Shadow and p2m changes for PV mem_access



On 22/08/14 20:07, Aravindh Puthiyaparambil (aravindp) wrote:
>>> I have a solution for the create_bounc_frame() issue I described above.
>>> Please find below a POC patch that includes pausing and unpausing the
>>> domain during the Xen writes to guest memory. I have it on top of the
>>> patch that was using CR0.WP to highlight the difference. Please take a
>>> look and let me know if this solution is acceptable.
>> As Andrew already pointed out, you absolutely need to deal with page
>> crossing accesses, 
> Is this for say an unsigned long that lives across two pages? Off the top of 
> my head, I think always allowing writes to the page in question and the next 
> followed by reverting to default for both pages at the end of the write 
> should take care of this. I would have to walk the page tables to figure out 
> the next mfn. Or am I on the wrong track here?

create_bounce_frame puts several adjacent words on a guest stack, and
this is very capable of crossing a page boundary.

Even an unaligned uint16_t can cross a page boundary.

>
>> and I think you also need to deal with hypervisor accesses
>> extending beyond a page worth of memory (I'm not sure we have a firmly
>> determined upper bound of how much memory we may copy in one go).
> Let me try to understand what happens in the non-mem_access case. Say the 
> hypervisor is writing to three pages and all of them are not accessible in 
> the guest. Which one of the following is true?
> 1. There is a pagefault for the first page which is resolved. The write is 
> then retried which causes a fault for the second page which is resolved. Then 
> the write is retried starting from the second page and so on for the third 
> page too.
> 2. Or does the write get retried starting from the first page each time the 
> page fault is resolved?

For the non-mem_access case, all faults cause failures.

copy_to/from_user() will typically result in an -EFAULT being handed
back to the hypercaller.  For create_bounce_frame, the results are more
severe and might result in a domain crash or an injection of a failsafe
callback.

No attempt is made to play with the page permissions, as it is the
guests fault that the pages have the wrong permissions.

What mem_access introduces is a case where it is Xen's fault that a
write fault occured, and the fault should be worked around as the guest
is unaware that its pages are actually read-only.

>>>              if ( violation && access_w &&
>>>                   regs->eip >= XEN_VIRT_START && regs->eip <= XEN_VIRT_END )
>>>              {
>>> -                unsigned long cr0 = read_cr0();
>>> -
>>>                  violation = 0;
>>> -                if ( cr0 & X86_CR0_WP &&
>>> -                     guest_l1e_get_flags(gw.l1e) & _PAGE_RW )
>>> +                if ( guest_l1e_get_flags(gw.l1e) & _PAGE_RW )
>>>                  {
>>> -                    cr0 &= ~X86_CR0_WP;
>>> -                    write_cr0(cr0);
>>> -                    v->arch.pv_vcpu.need_cr0_wp_set = 1;
>>> +                    domain_pause_nosync(d);
>> I don't think a "nosync" pause is enough here, as that leaves a window for 
>> the
>> guest to write to the page. Since the sync version may take some time to
>> complete it may become difficult for you to actually handle this in an
>> acceptable way.
> Are you worried about performance or is there some other issue? 

Both performance and correctness.  With nosync(), guest vcpus can still
be running on other pcpus, and playing with this pagetable entry.

The synchronous variants can block for a moderate period of time.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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