All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.