How does Kernel Mode execute in "same contexts" ?

Hi
I have a problem with a basic concept in kernel-mode programming.

I started to read The Windows 2000 Device Driver Book.

It defines context:“A context, as used here, describes the state of the system while a CPU instruction executes. It includes the state of all CPU registers (including the stack), the processor mode (user or kernel), and significantly, the state of the hardware page tables”

OK, and:

"The memory seen by kernel-mode code includes the same view as seen by the requesting user-mode thread.

When a user-mode thread makes a direct request of the I/O Manager, the I/O Manager executes within the context of the requester. In turn, the I/O Manager may call a dispatch routine within a device driver. Dispatch routines of a driver therefore execute within this exception context."

Is that mean : When a user-mode thread makes a direct request of the I/O Manager; I/O Manager starts to run upper 2 GB of the System area while user-mode thread is running in lower 2 GB ? So no context(EIP, ESP, CS…) swith occurs?

Is that right?

Can you please help me the understand the meaning of “executing within the context of requester(user-mode code)”.
Thanks…

xxxxx@gmail.com wrote:

I have a problem with a basic concept in kernel-mode programming.

I started to read The Windows 2000 Device Driver Book.

It defines context:“A context, as used here, describes the state of the system while a CPU instruction executes. It includes the state of all CPU registers (including the stack), the processor mode (user or kernel), and significantly, the state of the hardware page tables”

OK, and:

"The memory seen by kernel-mode code includes the same view as seen by the requesting user-mode thread.

When a user-mode thread makes a direct request of the I/O Manager, the I/O Manager executes within the context of the requester. In turn, the I/O Manager may call a dispatch routine within a device driver. Dispatch routines of a driver therefore execute within this exception context."

Is that mean : When a user-mode thread makes a direct request of the I/O Manager; I/O Manager starts to run upper 2 GB of the System area while user-mode thread is running in lower 2 GB ? So no context(EIP, ESP, CS…) swith occurs?

Is that right?

Well, more or less. I think you have the basic concept, if not the
details. Remember that it’s not really a separate thread. It’s the
SAME thread. Also remember that the entire 4GB address space is always
present, it’s just that user-mode code does not have permission to
access the upper half. When you make a call to I/O manager, you are
essentially making a function call into a kernel mode address. It’s not
really a function call, but it’s the same concept. It’s a function call
that raises the privilege of the CPU, moving it into “kernel mode”.
Once the CPU is in kernel mode, it can get at all 4GB of space. When
the I/O operation is done, it does the equivalent of a function return,
which reduces the privilege level, and returns to the calling application.

One problem in discussing this is that the phrase “context switch” is
overloaded. Some people use that phrase to refer to the user/kernel
switch, some people use it to refer to changing to a different thread,
and some people use it to refer to changing to a different process.

Can you please help me the understand the meaning of “executing within the context of requester(user-mode code)”.

It means that the requesting thread will jump to kernel mode and execute
kernel code. The requester’s memory will all still be set up in the
lower 2GB, and it’s possible that other threads from the requester will
still be running at the same time, in other processors.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thank you very much Tim Robert.
So can we say context switching is all about cr3 register?
In the same chapter it says:“When the hardware (or software) generates an
acknowledged interrupt, whatever code is executing within the system is
stopped dead in its tracks. The executing context is saved and control is
promptly handed over to a service routine appropriate for the kind of
interrupt that occurred.”

Now context switching occurs because i assume that this paragraph tries to
tell “cr3 is changed”. If cr3 isn’t change and there is only a function
call(only changes in CS,EIP and ESP), this doesn’t mean context switching.
Is that right?

2008/4/16, Tim Roberts :
>
> xxxxx@gmail.com wrote:
>
> > I have a problem with a basic concept in kernel-mode programming.
> >
> > I started to read The Windows 2000 Device Driver Book.
> > It defines context:“A context, as used here, describes the state of the
> > system while a CPU instruction executes. It includes the state of all CPU
> > registers (including the stack), the processor mode (user or kernel), and
> > significantly, the state of the hardware page tables”
> >
> > OK, and:
> >
> > “The memory seen by kernel-mode code includes the same view as seen by
> > the requesting user-mode thread.
> >
> > When a user-mode thread makes a direct request of the I/O Manager, the
> > I/O Manager executes within the context of the requester. In turn, the I/O
> > Manager may call a dispatch routine within a device driver. Dispatch
> > routines of a driver therefore execute within this exception context.”
> >
> > Is that mean : When a user-mode thread makes a direct request of the I/O
> > Manager; I/O Manager starts to run upper 2 GB of the System area while
> > user-mode thread is running in lower 2 GB ? So no context(EIP, ESP, CS…)
> > swith occurs?
> > Is that right?
> >
> >
>
> Well, more or less. I think you have the basic concept, if not the
> details. Remember that it’s not really a separate thread. It’s the SAME
> thread. Also remember that the entire 4GB address space is always present,
> it’s just that user-mode code does not have permission to access the upper
> half. When you make a call to I/O manager, you are essentially making a
> function call into a kernel mode address. It’s not really a function call,
> but it’s the same concept. It’s a function call that raises the privilege
> of the CPU, moving it into “kernel mode”. Once the CPU is in kernel mode,
> it can get at all 4GB of space. When the I/O operation is done, it does the
> equivalent of a function return, which reduces the privilege level, and
> returns to the calling application.
>
> One problem in discussing this is that the phrase “context switch” is
> overloaded. Some people use that phrase to refer to the user/kernel switch,
> some people use it to refer to changing to a different thread, and some
> people use it to refer to changing to a different process.
>
> Can you please help me the understand the meaning of “executing within
> > the context of requester(user-mode code)”.
> >
>
> It means that the requesting thread will jump to kernel mode and execute
> kernel code. The requester’s memory will all still be set up in the lower
> 2GB, and it’s possible that other threads from the requester will still be
> running at the same time, in other processors.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

serimc wrote:

So can we say context switching is all about cr3 register?

No, I don’t think we can. As I said, the term “context switching” means
different things in different circumstances. Changing CR3 is certainly
part of a “process switch”, but CR3 is not changed when switching to a
new thread, and yet some people would call that a “context switch”.

In the same chapter it says:“When the hardware (or software) generates
an acknowledged interrupt, whatever code is executing within the
system is stopped dead in its tracks. The executing context is saved
and control is promptly handed over to a service routine appropriate
for the kind of interrupt that occurred.”

Now context switching occurs because i assume that this paragraph
tries to tell “cr3 is changed”. If cr3 isn’t change and there is only
a function call(only changes in CS,EIP and ESP), this doesn’t mean
context switching.
Is that right?

Not necessarily. In this particular case, the interrupt will “hijack”
the thread that had been running. There is no context switch. CS, EIP,
and ESP all change, but the page tables (and hence CR3) remain the
same. This is why articles about interrupt handlers talk about them
running in an “arbitrary context”. They run as whatever process was
running at the time of the interrupt. That process is still alive and
in memory, but it is frozen until the interrupt finishes its job and
returns.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

You said:
“There is no context switch. CS, EIP, and ESP all change, but the page
tables (and hence CR3) remain the same”
Yes. Becaues of that i said it is all about cr3. Let me explain:

In Intel Doc.
For Task Switch:
“The TSS state is loaded into the processor. This includes the LDTR
register, the PDBR (control register CR3), the EFLAGS registers, the EIP
register, the general-purpose registers, and the segment selectors.”

For Interrupt Exception Handling:
“EFLAGS, CS, and EIP are saved”
So this is about what you said:“This is why articles about interrupt
handlers talk about them running in an “arbitrary context”. They run as
whatever process was running at the time of the interrupt. That process is
still alive and in memory, but it is frozen until the interrupt finishes its
job and returns.”
Right?

But there is nothing for thread switching. It is all about Windows. So i
looked SDK. This is CONTEXT structure:

typedef struct _CONTEXT {

DWORD ContextFlags;

//
// This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
// set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
// included in CONTEXT_FULL.
//

DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
//

FLOATING_SAVE_AREA FloatSave;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_SEGMENTS.
//

DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_INTEGER.
//

DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_CONTROL.
//

DWORD Ebp;
DWORD Eip;
DWORD SegCs; // MUST BE SANITIZED
DWORD EFlags; // MUST BE SANITIZED
DWORD Esp;
DWORD SegSs;

//
// This section is specified/returned if the ContextFlags word
// contains the flag CONTEXT_EXTENDED_REGISTERS.
// The format and contexts are processor specific
//

BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

Here all registers is changed except Control registers(especially cr3).

Can we say the difference between process and thread switch is related cr3
register.

And in Driver Development world.
If i read something that says: “executing within the context of requester”
means context switching doesn’t effect CR3.
Am i right?

If changing CR3 means there is a task switch occurs, why do they underline
execute within this exception context?
Driver codes are not self executable, they must be called from running
application?

I confused because whatever i read say: “execute within same context” Is
this have special meaning in driver development world?

Or secret code that newbies like me, mustn’t understand but driver
developers communicate :slight_smile:
Thanks…

2008/4/17, Tim Roberts :
>
> serimc wrote:
>
> >
> > So can we say context switching is all about cr3 register?
> >
>
> No, I don’t think we can. As I said, the term “context switching” means
> different things in different circumstances. Changing CR3 is certainly part
> of a “process switch”, but CR3 is not changed when switching to a new
> thread, and yet some people would call that a “context switch”.
>
>
> In the same chapter it says:“When the hardware (or software) generates an
> > acknowledged interrupt, whatever code is executing within the system is
> > stopped dead in its tracks. The executing context is saved and control is
> > promptly handed over to a service routine appropriate for the kind of
> > interrupt that occurred.”
> >
> > Now context switching occurs because i assume that this paragraph tries
> > to tell “cr3 is changed”. If cr3 isn’t change and there is only a function
> > call(only changes in CS,EIP and ESP), this doesn’t mean context switching.
> > Is that right?
> >
>
> Not necessarily. In this particular case, the interrupt will “hijack” the
> thread that had been running. There is no context switch. CS, EIP, and ESP
> all change, but the page tables (and hence CR3) remain the same. This is
> why articles about interrupt handlers talk about them running in an
> “arbitrary context”. They run as whatever process was running at the time
> of the interrupt. That process is still alive and in memory, but it is
> frozen until the interrupt finishes its job and returns.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

serimc wrote:

You said:
“There is no context switch. CS, EIP, and ESP all change, but the
page tables (and hence CR3) remain the same”
Yes. Becaues of that i said it is all about cr3. Let me explain:

In Intel Doc.
For Task Switch:
“The TSS state is loaded into the processor. This includes the LDTR
register, the PDBR (control register CR3), the EFLAGS registers, the
EIP register, the general-purpose registers, and the segment selectors.”

This is true, but Windows does not use the TSS.

But there is nothing for thread switching. It is all about Windows. So
i looked SDK. This is CONTEXT structure:

typedef struct _CONTEXT {

} CONTEXT;

Here all registers is changed except Control registers(especially cr3).

Yes, but again I would caution you that the word “context” has many
meanings. You should not assume that the CONTEXT structure is used to
store the context for a “context switch”.

Can we say the difference between process and thread switch is
related cr3 register.

I think that is accurate, yes.

And in Driver Development world.
If i read something that says: “executing within the context of
requester” means context switching doesn’t effect CR3.
Am i right?

I would not word it that way, but I believe you are correct. When
something executes within the context of the requester, then the page
tables (and CR3) are still set to whatever the current process needed.
The key point is that a driver writer must not assume that it always
executes in the context of whatever process last opened the driver using
CreateFile for the driver, for instance. That’s a relatively common
mistake.

If changing CR3 means there is a task switch occurs, why do they
underline execute within this exception context?

“Task switch” is not well-defined in Windows. Changing CR3 means there
was a “process switch”.

Driver codes are not self executable, they must be called from running
application?

Or from an interrupt handler, or from an IRP completion routine, or from
a timer callback, etc. Driver code can be called from many places.

Here’s an example. Let’s say a user opens my driver using CreateFile,
and then sends me an ioctl using DeviceIoControl. Let’s say the input
buffer to DeviceIoControl contains a raw pointer to a user-mode buffer
(which is a dangerous thing to do, partly because of what I’m about to
describe). In my ioctl handler, I can use that user-mode address and
read the data, because the page tables are still set to that process.

OK, now let’s say I can’t finish the ioctl right away, so I mark it as
pending and set up a timer callback. When I get the timer callback, I
am in an “arbitrary process context”. That means I don’t know what
process is in the page tables. If I now fetch that pending IRP and try
to access the user-mode address, it will either crash (because the
address is not valid), or access unknown memory in a different process.

I confused because whatever i read say: “execute within same context”
Is this have special meaning in driver development world?

In our world, that almost always refers to user-mode process memory.

Or secret code that newbies like me, mustn’t understand but driver
developers communicate :slight_smile:

Every new activity has its own lingo. It’s just a matter of picking it up.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Windows does not use the TSS.

Under the normal circumstances it does not - all Windows processes run in context of a single task, as far as TSS is concerned. However, there are multiple TSS descriptors in GDT. The remaining ones come into the play upon the bugcheck -their purpose is to allow the system operate long enough to show a blue screen…

Anton Bassov

Thank you very much for the example.
Now, Understood.
Good works…

2008/4/17, Tim Roberts :
>
> serimc wrote:
>
> > You said:
> > “There is no context switch. CS, EIP, and ESP all change, but the page
> > tables (and hence CR3) remain the same”
> > Yes. Becaues of that i said it is all about cr3. Let me explain:
> >
> > In Intel Doc.
> > For Task Switch:
> > “The TSS state is loaded into the processor. This includes the LDTR
> > register, the PDBR (control register CR3), the EFLAGS registers, the EIP
> > register, the general-purpose registers, and the segment selectors.”
> >
>
> This is true, but Windows does not use the TSS.
>
>
> But there is nothing for thread switching. It is all about Windows. So i
> > looked SDK. This is CONTEXT structure:
> >
> > typedef struct _CONTEXT {
> > …
> > } CONTEXT;
> > Here all registers is changed except Control registers(especially cr3).
> >
>
> Yes, but again I would caution you that the word “context” has many
> meanings. You should not assume that the CONTEXT structure is used to store
> the context for a “context switch”.
>
>
> Can we say the difference between process and thread switch is related
> > cr3 register.
> >
>
> I think that is accurate, yes.
>
>
> And in Driver Development world.
> > If i read something that says: “executing within the context of
> > requester” means context switching doesn’t effect CR3.
> > Am i right?
> >
>
> I would not word it that way, but I believe you are correct. When
> something executes within the context of the requester, then the page tables
> (and CR3) are still set to whatever the current process needed. The key
> point is that a driver writer must not assume that it always executes in the
> context of whatever process last opened the driver using CreateFile for the
> driver, for instance. That’s a relatively common mistake.
>
>
> If changing CR3 means there is a task switch occurs, why do they
> > underline execute within this exception context?
> >
>
> “Task switch” is not well-defined in Windows. Changing CR3 means there
> was a “process switch”.
>
>
> Driver codes are not self executable, they must be called from running
> > application?
> >
>
> Or from an interrupt handler, or from an IRP completion routine, or from a
> timer callback, etc. Driver code can be called from many places.
>
> Here’s an example. Let’s say a user opens my driver using CreateFile, and
> then sends me an ioctl using DeviceIoControl. Let’s say the input buffer to
> DeviceIoControl contains a raw pointer to a user-mode buffer (which is a
> dangerous thing to do, partly because of what I’m about to describe). In my
> ioctl handler, I can use that user-mode address and read the data, because
> the page tables are still set to that process.
>
> OK, now let’s say I can’t finish the ioctl right away, so I mark it as
> pending and set up a timer callback. When I get the timer callback, I am in
> an “arbitrary process context”. That means I don’t know what process is in
> the page tables. If I now fetch that pending IRP and try to access the
> user-mode address, it will either crash (because the address is not valid),
> or access unknown memory in a different process.
>
>
> I confused because whatever i read say: “execute within same context” Is
> > this have special meaning in driver development world?
> >
>
> In our world, that almost always refers to user-mode process memory.
>
>
> Or secret code that newbies like me, mustn’t understand but driver
> > developers communicate :slight_smile:
> >
>
> Every new activity has its own lingo. It’s just a matter of picking it
> up.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>