On 6/22/2016 9:39 PM, Corneliu ZUZU wrote:
On 6/22/2016 8:17 PM, Julien Grall wrote:
On 22/06/16 17:35, Corneliu ZUZU wrote:
Julien,
Hello Corneliu,
I was trying to implement having HCR stored in arch_domain or arch_vcpu
as suggested above and I'm a bit confused about the code in
p2m_restore_state.
I'm hoping you can provide some feedback on this matter. Here's the
current implementation of the function:
void p2m_restore_state(struct vcpu *n)
{
register_t hcr;
hcr = READ_SYSREG(HCR_EL2);
WRITE_SYSREG(hcr & ~HCR_VM, HCR_EL2);
isb();
p2m_load_VTTBR(n->domain);
isb();
if ( is_32bit_domain(n->domain) )
hcr &= ~HCR_RW;
else
hcr |= HCR_RW;
WRITE_SYSREG(n->arch.sctlr, SCTLR_EL1);
isb();
WRITE_SYSREG(hcr, HCR_EL2);
isb();
}
First of all, I see the HCR_VM bit being unset (=0) but I don't quite
understand why and even more peculiar is the fact that I couldn't find
any place where the bit is set (=1) again.
After the first write to HCR_EL2, "hcr" still have the VM bit set as
we only mask it. So the second write will re-set the VM bit.
Ooh..right. Don't know how I missed that, I guess I was too focused in
finding a -different- place where HCR was modified.
I am not sure why the VM bit is unset/set in this function. I am not
able to find a paragraph justifying it in the ARM ARM. I have CCed
some ARM folks to check if I missed something.
An answer to that would be useful. I'm also curious if there's a
reason why HCR_RW is set/unset afterwards and not before and why
there's an isb() after calling p2m_load_VTTBR if that function already
has an isb() @ its end.
Secondly, why this order of operations? More specifically, why is
p2m_load_VTTBR done after the HCR_VM bit is unset and before the HCR_RW
bit is set/unset? Can't we write HCR only once here?
And finally, I see the function is called by construct_dom0. The code
there looks like:
/*
* The following loads use the domain's p2m and require current to
* be a vcpu of the domain, temporarily switch
*/
saved_current = current;
p2m_restore_state(v);
[...]
/* Now that we are done restore the original p2m and current. */
set_current(saved_current);
p2m_restore_state(saved_current);
I suppose the significant changes p2m_restore_state does for the
code in
between ("[...]") is setting VTTBR & SCTLR which are used by
translation
functions such as gvirt_to_maddr (which seems to use PAR_EL1).
What I don't grasp is what effect setting the VTTBR has if
HCR.HCR_VM is
unset and left unset...
HCR.VM is not left unset (see why above).
Regards,
Thanks,
Corneliu.
Julien,
I've also realized that it's a bit complicated to avoid writing HCR from
2 places.
That's because:
- p2m_restore_state is part of the process of switching to another vCPU
and the HCR write _must be committed_ here because other components
depend on that, like address-translation functions
- I want vm_event_vcpu_enter to be called _after_ the switch to the vCPU
is completed
- I want HCR_TVM to be set in vm_event_vcpu_enter because setting
necessary traps _for cr vm-events_ to work should be done there (setting
HCR_TVM bit makes sense to be there and the purpose is to centralize
operations such as this for code comprehensibility; also, on the X86
counterpart a similar operation is done for trapping CR3, so it would be
nice to keep the symmetry)
Would it be such a stretch to have HCR written in 2 places? (the second
time happens rarely anyway: it's unlikely(..) to have to do the write in
vm_event_vcpu_enter)
Regards,
Corneliu.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel