All of lore.kernel.org
 help / color / mirror / Atom feed
* [SVM] Getting the length of the current instruction in svm_vmexit_handler()
@ 2018-03-14 14:56 Razvan Cojocaru
  2018-03-14 15:53 ` Jan Beulich
  0 siblings, 1 reply; 6+ messages in thread
From: Razvan Cojocaru @ 2018-03-14 14:56 UTC (permalink / raw)
  To: xen-devel
  Cc: Alexandru Isaila, Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Hello,

We'd like to retrieve the length of the current instruction in
svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
VMEXIT_EXCEPTION_BP cases.

We've combed the vmcb to no avail. Everything we've thought to check
(exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
testing.

There's __get_instruction_length(vcpu, instr), but it expects to be fed
the exact instruction we want the length for, which obviously defeats
the purpose here.

Is there a clean way to get the current instruction length like we do in
the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
overlooking?


Thanks,
Razvan

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [SVM] Getting the length of the current instruction in svm_vmexit_handler()
  2018-03-14 14:56 [SVM] Getting the length of the current instruction in svm_vmexit_handler() Razvan Cojocaru
@ 2018-03-14 15:53 ` Jan Beulich
  2018-03-14 17:06   ` Andrew Cooper
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2018-03-14 15:53 UTC (permalink / raw)
  To: Razvan Cojocaru
  Cc: Alexandru Isaila, Andrew Cooper, Boris Ostrovsky,
	Suravee Suthikulpanit, xen-devel

>>> On 14.03.18 at 15:56, <rcojocaru@bitdefender.com> wrote:
> We'd like to retrieve the length of the current instruction in
> svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
> VMEXIT_EXCEPTION_BP cases.
> 
> We've combed the vmcb to no avail. Everything we've thought to check
> (exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
> testing.
> 
> There's __get_instruction_length(vcpu, instr), but it expects to be fed
> the exact instruction we want the length for, which obviously defeats
> the purpose here.
> 
> Is there a clean way to get the current instruction length like we do in
> the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
> overlooking?

Just like Intel's, AMD's is available in a subset of cases only
(look for vmcb->guest_ins_len), which don't include the
exception intercepts you talk about. For #DB I think there's
no difference between both anyway.

Jan


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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [SVM] Getting the length of the current instruction in svm_vmexit_handler()
  2018-03-14 15:53 ` Jan Beulich
@ 2018-03-14 17:06   ` Andrew Cooper
  2018-03-17 21:11     ` Razvan Cojocaru
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Cooper @ 2018-03-14 17:06 UTC (permalink / raw)
  To: Jan Beulich, Razvan Cojocaru
  Cc: Alexandru Isaila, xen-devel, Boris Ostrovsky, Suravee Suthikulpanit

On 14/03/18 15:53, Jan Beulich wrote:
>>>> On 14.03.18 at 15:56, <rcojocaru@bitdefender.com> wrote:
>> We'd like to retrieve the length of the current instruction in
>> svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
>> VMEXIT_EXCEPTION_BP cases.
>>
>> We've combed the vmcb to no avail. Everything we've thought to check
>> (exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
>> testing.
>>
>> There's __get_instruction_length(vcpu, instr), but it expects to be fed
>> the exact instruction we want the length for, which obviously defeats
>> the purpose here.
>>
>> Is there a clean way to get the current instruction length like we do in
>> the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
>> overlooking?
> Just like Intel's, AMD's is available in a subset of cases only
> (look for vmcb->guest_ins_len), which don't include the
> exception intercepts you talk about. For #DB I think there's
> no difference between both anyway.

On non-first-gen hardware, the difference between RIP and NextRIP should
give you the instruction length.  ISTR NextRIP is written on all exits,
and consumed on all entries.

~Andrew

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [SVM] Getting the length of the current instruction in svm_vmexit_handler()
  2018-03-14 17:06   ` Andrew Cooper
@ 2018-03-17 21:11     ` Razvan Cojocaru
  2018-03-17 21:45       ` Andrew Cooper
  0 siblings, 1 reply; 6+ messages in thread
From: Razvan Cojocaru @ 2018-03-17 21:11 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich
  Cc: Alexandru Isaila, xen-devel, Boris Ostrovsky, Suravee Suthikulpanit

On 03/14/2018 07:06 PM, Andrew Cooper wrote:
> On 14/03/18 15:53, Jan Beulich wrote:
>>>>> On 14.03.18 at 15:56, <rcojocaru@bitdefender.com> wrote:
>>> We'd like to retrieve the length of the current instruction in
>>> svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
>>> VMEXIT_EXCEPTION_BP cases.
>>>
>>> We've combed the vmcb to no avail. Everything we've thought to check
>>> (exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
>>> testing.
>>>
>>> There's __get_instruction_length(vcpu, instr), but it expects to be fed
>>> the exact instruction we want the length for, which obviously defeats
>>> the purpose here.
>>>
>>> Is there a clean way to get the current instruction length like we do in
>>> the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
>>> overlooking?
>> Just like Intel's, AMD's is available in a subset of cases only
>> (look for vmcb->guest_ins_len), which don't include the
>> exception intercepts you talk about. For #DB I think there's
>> no difference between both anyway.
> 
> On non-first-gen hardware, the difference between RIP and NextRIP should
> give you the instruction length.  ISTR NextRIP is written on all exits,
> and consumed on all entries.

Thanks!

vmcb->nextrip - vmcb->rip seems to work well for the instruction length.

Shouldn't vmcb->exitintinfo also be filled in properly on SVM? I'm
getting this on VMEXIT_EXCEPTION_BP:

(XEN) Dumping guest's current state at svm_vmexit_handler...
(XEN) Size of VMCB = 4096, paddr = 0000000c1cc7e000, vaddr =
ffff830c1cc7e000
(XEN) cr_intercepts = 0xfef3fef3 dr_intercepts = 0xffffffff
exception_intercepts = 0x6000a
(XEN) general1_intercepts = 0xbdc4000f general2_intercepts = 0x2f7f
(XEN) iopm_base_pa = 0xdbf79000 msrpm_base_pa = 0xc1cc7c000 tsc_offset =
0xffffffa40f20290d
(XEN) tlb_control = 0 vintr = 0x1000000 interrupt_shadow = 0
(XEN) eventinj 0000000000000000, valid? 0, ec? 0, type 0, vector 0
(XEN) exitcode = 0x43 exitintinfo = 0
(XEN) exitinfo1 = 0 exitinfo2 = 0
(XEN) np_enable = 0x1 guest_asid = 0x4
(XEN) virtual vmload/vmsave = 0, virt_ext = 0
(XEN) cpl = 0 efer = 0x1500 star = 0 lstar = 0
(XEN) CR0 = 0x0000000080010011 CR2 = 0x0000000000000000
(XEN) CR3 = 0x000000000010d000 CR4 = 0x0000000000000060
(XEN) RSP = 0x000000000011afa8  RIP = 0x0000000000104b01
(XEN) RAX = 0x0000000000104b02  RFLAGS=0x0000000000000046
(XEN) DR6 = 0x0000000000000000, DR7 = 0x0000000000000000
(XEN) CSTAR = 0x0000000000000000 SFMask = 0x0000000000000000
(XEN) KernGSBase = 0x0000000000000000 PAT = 0x0007040600070406
(XEN) H_CR3 = 0x00000003b912a000 CleanBits = 0xffffffff
(XEN)        sel attr  limit   base
(XEN)   CS: 0008 029b ffffffff 0000000000000000
(XEN)   DS: 0033 0cf3 ffffffff 0000000000000000
(XEN)   SS: 0000 0400 ffffffff 0000000000000000
(XEN)   ES: 0033 0cf3 ffffffff 0000000000000000
(XEN)   FS: 0000 0000 00000000 0000000000000000
(XEN)   GS: 0000 0000 00000000 0000000000000000
(XEN) GDTR: 0000 0000 00000077 00000000001060c0
(XEN) LDTR: 0000 0000 00000000 0000000000000000
(XEN) IDTR: 0000 0000 00000fff 0000000000115900
(XEN)   TR: 0000 008b 00000067 0000000000000000

and this on (newly added for testing purposes) VMEXIT_ICEBP:

(XEN) Dumping guest's current state at svm_vmexit_handler...
(XEN) Size of VMCB = 4096, paddr = 0000000c1cc7e000, vaddr =
ffff830c1cc7e000
(XEN) cr_intercepts = 0xfef3fef3 dr_intercepts = 0xffffffff
exception_intercepts = 0x6000a
(XEN) general1_intercepts = 0xbdc4000f general2_intercepts = 0x2f7f
(XEN) iopm_base_pa = 0xdbf79000 msrpm_base_pa = 0xc1cc7c000 tsc_offset =
0xffffffa40f20290d
(XEN) tlb_control = 0 vintr = 0x1000000 interrupt_shadow = 0
(XEN) eventinj 0000000000000000, valid? 0, ec? 0, type 0, vector 0
(XEN) exitcode = 0x88 exitintinfo = 0
(XEN) exitinfo1 = 0 exitinfo2 = 0
(XEN) np_enable = 0x1 guest_asid = 0x4
(XEN) virtual vmload/vmsave = 0, virt_ext = 0
(XEN) cpl = 0 efer = 0x1500 star = 0 lstar = 0
(XEN) CR0 = 0x0000000080010011 CR2 = 0x0000000000000000
(XEN) CR3 = 0x000000000010d000 CR4 = 0x0000000000000060
(XEN) RSP = 0x000000000011afa8  RIP = 0x0000000000104b81
(XEN) RAX = 0x0000000000104b82  RFLAGS=0x0000000000000046
(XEN) DR6 = 0x0000000000000000, DR7 = 0x0000000000000000
(XEN) CSTAR = 0x0000000000000000 SFMask = 0x0000000000000000
(XEN) KernGSBase = 0x0000000000000000 PAT = 0x0007040600070406
(XEN) H_CR3 = 0x00000003b912a000 CleanBits = 0xffffffff
(XEN)        sel attr  limit   base
(XEN)   CS: 0008 029b ffffffff 0000000000000000
(XEN)   DS: 0033 0cf3 ffffffff 0000000000000000
(XEN)   SS: 0000 0400 ffffffff 0000000000000000
(XEN)   ES: 0033 0cf3 ffffffff 0000000000000000
(XEN)   FS: 0000 0000 00000000 0000000000000000
(XEN)   GS: 0000 0000 00000000 0000000000000000
(XEN) GDTR: 0000 0000 00000077 00000000001060c0
(XEN) LDTR: 0000 0000 00000000 0000000000000000
(XEN) IDTR: 0000 0000 00000fff 0000000000115900
(XEN)   TR: 0000 008b 00000067 0000000000000000

Not a lot of useful information there.


Thanks,
Razvan

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [SVM] Getting the length of the current instruction in svm_vmexit_handler()
  2018-03-17 21:11     ` Razvan Cojocaru
@ 2018-03-17 21:45       ` Andrew Cooper
  2018-03-17 22:08         ` Razvan Cojocaru
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Cooper @ 2018-03-17 21:45 UTC (permalink / raw)
  To: Razvan Cojocaru, Jan Beulich
  Cc: Alexandru Isaila, xen-devel, Boris Ostrovsky, Suravee Suthikulpanit

On 17/03/18 21:11, Razvan Cojocaru wrote:
> On 03/14/2018 07:06 PM, Andrew Cooper wrote:
>> On 14/03/18 15:53, Jan Beulich wrote:
>>>>>> On 14.03.18 at 15:56, <rcojocaru@bitdefender.com> wrote:
>>>> We'd like to retrieve the length of the current instruction in
>>>> svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
>>>> VMEXIT_EXCEPTION_BP cases.
>>>>
>>>> We've combed the vmcb to no avail. Everything we've thought to check
>>>> (exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
>>>> testing.
>>>>
>>>> There's __get_instruction_length(vcpu, instr), but it expects to be fed
>>>> the exact instruction we want the length for, which obviously defeats
>>>> the purpose here.
>>>>
>>>> Is there a clean way to get the current instruction length like we do in
>>>> the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
>>>> overlooking?
>>> Just like Intel's, AMD's is available in a subset of cases only
>>> (look for vmcb->guest_ins_len), which don't include the
>>> exception intercepts you talk about. For #DB I think there's
>>> no difference between both anyway.
>> On non-first-gen hardware, the difference between RIP and NextRIP should
>> give you the instruction length.  ISTR NextRIP is written on all exits,
>> and consumed on all entries.
> Thanks!
>
> vmcb->nextrip - vmcb->rip seems to work well for the instruction length.

Turns out I was wrong.

From 15.7.1 "State Saved on Exit":
> The next sequential instruction pointer (nRIP) is saved in the guest
> VMCB control area at location C8h
> on all #VMEXITs that are due to instruction intercepts, as defined in
> Section 15.9 on page 461, as well
> as MSR and IOIO intercepts and exceptions caused by the INT3, INTO,
> and BOUND instructions. For
> all other intercepts, nRIP is reset to zero.

On 17/03/18 21:11, Razvan Cojocaru wrote:
>
> Shouldn't vmcb->exitintinfo also be filled in properly on SVM? I'm
> getting this on VMEXIT_EXCEPTION_BP:

No.  The manual says not.  From 15.12.4 "#BP (Breakpoint)":

> This intercept applies to the trap raised by the single byte INT3
> (opcode CCh) instruction. The
> EXITINFO1 and EXITINFO2 fields are undefined. The CS:rIP reported on
> #VMEXIT are those of
> the INT3 instruction.

What other information are you trying to derive when intercepting #BP?

~Andrew

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [SVM] Getting the length of the current instruction in svm_vmexit_handler()
  2018-03-17 21:45       ` Andrew Cooper
@ 2018-03-17 22:08         ` Razvan Cojocaru
  0 siblings, 0 replies; 6+ messages in thread
From: Razvan Cojocaru @ 2018-03-17 22:08 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich
  Cc: Alexandru Isaila, xen-devel, Boris Ostrovsky, Suravee Suthikulpanit

On 03/17/2018 11:45 PM, Andrew Cooper wrote:
> On 17/03/18 21:11, Razvan Cojocaru wrote:
>> On 03/14/2018 07:06 PM, Andrew Cooper wrote:
>>> On 14/03/18 15:53, Jan Beulich wrote:
>>>>>>> On 14.03.18 at 15:56, <rcojocaru@bitdefender.com> wrote:
>>>>> We'd like to retrieve the length of the current instruction in
>>>>> svm_vmexit_handler(), specifically for the VMEXIT_EXCEPTION_DB and
>>>>> VMEXIT_EXCEPTION_BP cases.
>>>>>
>>>>> We've combed the vmcb to no avail. Everything we've thought to check
>>>>> (exitinfo1, exitinfo2, exitintinfo) turns out to be zero there while
>>>>> testing.
>>>>>
>>>>> There's __get_instruction_length(vcpu, instr), but it expects to be fed
>>>>> the exact instruction we want the length for, which obviously defeats
>>>>> the purpose here.
>>>>>
>>>>> Is there a clean way to get the current instruction length like we do in
>>>>> the VMX case (__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len)) that we're
>>>>> overlooking?
>>>> Just like Intel's, AMD's is available in a subset of cases only
>>>> (look for vmcb->guest_ins_len), which don't include the
>>>> exception intercepts you talk about. For #DB I think there's
>>>> no difference between both anyway.
>>> On non-first-gen hardware, the difference between RIP and NextRIP should
>>> give you the instruction length.  ISTR NextRIP is written on all exits,
>>> and consumed on all entries.
>> Thanks!
>>
>> vmcb->nextrip - vmcb->rip seems to work well for the instruction length.
> 
> Turns out I was wrong.
> 
>>From 15.7.1 "State Saved on Exit":
>> The next sequential instruction pointer (nRIP) is saved in the guest
>> VMCB control area at location C8h
>> on all #VMEXITs that are due to instruction intercepts, as defined in
>> Section 15.9 on page 461, as well
>> as MSR and IOIO intercepts and exceptions caused by the INT3, INTO,
>> and BOUND instructions. For
>> all other intercepts, nRIP is reset to zero.

Still, it does work well for int3, int $3, into and icebp - so for
everything the swint XTF test throws at Xen.

> On 17/03/18 21:11, Razvan Cojocaru wrote:
>>
>> Shouldn't vmcb->exitintinfo also be filled in properly on SVM? I'm
>> getting this on VMEXIT_EXCEPTION_BP:
> 
> No.  The manual says not.  From 15.12.4 "#BP (Breakpoint)":
> 
>> This intercept applies to the trap raised by the single byte INT3
>> (opcode CCh) instruction. The
>> EXITINFO1 and EXITINFO2 fields are undefined. The CS:rIP reported on
>> #VMEXIT are those of
>> the INT3 instruction.

Fair enough, thanks!

> What other information are you trying to derive when intercepting #BP?

Well, we've added GENERAL2_INTERCEPT_ICEBP to the SVM intercepts, and
added a case VMEXIT_ICEBP: that's really just a fallthrough for case
VMEXIT_EXCEPTION_DB:, to try to make it look like what VMX currently
does (where icebp causes a debug vm_event). So now we'd like to call
hvm_monitor_debug(regs->rip, HVM_MONITOR_DEBUG_EXCEPTION, trap_type,
inst_len), where trap_type now needs to be
X86_EVENTTYPE_PRI_SW_EXCEPTION (5) for icebp, but whatever else is
appropriate for VMEXIT_EXCEPTION_DB. All this is made easy on VMX by
checking intr, but requires a lot of verbosity on SVM.


Thanks,
Razvan

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-03-17 22:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-14 14:56 [SVM] Getting the length of the current instruction in svm_vmexit_handler() Razvan Cojocaru
2018-03-14 15:53 ` Jan Beulich
2018-03-14 17:06   ` Andrew Cooper
2018-03-17 21:11     ` Razvan Cojocaru
2018-03-17 21:45       ` Andrew Cooper
2018-03-17 22:08         ` 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.