Disabling interrupt in RtlRestoreContext

Hello !

In RtlRestoreContext interrupts are disabled before restoring some
registers and restoring context with iretq.

cli
mov rbx, qword ptr[rcx + 90h]
mov rsi, qword ptr[rcx + 0A8h]
mov rdi, qword ptr[rcx + 0B0h]
mov rbp, qword ptr[rcx + 0A0h]
mov r12, qword ptr[rcx + 0D8h]
mov r13, qword ptr[rcx + 0E0h]
mov r14, qword ptr[rcx + 0E8h]
mov r15, qword ptr[rcx + 0F0h]
mov rcx, qword ptr[rcx + 80h]
iretq

Why interrupts must be disabled ? iretq doesn’t require it (for example
interrupts are enabled in trap handler).

I am almost ready to give you a full answer to your question, but in order to make sure
that I don’t make a fool out of myself the way Mr.Wieland did on another thread, could you please provide interrupt handler stub (i.e. the one that saves the registers upon the interrupt) code - I just want to look at it so that all the pieces get together

Anton Bassov

for example nt!KiVmbusInterrupt0Shadow starts with

sub rsp, 8
push rbp
push rsi
sub rsp, 150h
lea rbp, [rsp + 80h]
mov byte ptr[rbp - 55h], 0
mov qword ptr[rbp - 50h], rax
mov qword ptr[rbp - 48h], rcx
mov qword ptr[rbp - 40h], rdx
mov qword ptr[rbp - 38h], r8
mov qword ptr[rbp - 30h], r9
mov qword ptr[rbp - 28h], r10
mov qword ptr[rbp - 20h], r11
test byte ptr[rbp + 0F0h], 1
jne nt!KiVmbusInterrupt0 + 0x1a2

also later in that function

call nt!KiSaveDebugRegisterState
cld
lfence
stmxcsr dword ptr[rbp - 54h]
ldmxcsr dword ptr gs : [180h]
movaps xmmword ptr[rbp - 10h], xmm0
movaps xmmword ptr[rbp], xmm1
movaps xmmword ptr[rbp + 10h], xmm2
movaps xmmword ptr[rbp + 20h], xmm3
movaps xmmword ptr[rbp + 30h], xmm4
movaps xmmword ptr[rbp + 40h], xmm5
cmp byte ptr gs : [5D1Ah], 0
je nt!KiVmbusInterrupt0 + 0x371

This is the part that saves register state. Or should i post complete
routine code ?

On Thu, Mar 22, 2018 at 5:40 AM, xxxxx@hotmail.com <
xxxxx@lists.osr.com> wrote:

I am almost ready to give you a full answer to your question, but in order
to make sure
that I don’t make a fool out of myself the way Mr.Wieland did on another
thread, could you please provide interrupt handler stub (i.e. the one that
saves the registers upon the interrupt) code - I just want to look at it so
that all the pieces get together

Anton Bassov


NTDEV is sponsored by OSR

Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

> This is the part that saves register state.

Well, this part saves just a PART of what has to be saved,and the original code shows a part of what gets restored. Certainly, they don’t match. What I want to do is to analyse how the entire stack frame gets saved and restored.

It is obvious that RCX in the returning part acts as a frame pointer. It would be a great idea to see where it actually comes from- I don’t see it in your original code. I also wonder whether RBP and RSI get saved once again somewhere in the frame or whether they stay where they are, i.e. just above interrupt frame (which, BTW, could also get duplicated - after all, a single byte above RAX gets zeroed for some reason, and this thing just cannot be related to the register state alone). Your code does not show this part either

Concerning your actual question, it is obvious that interrupts get disabled in order to preserve the stack frame consistency. What I am trying to understand is WHY this consistency would be violated if interrupt occurs, and it is, apparently, somehow related to RCX register and its interactions with RBP. Therefore, I would certainly prefer to see as much code as you can provide

Anton Bassov

Since RtlRestoreContext used to restore context saved by RtlCaptureContext
maybe it is better to post capture function code ?

nt!RtlCaptureContext:
pushfq
mov qword ptr[rcx + 78h], rax
mov qword ptr[rcx + 80h], rcx
mov qword ptr[rcx + 88h], rdx
mov qword ptr[rcx + 0B8h], r8
mov qword ptr[rcx + 0C0h], r9
mov qword ptr[rcx + 0C8h], r10
mov qword ptr[rcx + 0D0h], r11
movaps xmmword ptr[rcx + 1A0h], xmm0
movaps xmmword ptr[rcx + 1B0h], xmm1
movaps xmmword ptr[rcx + 1C0h], xmm2
movaps xmmword ptr[rcx + 1D0h], xmm3
movaps xmmword ptr[rcx + 1E0h], xmm4
movaps xmmword ptr[rcx + 1F0h], xmm5
mov word ptr[rcx + 38h], cs
mov word ptr[rcx + 3Ah], ds
mov word ptr[rcx + 3Ch], es
mov word ptr[rcx + 42h], ss
mov word ptr[rcx + 3Eh], fs
mov word ptr[rcx + 40h], gs
mov qword ptr[rcx + 90h], rbx
mov qword ptr[rcx + 0A0h], rbp
mov qword ptr[rcx + 0A8h], rsi
mov qword ptr[rcx + 0B0h], rdi
mov qword ptr[rcx + 0D8h], r12
mov qword ptr[rcx + 0E0h], r13
mov qword ptr[rcx + 0E8h], r14
mov qword ptr[rcx + 0F0h], r15
fnstcw word ptr[rcx + 100h]
mov dword ptr[rcx + 102h], 0
movaps xmmword ptr[rcx + 200h], xmm6
movaps xmmword ptr[rcx + 210h], xmm7
movaps xmmword ptr[rcx + 220h], xmm8
movaps xmmword ptr[rcx + 230h], xmm9
movaps xmmword ptr[rcx + 240h], xmm10
movaps xmmword ptr[rcx + 250h], xmm11
movaps xmmword ptr[rcx + 260h], xmm12
movaps xmmword ptr[rcx + 270h], xmm13
movaps xmmword ptr[rcx + 280h], xmm14
movaps xmmword ptr[rcx + 290h], xmm15
stmxcsr dword ptr[rcx + 118h]
stmxcsr dword ptr[rcx + 34h]
lea rax, [rsp + 10h]
mov qword ptr[rcx + 98h], rax
mov rax, qword ptr[rsp + 8]
mov qword ptr[rcx + 0F8h], rax
mov eax, dword ptr[rsp]
mov dword ptr[rcx + 44h], eax
mov dword ptr[rcx + 30h], 10000Fh
add rsp, 8
ret

input argument for capture function is pointer to _CONTEXT structure

nt!_CONTEXT
+0x000 P1Home : Uint8B
+0x008 P2Home : Uint8B
+0x010 P3Home : Uint8B
+0x018 P4Home : Uint8B
+0x020 P5Home : Uint8B
+0x028 P6Home : Uint8B
+0x030 ContextFlags : Uint4B
+0x034 MxCsr : Uint4B
+0x038 SegCs : Uint2B
+0x03a SegDs : Uint2B
+0x03c SegEs : Uint2B
+0x03e SegFs : Uint2B
+0x040 SegGs : Uint2B
+0x042 SegSs : Uint2B
+0x044 EFlags : Uint4B
+0x048 Dr0 : Uint8B
+0x050 Dr1 : Uint8B
+0x058 Dr2 : Uint8B
+0x060 Dr3 : Uint8B
+0x068 Dr6 : Uint8B
+0x070 Dr7 : Uint8B
+0x078 Rax : Uint8B
+0x080 Rcx : Uint8B
+0x088 Rdx : Uint8B
+0x090 Rbx : Uint8B
+0x098 Rsp : Uint8B
+0x0a0 Rbp : Uint8B
+0x0a8 Rsi : Uint8B
+0x0b0 Rdi : Uint8B
+0x0b8 R8 : Uint8B
+0x0c0 R9 : Uint8B
+0x0c8 R10 : Uint8B
+0x0d0 R11 : Uint8B
+0x0d8 R12 : Uint8B
+0x0e0 R13 : Uint8B
+0x0e8 R14 : Uint8B
+0x0f0 R15 : Uint8B
+0x0f8 Rip : Uint8B
+0x100 FltSave : _XSAVE_FORMAT
+0x100 Header : [2] _M128A
+0x120 Legacy : [8] _M128A
+0x1a0 Xmm0 : _M128A
+0x1b0 Xmm1 : _M128A
+0x1c0 Xmm2 : _M128A
+0x1d0 Xmm3 : _M128A
+0x1e0 Xmm4 : _M128A
+0x1f0 Xmm5 : _M128A
+0x200 Xmm6 : _M128A
+0x210 Xmm7 : _M128A
+0x220 Xmm8 : _M128A
+0x230 Xmm9 : _M128A
+0x240 Xmm10 : _M128A
+0x250 Xmm11 : _M128A
+0x260 Xmm12 : _M128A
+0x270 Xmm13 : _M128A
+0x280 Xmm14 : _M128A
+0x290 Xmm15 : _M128A
+0x300 VectorRegister : [26] _M128A
+0x4a0 VectorControl : Uint8B
+0x4a8 DebugControl : Uint8B
+0x4b0 LastBranchToRip : Uint8B
+0x4b8 LastBranchFromRip : Uint8B
+0x4c0 LastExceptionToRip : Uint8B
+0x4c8 LastExceptionFromRip : Uint8B

On Thu, Mar 22, 2018 at 7:54 AM, xxxxx@hotmail.com <
xxxxx@lists.osr.com> wrote:

> This is the part that saves register state.

Well, this part saves just a PART of what has to be saved,and the original
code shows a part of what gets restored. Certainly, they don’t match. What
I want to do is to analyse how the entire stack frame gets saved and
restored.

It is obvious that RCX in the returning part acts as a frame pointer. It
would be a great idea to see where it actually comes from- I don’t see it
in your original code. I also wonder whether RBP and RSI get saved once
again somewhere in the frame or whether they stay where they are, i.e. just
above interrupt frame (which, BTW, could also get duplicated - after all, a
single byte above RAX gets zeroed for some reason, and this thing just
cannot be related to the register state alone). Your code does not show
this part either

Concerning your actual question, it is obvious that interrupts get
disabled in order to preserve the stack frame consistency. What I am trying
to understand is WHY this consistency would be violated if interrupt
occurs, and it is, apparently, somehow related to RCX register and its
interactions with RBP. Therefore, I would certainly prefer to see as much
code as you can provide

Anton Bassov


NTDEV is sponsored by OSR

Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

> Since RtlRestoreContext used to restore context saved by RtlCaptureContext

maybe it is better to post capture function code ?

We are almost there - the “only” thing left is RCX modification,which is the “missing link”.
It is very obviously gets modified before calling both RtlCaptureContext:() and RtlRestoreContext()
so that it is used as an argument to these functions. Although it it is obviously a pointer to CONTEXT structure, this structure may be stored either on the stack or in some other thread-specific location.

AS I said already, I want to see how it is related to RBP and RSP…

Anton Bassov

If i understand corerctly rcx doesn’t get modified at all in
RtlCaptureContext and set to value in _CONTEXT structure in
RtlRestoreContext right before iretq.

For example

#include <ntifs.h>

namespace
{
bool exit_now = false;
}

extern “C”
{
NTSYSAPI VOID RtlRestoreContext(In PCONTEXT ContextRecord, In_opt
struct _EXCEPTION_RECORD * ExceptionRecord);
}

extern “C” NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING)
{
CONTEXT c;
RtlCaptureContext(&c);

if (exit_now)
{
return STATUS_UNSUCCESSFUL;
}

exit_now = true;
RtlRestoreContext(&c, 0);

return STATUS_UNSUCCESSFUL;
}

Here CONTEXT is allocated on stack and rcx set to point to this structure.
Since it is fastcall calling convention rcx doesn’t get modified, it is
just first parameter

idt!DriverEntry [c:\users\pisar\onedrive\desktop\idt\idt\main.cpp @ 14]:
14 fffff809e6891000 4889542410 mov qword ptr [rsp+10h],rdx<br> 14 fffff809e6891005 48894c2408 mov qword ptr [rsp+8],rcx
14 fffff809e689100a 4881ec08050000 sub rsp,508h<br> 14 fffff809e6891011 488b05e81f0000 mov rax,qword ptr
[idt!__security_cookie (fffff809e6893000)]<br> 14 fffff809e6891018 4833c4 xor rax,rsp
14 fffff809e689101b 48898424f0040000 mov qword ptr [rsp+4F0h],rax<br> 16 fffff809e6891023 488d4c2420 lea rcx,[rsp+20h]
16 fffff809e6891028 ff15da0f0000 call qword ptr<br>[idt!_imp_RtlCaptureContext (fffff809e6892008)]
18 fffff809e689102e 0fb605db1f0000 movzx eax,byte ptr [idt!exit_now<br>(fffff809e6893010)]
18 fffff809e6891035 85c0 test eax,eax<br> 18 fffff809e6891037 7407 je idt!DriverEntry+0x40
(fffff809e6891040) Branch<br><br>idt!DriverEntry+0x39 [c:\users\pisar\onedrive\desktop\idt\idt\main.cpp @<br>20]:<br> 20 fffff809e6891039 b8010000c0 mov eax,0C0000001h
20 fffff809e689103e eb19 jmp idt!DriverEntry+0x59<br>(fffff809e6891059) Branch

idt!DriverEntry+0x40 [c:\users\pisar\onedrive\desktop\idt\idt\main.cpp @
23]:
23 fffff809e6891040 c605c91f000001 mov byte ptr [idt!exit_now<br>(fffff809e6893010)],1
24 fffff809e6891047 33d2 xor edx,edx<br> 24 fffff809e6891049 488d4c2420 lea rcx,[rsp+20h]
24 fffff809e689104e ff15ac0f0000 call qword ptr<br>[idt!_imp_RtlRestoreContext (fffff809e6892000)]
26 fffff809e6891054 b8010000c0 mov eax,0C0000001h<br><br>idt!DriverEntry+0x59 [c:\users\pisar\onedrive\desktop\idt\idt\main.cpp @<br>27]:<br> 27 fffff809e6891059 488b8c24f0040000 mov rcx,qword ptr [rsp+4F0h]
27 fffff809e6891061 4833cc xor rcx,rsp<br> 27 fffff809e6891064 e827000000 call idt!__security_check_cookie
(fffff809e6891090)<br> 27 fffff809e6891069 4881c408050000 add rsp,508h
27 fffff809`e6891070 c3 ret

On Thu, Mar 22, 2018 at 2:39 PM, xxxxx@hotmail.com <
xxxxx@lists.osr.com> wrote:

>
> > Since RtlRestoreContext used to restore context saved by
> RtlCaptureContext
> >maybe it is better to post capture function code ?
>
> We are almost there - the “only” thing left is RCX modification,which is
> the “missing link”.
> It is very obviously gets modified before calling both
> RtlCaptureContext:() and RtlRestoreContext()
> so that it is used as an argument to these functions. Although it it is
> obviously a pointer to CONTEXT structure, this structure may be stored
> either on the stack or in some other thread-specific location.
>
> AS I said already, I want to see how it is related to RBP and RSP…
>
>
>
> Anton Bassov
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></ntifs.h>

> If i understand corerctly rcx doesn’t get modified at all in RtlCaptureContext

Of course not - once we are speaking about x86_64 calling convention RCX happens to be a register in which the first parameter gets passed to a function (i.e to both RtlCaptureContext() and RtlRestoreContext()). What I want to see is where this parameter comes from. If you provide all the code that executes from the moment interrupt occurs untill RtlCaptureContext() gets invoked we will see where RCX gets modified, and, at this point, we will discover how CONTEXT structure is related to RBP and RSP pointers on the stack at the moment of invocation …

Once we have found out how CONTEXT structure is related to the stack frame we will be (hopefully) in a position to deduce why (and if) interrupt that occurs while registers are restored from CONTEXT structure is going to corrupt the stack frame and/or CONTEXT structure. Simple,ugh…

Anton Bassov

I don’t think that capture/restore are actually used in interrupt handlers.
At least in 5-10 interrupt handlers i checked small subset of registers is
saved/restored by hand, without calls to these Rtl routines. So as i
understand RtlRestore does not implicitly expect for CONTEXT to be in some
specific place in memory

On Thu, Mar 22, 2018 at 5:03 PM, xxxxx@hotmail.com <
xxxxx@lists.osr.com> wrote:

> If i understand corerctly rcx doesn’t get modified at all in
RtlCaptureContext

Of course not - once we are speaking about x86_64 calling convention RCX
happens to be a register in which the first parameter gets passed to a
function (i.e to both RtlCaptureContext() and RtlRestoreContext()). What I
want to see is where this parameter comes from. If you provide all the code
that executes from the moment interrupt occurs untill RtlCaptureContext()
gets invoked we will see where RCX gets modified, and, at this point, we
will discover how CONTEXT structure is related to RBP and RSP pointers on
the stack at the moment of invocation …

Once we have found out how CONTEXT structure is related to the stack frame
we will be (hopefully) in a position to deduce why (and if) interrupt that
occurs while registers are restored from CONTEXT structure is going to
corrupt the stack frame and/or CONTEXT structure. Simple,ugh…

Anton Bassov


NTDEV is sponsored by OSR

Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

I’m assuming that this is out of curiosity as I don’t know how this could
ever matter. I also don’t know what the answer is. However, the question
(and this thread) are sort of weird so I’ll bite…

Interesting that the cli happens right before the restoring of non-volatile
general purpose registers. The x64 and ARM trap frames don’t contain
non-volatile registers:

1: kd> .trap ffffcc80e7980180
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.

The idea being that the non-volatile registers are naturally saved by the
ABI so there’s no point in putting them in the trap. So maybe trying to
prevent something weird from happening with the non-volatiles? I can’t
conjure what that “weird thing” would be in this case (and not all of the
non-volatiles are restored under cli here, XMM6:15 are missing), but then
again this is creepy exception handling/stack unwinding code so I’m sure
there’s a TON of subtlety involved.

Aside: For fun I turned the CLI into a NOP on a test system and let it run
for a while. Hasn’t died yet so it doesn’t immediately fall over dead, but
that’s not really evidence of anything.

Also interesting is that they do something equivalent on the ARM but restore
both volatile AND non-volatile with interrupts disabled:

nt!RtlRestoreContext+0xdc:
8351de0c cpsid i

8351de3c ldrd r1,r2,[r0,#8]
8351de40 ldrd r3,r4,[r0,#0x10]

8351de54 ldr r0,[r0,#4]
8351de56 rfe sp

Admittedly this is an ancient ARM system from 2012 so might be different
now.

Soooo…In summary, don’t know and not sure that we’ll ever find out, but I
agree it’s a funny cli.

-scott
OSR
@OSRDrivers

That Arm assembler code is from Armv7 (32-bit) so it’s not going to be the same for 64-bit.

Greg
xxxxx@lists.osr.com wrote:

From: ““Scott Noone” ”
To: “Windows System Software Devs Interest List”
Subject: Re:[ntdev] Disabling interrupt in RtlRestoreContext
Date: Thu, 22 Mar 2018 15:20:34 -0400

I’m assuming that this is out of curiosity as I don’t know how this could
ever matter. I also don’t know what the answer is. However, the question
(and this thread) are sort of weird so I’ll bite…

Interesting that the cli happens right before the restoring of non-volatile
general purpose registers. The x64 and ARM trap frames don’t contain
non-volatile registers:

1: kd> .trap ffffcc80e7980180
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.

The idea being that the non-volatile registers are naturally saved by the
ABI so there’s no point in putting them in the trap. So maybe trying to
prevent something weird from happening with the non-volatiles? I can’t
conjure what that “weird thing” would be in this case (and not all of the
non-volatiles are restored under cli here, XMM6:15 are missing), but then
again this is creepy exception handling/stack unwinding code so I’m sure
there’s a TON of subtlety involved.

Aside: For fun I turned the CLI into a NOP on a test system and let it run
for a while. Hasn’t died yet so it doesn’t immediately fall over dead, but
that’s not really evidence of anything.

Also interesting is that they do something equivalent on the ARM but restore
both volatile AND non-volatile with interrupts disabled:

nt!RtlRestoreContext+0xdc:
8351de0c cpsid i

8351de3c ldrd r1,r2,[r0,#8]
8351de40 ldrd r3,r4,[r0,#0x10]

8351de54 ldr r0,[r0,#4]
8351de56 rfe sp

Admittedly this is an ancient ARM system from 2012 so might be different
now.

Soooo…In summary, don’t know and not sure that we’ll ever find out, but I
agree it’s a funny cli.

-scott
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

> I don’t think that capture/restore are actually used in interrupt handlers.

At this point the whole thing starts making a perfect sense - my theory seems to be, indeed, correct

Consider what happens if interrupt eventually results in context switch through ISR-DPC-KeSetEvent() sequence before interrupted thread gets a chance to continue its execution. If interrupt handler stub does not save the entire context in CONTEXT structure straight away, it is going to be done later in case of context switch - no matter how you look at it, it has to be done at some point before some new thread gets scheduled on the CPU. Therefore, CONTEXT structure of interrupted thread needs to be 100% free at the time of interrupt, because it may get overwritten in case of context switch.

This is the reason why RtlRestoreContext() disables interrupts - it cannot allow interrupts while it restores the thread’s registers, because CONTEXT structure that stores these registers in not yet free. If interrupt eventually results in context switch, CONTEXT structure is going to get corrupted under these circumstances. Therefore, RtlRestoreContext() disables interrupts in order to prevent this unfortunate scenario,…

Anton Bassov

True. Though isn’t the Windows ARM ABI is the same for 32-bit and 64-bit? If
it uses unwind data and trap frames are only volatile registers then it’s
similar enough to the x64 in this case.

-scott
OSR
@OSRDrivers

Sorry, I can’t comment on what Microsoft does to Arm code. If they follow the Arm ABI, then it is somewhat similar, just wider registers (64-bit),
more corruptible registers (X0-X7 and V0-V7) and more registers overall (X0-X30 and V0-V31). No, that is NOT a typo, there is no X31.

What IS slightly different with Aarch64 is how exceptions are handled. You must restore both the corruptible and non-corruptible registers before performing the ERET instruction. There should be no need to reenable interrupts unless you are handling nested interrupts. The ERET will restore the processor’s pre-exception asynchronous exception masks.

Greg

xxxxx@lists.osr.com wrote:

From: ““Scott Noone” ”
To: “Windows System Software Devs Interest List”
Subject: Re:[ntdev] Re:Disabling interrupt in RtlRestoreContext
Date: Thu, 22 Mar 2018 15:48:32 -0400



True. Though isn’t the Windows ARM ABI is the same for 32-bit and 64-bit? If
it uses unwind data and trap frames are only volatile registers then it’s
similar enough to the x64 in this case.

-scott
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

thank you guys

On Thu, Mar 22, 2018 at 10:56 PM, xxxxx@PDQ.NET
wrote:

> Sorry, I can’t comment on what Microsoft does to Arm code. If they follow
> the Arm ABI, then it is somewhat similar, just wider registers (64-bit),
> more corruptible registers (X0-X7 and V0-V7) and more registers overall
> (X0-X30 and V0-V31). No, that is NOT a typo, there is no X31.
>
> What IS slightly different with Aarch64 is how exceptions are handled.
> You must restore both the corruptible and non-corruptible registers before
> performing the ERET instruction. There should be no need to reenable
> interrupts unless you are handling nested interrupts. The ERET will
> restore the processor’s pre-exception asynchronous exception masks.
>
> Greg
>
> — xxxxx@lists.osr.com wrote:
>
> From: ““Scott Noone” ”
> To: “Windows System Software Devs Interest List”
> Subject: Re:[ntdev] Re:Disabling interrupt in RtlRestoreContext
> Date: Thu, 22 Mar 2018 15:48:32 -0400
>
>


>
> True. Though isn’t the Windows ARM ABI is the same for 32-bit and 64-bit?
> If
> it uses unwind data and trap frames are only volatile registers then it’s
> similar enough to the x64 in this case.
>
> -scott
> OSR
> @OSRDrivers
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></http:></http:>