* RIP register value in p2m_mem_access_check()
@ 2013-03-06 10:55 Razvan Cojocaru
2013-03-06 11:15 ` Jan Beulich
0 siblings, 1 reply; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 10:55 UTC (permalink / raw)
To: xen-devel@lists.xen.org
Hello again,
simple test case: added the following statement in
xen/arch/x86/mm/p2m.c, in function p2m_mem_access_check():
printk("v->arch.user_regs.eip: 0x%016lx, __vmread(GUEST_RIP):
0x%016lx\n", v->arch.user_regs.eip, __vmread(GUEST_RIP));
(where v is current) which dutifully prints out (at the first page fault):
(XEN) v->arch.user_regs.eip: 0xfffff80002c13a7b, __vmread(GUEST_RIP):
0xfffff8000269ec0a
They're not equal, and furthermore __vmread(GUEST_RIP) is the correct
one (the same value returned by xc_domain_hvm_getcontext_partial()).
The questions:
1. What's the Xen-friendliest way to retrieve the _correct_ values for
RIP and all the other registers usually put in a struct hvm_hw_cpu
instance, in p2m_mem_access_check()?
2. What's the explanation for why things run as they do now?
Thanks,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 10:55 RIP register value in p2m_mem_access_check() Razvan Cojocaru
@ 2013-03-06 11:15 ` Jan Beulich
2013-03-06 11:35 ` Razvan Cojocaru
0 siblings, 1 reply; 12+ messages in thread
From: Jan Beulich @ 2013-03-06 11:15 UTC (permalink / raw)
To: Razvan Cojocaru; +Cc: xen-devel@lists.xen.org
>>> On 06.03.13 at 11:55, Razvan Cojocaru <rzvncj@gmail.com> wrote:
> Hello again,
>
> simple test case: added the following statement in
> xen/arch/x86/mm/p2m.c, in function p2m_mem_access_check():
>
> printk("v->arch.user_regs.eip: 0x%016lx, __vmread(GUEST_RIP):
> 0x%016lx\n", v->arch.user_regs.eip, __vmread(GUEST_RIP));
>
> (where v is current) which dutifully prints out (at the first page fault):
>
> (XEN) v->arch.user_regs.eip: 0xfffff80002c13a7b, __vmread(GUEST_RIP):
> 0xfffff8000269ec0a
>
> They're not equal, and furthermore __vmread(GUEST_RIP) is the correct
> one (the same value returned by xc_domain_hvm_getcontext_partial()).
>
> The questions:
>
> 1. What's the Xen-friendliest way to retrieve the _correct_ values for
> RIP and all the other registers usually put in a struct hvm_hw_cpu
> instance, in p2m_mem_access_check()?
v->arch.user_regs.eip is what you should look at. It's
expected to be in sync with the VMCS value as long as
nothing (e.g. emulation) modified the value. There's code in
vmx_asm_vmexit_handler to sync the fields, and in
vmx_asm_do_vmentry to sync them back in the opposite
direction.
> 2. What's the explanation for why things run as they do now?
If the above doesn't work, you're likely in bigger trouble. So
you will want to hunt down why the user_regs field isn't what
you expect it to be.
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 11:15 ` Jan Beulich
@ 2013-03-06 11:35 ` Razvan Cojocaru
2013-03-06 13:22 ` Jan Beulich
0 siblings, 1 reply; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 11:35 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel@lists.xen.org
> v->arch.user_regs.eip is what you should look at. It's
> expected to be in sync with the VMCS value as long as
> nothing (e.g. emulation) modified the value. There's code in
> vmx_asm_vmexit_handler to sync the fields, and in
> vmx_asm_do_vmentry to sync them back in the opposite
> direction.
Thank you for your answer. Isn't it possible that emulation is indeed
involved, since in p2m_mem_access_check() a page fault has occured, and
RIP might point to _after_ the offending instruction?
Thanks,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 11:35 ` Razvan Cojocaru
@ 2013-03-06 13:22 ` Jan Beulich
2013-03-06 13:25 ` Razvan Cojocaru
2013-03-06 13:49 ` Razvan Cojocaru
0 siblings, 2 replies; 12+ messages in thread
From: Jan Beulich @ 2013-03-06 13:22 UTC (permalink / raw)
To: Razvan Cojocaru; +Cc: xen-devel@lists.xen.org
>>> On 06.03.13 at 12:35, Razvan Cojocaru <rzvncj@gmail.com> wrote:
>> v->arch.user_regs.eip is what you should look at. It's
>> expected to be in sync with the VMCS value as long as
>> nothing (e.g. emulation) modified the value. There's code in
>> vmx_asm_vmexit_handler to sync the fields, and in
>> vmx_asm_do_vmentry to sync them back in the opposite
>> direction.
>
> Thank you for your answer. Isn't it possible that emulation is indeed
> involved, since in p2m_mem_access_check() a page fault has occured, and
> RIP might point to _after_ the offending instruction?
That wouldn't match your observation (the two values were
much farther apart), unless a call or jump got emulated.
Further, after emulation, the user_regs.eip value should be the
canonical one.
And finally, you said you took this right after a page fault
occurred, and - just like for any fault - the RIP the fault refers
to is the faulting instruction, not the one following it.
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 13:22 ` Jan Beulich
@ 2013-03-06 13:25 ` Razvan Cojocaru
2013-03-06 13:49 ` Razvan Cojocaru
1 sibling, 0 replies; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 13:25 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel@lists.xen.org
>> Thank you for your answer. Isn't it possible that emulation is indeed
>> involved, since in p2m_mem_access_check() a page fault has occured, and
>> RIP might point to _after_ the offending instruction?
>
> That wouldn't match your observation (the two values were
> much farther apart), unless a call or jump got emulated.
I've noticed that, and have indeed assumed that it was something like a
call.
> Further, after emulation, the user_regs.eip value should be the
> canonical one.
>
> And finally, you said you took this right after a page fault
> occurred, and - just like for any fault - the RIP the fault refers
> to is the faulting instruction, not the one following it.
Fair enough. Will debug the issue.
Thanks,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 13:22 ` Jan Beulich
2013-03-06 13:25 ` Razvan Cojocaru
@ 2013-03-06 13:49 ` Razvan Cojocaru
2013-03-06 14:26 ` Razvan Cojocaru
2013-03-06 14:33 ` Jan Beulich
1 sibling, 2 replies; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 13:49 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel@lists.xen.org
> That wouldn't match your observation (the two values were
> much farther apart), unless a call or jump got emulated.
>
> Further, after emulation, the user_regs.eip value should be the
> canonical one.
Well, I've downloaded and installed a fresh copy of Xen 4.2.0 from the
official website, and added the printk() to p2m.c (the only modification
I've done):
1311 req->vcpu_id = v->vcpu_id;
1312
1313 printk("v->arch.user_regs.eip: 0x%016lx,
__vmread(GUEST_RIP):0x%016lx\n",
1314 v->arch.user_regs.eip, __vmread(GUEST_RIP));
1315 }
I then launched my guest VM, and tested it with the xen-access tool from
tools/tests/xen-access, which I've run like this (1 is the machine ID,
as printed out by 'sudo xm list'):
sudo ./xen-access 1 write
Here's what the hypervisor wrote (values that are different appear once
per each VCPU):
(XEN) HVM1: Booting from 0000:7c00
(XEN) v->arch.user_regs.eip: 0x00000000fc002de9,
__vmread(GUEST_RIP):0x0000000000007c17
(XEN) v->arch.user_regs.eip: 0x0000000000007c17,
__vmread(GUEST_RIP):0x0000000000000667
(XEN) v->arch.user_regs.eip: 0x0000000000000667,
__vmread(GUEST_RIP):0x0000000000000116
(XEN) v->arch.user_regs.eip: 0x0000000000000116,
__vmread(GUEST_RIP):0x0000000000000116
(XEN) v->arch.user_regs.eip: 0x0000000000000116,
__vmread(GUEST_RIP):0x00000000000005ab
(XEN) v->arch.user_regs.eip: 0x00000000000005ab,
__vmread(GUEST_RIP):0x00000000000001e7
(XEN) v->arch.user_regs.eip: 0x00000000000001e7,
__vmread(GUEST_RIP):0x00000000000001f3
(XEN) v->arch.user_regs.eip: 0x00000000000001f3,
__vmread(GUEST_RIP):0x0000000000000b71
(XEN) v->arch.user_regs.eip: 0x0000000000000b71,
__vmread(GUEST_RIP):0x0000000000000782
(XEN) v->arch.user_regs.eip: 0x0000000000000782,
__vmread(GUEST_RIP):0x0000000000000782
(XEN) v->arch.user_regs.eip: 0x0000000000000782,
__vmread(GUEST_RIP):0x0000000000000782
Not sure what's going on, but this time the only code I've added is the
printk(). Any thoughts?
Thanks,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 13:49 ` Razvan Cojocaru
@ 2013-03-06 14:26 ` Razvan Cojocaru
2013-03-06 14:33 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 14:26 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel@lists.xen.org
Furthermore (with the fresh install of Xen 4.2.0), when modifying
xen-access.c to fetch the registers and print RIP out:
624 case MEM_EVENT_REASON_VIOLATION:
625 {
626 struct hvm_hw_cpu hwcpu;
627
628 if (xc_domain_hvm_getcontext_partial(xch, domain_id,
HVM_SAVE_CODE(CPU),
629 req.vcpu_id, &hwcpu,
sizeof(hwcpu)) != 0)
630 {
631 ERROR("xc_domain_hvm_getcontext_partial()
failed\n");
632 interrupted = -1;
633 continue;
634 }
635
636 printf("RIP: 0x%016lx\n", hwCpu.rip);
637 fflush(stdout);
the RIP it prints out is always the __vmread(GUEST_RIP), not
v->arch.user_regs.eip:
xen-access output:
Got event from Xen
RIP: 0x0000000000003272
Got event from Xen
PAGE ACCESS: -w- for GFN 25 (offset 0001ba) gla 00000000000251ba (vcpu 0)
RIP: 0x000000000000fed9
Got event from Xen
PAGE ACCESS: -w- for GFN 0 (offset 00046c) gla 000000000000046c (vcpu 0)
RIP: 0x0000000000000643
Got event from Xen
PAGE ACCESS: -w- for GFN 9f (offset 000e54) gla 000000000009fe54 (vcpu 0)
RIP: 0x0000000000000643
Got event from Xen
PAGE ACCESS: -w- for GFN 32 (offset 000042) gla 0000000000032042 (vcpu 0)
RIP: 0x000000000000009b
Got event from Xen
PAGE ACCESS: -w- for GFN 9a (offset 0003d9) gla 000000000009a3d9 (vcpu 0)
RIP: 0x0000000000000269
corresponding hypervisor log:
(XEN) v->arch.user_regs.eip: 0x0000000000003272,
__vmread(GUEST_RIP):0x0000000000003272
(XEN) v->arch.user_regs.eip: 0x0000000000003272,
__vmread(GUEST_RIP):0x000000000000fed9
(XEN) v->arch.user_regs.eip: 0x000000000000fed9,
__vmread(GUEST_RIP):0x0000000000000643
(XEN) v->arch.user_regs.eip: 0x0000000000000643,
__vmread(GUEST_RIP):0x0000000000000643
(XEN) v->arch.user_regs.eip: 0x0000000000000643,
__vmread(GUEST_RIP):0x000000000000009b
(XEN) v->arch.user_regs.eip: 0x000000000000009b,
__vmread(GUEST_RIP):0x0000000000000269
Hope this helps,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 13:49 ` Razvan Cojocaru
2013-03-06 14:26 ` Razvan Cojocaru
@ 2013-03-06 14:33 ` Jan Beulich
2013-03-06 14:47 ` Razvan Cojocaru
2013-03-07 16:49 ` Tim Deegan
1 sibling, 2 replies; 12+ messages in thread
From: Jan Beulich @ 2013-03-06 14:33 UTC (permalink / raw)
To: Razvan Cojocaru; +Cc: xen-devel@lists.xen.org
>>> On 06.03.13 at 14:49, Razvan Cojocaru <rzvncj@gmail.com> wrote:
>> That wouldn't match your observation (the two values were
>> much farther apart), unless a call or jump got emulated.
>>
>> Further, after emulation, the user_regs.eip value should be the
>> canonical one.
>
> Well, I've downloaded and installed a fresh copy of Xen 4.2.0 from the
> official website, and added the printk() to p2m.c (the only modification
> I've done):
>
> 1311 req->vcpu_id = v->vcpu_id;
> 1312
> 1313 printk("v->arch.user_regs.eip: 0x%016lx,
> __vmread(GUEST_RIP):0x%016lx\n",
> 1314 v->arch.user_regs.eip, __vmread(GUEST_RIP));
> 1315 }
I know close to nothing about the paths that can lead here, and
hence I can't assess whether expecting consistency at this point
is valid. All I can tell is that right after VM exit (i.e. at the top of
vmx_vmexit_handler()) the two values ought to be consistent.
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 14:33 ` Jan Beulich
@ 2013-03-06 14:47 ` Razvan Cojocaru
2013-03-07 16:49 ` Tim Deegan
1 sibling, 0 replies; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-06 14:47 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel@lists.xen.org
> I know close to nothing about the paths that can lead here, and
> hence I can't assess whether expecting consistency at this point
> is valid. All I can tell is that right after VM exit (i.e. at the top of
> vmx_vmexit_handler()) the two values ought to be consistent.
Yes, that's true, however what I'm after is a way to have the
information associated with the proper RIP _before_ the VM exit
(basically all of the information that gets stuffed into the struct
hvm_hw_cpu instance by xc_domain_hvm_getcontext_partial()).
Specifically, I want that information inside p2m_mem_access_check().
Thanks for your help,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-06 14:33 ` Jan Beulich
2013-03-06 14:47 ` Razvan Cojocaru
@ 2013-03-07 16:49 ` Tim Deegan
2013-03-07 17:04 ` Jan Beulich
2013-03-07 17:31 ` Razvan Cojocaru
1 sibling, 2 replies; 12+ messages in thread
From: Tim Deegan @ 2013-03-07 16:49 UTC (permalink / raw)
To: Jan Beulich; +Cc: Razvan Cojocaru, xen-devel@lists.xen.org
At 14:33 +0000 on 06 Mar (1362580383), Jan Beulich wrote:
> >>> On 06.03.13 at 14:49, Razvan Cojocaru <rzvncj@gmail.com> wrote:
> >> That wouldn't match your observation (the two values were
> >> much farther apart), unless a call or jump got emulated.
> >>
> >> Further, after emulation, the user_regs.eip value should be the
> >> canonical one.
> >
> > Well, I've downloaded and installed a fresh copy of Xen 4.2.0 from the
> > official website, and added the printk() to p2m.c (the only modification
> > I've done):
> >
> > 1311 req->vcpu_id = v->vcpu_id;
> > 1312
> > 1313 printk("v->arch.user_regs.eip: 0x%016lx,
> > __vmread(GUEST_RIP):0x%016lx\n",
> > 1314 v->arch.user_regs.eip, __vmread(GUEST_RIP));
> > 1315 }
>
> I know close to nothing about the paths that can lead here, and
> hence I can't assess whether expecting consistency at this point
> is valid. All I can tell is that right after VM exit (i.e. at the top of
> vmx_vmexit_handler()) the two values ought to be consistent.
I don't think so -- v->arch.user_regs is only brought up to date during
context switches. For the currently running vcpu you should be looking
at guest_cpu_user_regs().
Cheers,
Tim.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-07 16:49 ` Tim Deegan
@ 2013-03-07 17:04 ` Jan Beulich
2013-03-07 17:31 ` Razvan Cojocaru
1 sibling, 0 replies; 12+ messages in thread
From: Jan Beulich @ 2013-03-07 17:04 UTC (permalink / raw)
To: Tim Deegan; +Cc: Razvan Cojocaru, xen-devel@lists.xen.org
>>> On 07.03.13 at 17:49, Tim Deegan <tim@xen.org> wrote:
> At 14:33 +0000 on 06 Mar (1362580383), Jan Beulich wrote:
>> >>> On 06.03.13 at 14:49, Razvan Cojocaru <rzvncj@gmail.com> wrote:
>> >> That wouldn't match your observation (the two values were
>> >> much farther apart), unless a call or jump got emulated.
>> >>
>> >> Further, after emulation, the user_regs.eip value should be the
>> >> canonical one.
>> >
>> > Well, I've downloaded and installed a fresh copy of Xen 4.2.0 from the
>> > official website, and added the printk() to p2m.c (the only modification
>> > I've done):
>> >
>> > 1311 req->vcpu_id = v->vcpu_id;
>> > 1312
>> > 1313 printk("v->arch.user_regs.eip: 0x%016lx,
>> > __vmread(GUEST_RIP):0x%016lx\n",
>> > 1314 v->arch.user_regs.eip, __vmread(GUEST_RIP));
>> > 1315 }
>>
>> I know close to nothing about the paths that can lead here, and
>> hence I can't assess whether expecting consistency at this point
>> is valid. All I can tell is that right after VM exit (i.e. at the top of
>> vmx_vmexit_handler()) the two values ought to be consistent.
>
> I don't think so -- v->arch.user_regs is only brought up to date during
> context switches. For the currently running vcpu you should be looking
> at guest_cpu_user_regs().
Oh, of course, yes - I was mixing them up quite badly. Sorry
for that.
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RIP register value in p2m_mem_access_check()
2013-03-07 16:49 ` Tim Deegan
2013-03-07 17:04 ` Jan Beulich
@ 2013-03-07 17:31 ` Razvan Cojocaru
1 sibling, 0 replies; 12+ messages in thread
From: Razvan Cojocaru @ 2013-03-07 17:31 UTC (permalink / raw)
To: Tim Deegan; +Cc: Jan Beulich, xen-devel@lists.xen.org
> I don't think so -- v->arch.user_regs is only brought up to date during
> context switches. For the currently running vcpu you should be looking
> at guest_cpu_user_regs().
Yes, that's what did it - I discovered that a few hours earlier and
wanted to post the solution but you beat me to it :)
Thanks,
Razvan Cojocaru
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-03-07 17:31 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-06 10:55 RIP register value in p2m_mem_access_check() Razvan Cojocaru
2013-03-06 11:15 ` Jan Beulich
2013-03-06 11:35 ` Razvan Cojocaru
2013-03-06 13:22 ` Jan Beulich
2013-03-06 13:25 ` Razvan Cojocaru
2013-03-06 13:49 ` Razvan Cojocaru
2013-03-06 14:26 ` Razvan Cojocaru
2013-03-06 14:33 ` Jan Beulich
2013-03-06 14:47 ` Razvan Cojocaru
2013-03-07 16:49 ` Tim Deegan
2013-03-07 17:04 ` Jan Beulich
2013-03-07 17:31 ` Razvan Cojocaru
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.