On 21/12/2018 17:01, Roger Pau Monné wrote:
> On Fri, Dec 21, 2018 at 01:46:05PM +0000, Andrew Cooper wrote:
>> @@ -1091,12 +1091,12 @@ int arch_set_info_guest(
>>      set_bit(_VPF_in_reset, &v->pause_flags);
>>  
>>      if ( !compat )
>> -        cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]);
>> +        cr3_mfn = _mfn(xen_cr3_to_pfn(c.nat->ctrlreg[3]));
>>      else
>> -        cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
>> -    cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
>> +        cr3_mfn = _mfn(compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
>>  
>> -    if ( !cr3_page )
>> +    if ( !mfn_valid(cr3_mfn) ||
>> +         !(cr3_page = mfn_to_page(cr3_mfn), get_page(cr3_page, d)) )
> This is kind of an open-coded version of get_page_from_gfn with just
> the non-paging bits, IMO I would use get_page_from_gfn, or introduce a
> get_page_from_mfn helper?

Turns out that we already have one of those.  I'll tweak it for purpose
and use it.

>
> The more that you use the same construct below.
>
>>          rc = -EINVAL;
>>      else if ( paging_mode_refcounts(d) )
>>          /* nothing */;
>> @@ -1122,7 +1122,7 @@ int arch_set_info_guest(
>>          case 0:
>>              if ( !compat && !VM_ASSIST(d, m2p_strict) &&
>>                   !paging_mode_refcounts(d) )
>> -                fill_ro_mpt(_mfn(cr3_gfn));
>> +                fill_ro_mpt(cr3_mfn);
>>              break;
>>          default:
>>              if ( cr3_page == current->arch.old_guest_table )
>> @@ -1137,10 +1137,10 @@ int arch_set_info_guest(
>>          v->arch.guest_table = pagetable_from_page(cr3_page);
>>          if ( c.nat->ctrlreg[1] )
>>          {
>> -            cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[1]);
>> -            cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
>> +            cr3_mfn = _mfn(xen_cr3_to_pfn(c.nat->ctrlreg[1]));
> I assume this is something PV specific, but calling xen_cr3_to_pfn on
> ctrlreg[1] seems wrong at first sight. And the xen_cr3_to_pfn and
> xen_pfn_to_cr3 helpers seem quite pointless, since it's just PFN_DOWN
> or pfn_to_paddr.

It is one of the more peculiar pieces of PV magic.

For reasons best explained by whomever wrote the code, the 64bit ABI,
having separate kernel and user %cr3's, stashes the user %cr3 in ctrlreg[1].

This code is correct, but I do accept that it is very confusing to read
without knowing the PV ABI inside out.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Reply via email to