Page 1 of 1

x86: how to access data at "user-mode" address, from kernel?

Posted: Sat Apr 04, 2015 12:23 pm
by amn
Hi all,

I am dreaded that this has slipped my curiosity for so long. Granted, I am no expert at paging and protection yet, but I have done some extensive googling both on osdev wiki and even reaching some Quora pages, with more or less useful information there.

Say I have a kernel function exposed to user-mode processes through a system call. The "kernel-mode" function signature is as follows.

Code: Select all

int _foo(char* buf);
If this function were to fill the specified buffer, since the value of `buf` - the address - is supplied by the process itself and is probably a virtual address, how can kernel access the data at its physical address counterpart? The virtual address may be a statically allocated `char arr[1024]` in process data segment, for example. When `_foo` is executed by the kernel, the address space is different, is it not?

In other words, when a process ends up invoking `_foo` through a syscall mechanism, with `buf` being the virtual address of the abovementioned `arr`, say 0x1000, then for the kernel the same address value 0x1000 is something at a different physical memory location, no? I mean what for the invoking process is virtual address, is for kernel a physical address or virtual address that is subject to different translation parameters?

This is a homework thing, but I see no address conversion functions in the kernel I have in front of me, nothing like `copy_to_user`which Linux seems to be doing. This seems like a glaring hole I am supposed to fill, but I am a bit at loss here.

Just point me to a page in wiki, if this is obvious, but I could not find anything that would explain to me what's going on. Am I missing something obvious again? (tm)(c)(R)

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 1:43 pm
by iansjack
Why would a system call switch to a different page table?

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 2:32 pm
by Brendan
Hi,
amn wrote:In other words, when a process ends up invoking `_foo` through a syscall mechanism, with `buf` being the virtual address of the abovementioned `arr`, say 0x1000, then for the kernel the same address value 0x1000 is something at a different physical memory location, no? I mean what for the invoking process is virtual address, is for kernel a physical address or virtual address that is subject to different translation parameters?
Typically each process has its own virtual address space and uses the lower half of it, and the kernel is mapped into upper half of every virtual address space. This means that for your "int _foo(char* buf);" the kernel can access the data at "buf" by its virtual address without problems (and has no reason to care what the physical address is). Of course security is important and the kernel would need to check that the pointer is sane (e.g. points to something in user space and not kernel space, points to a page that's present, etc), and would need to do that for each page containing the data (e.g. in case it's a string that begins in user-space but ends in kernel space).

Normally the only things in the entire OS that use physical addresses are device drivers that use DMA or bus mastering (because the hardware/device doesn't know about paging) and the kernel's virtual memory management (so it can map things into virtual address spaces). Everything else uses virtual addresses and doesn't know or care about physical addresses.


Cheers,

Brendan

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 2:35 pm
by amn
iansjack wrote:Why would a system call switch to a different page table?
How do you figure it would?

I never said it does? What I said was that I am afraid that in kernel mode, address 0x1000 is a different physical location than the same address in user mode, and that it obviously creates a problem where a kernel procedure has to fill out data at an address supplied by a user-level process.

Are you saying that since page tables are not switched (I don't know if they even play a role in the kernel), then 0x1000 points to the same physical location in both kernel and the process that made the syscall?

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 2:46 pm
by cmdrcoriander
amn wrote:
iansjack wrote:Why would a system call switch to a different page table?
How do you figure it would?

I never said it does? What I said was that I am afraid that in kernel mode, address 0x1000 is a different physical location than the same address in user mode, and that it obviously creates a problem where a kernel procedure has to fill out data at an address supplied by a user-level process.

Are you saying that since page tables are not switched (I don't know if they even play a role in the kernel), then 0x1000 points to the same physical location in both kernel and the process that made the syscall?
Yes, that's exactly what he's saying. Without a page table switch, which the kernel has to do explicitly, how would 0x1000 suddenly point to a different physical location?

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 3:12 pm
by iansjack
amn wrote:
iansjack wrote:Why would a system call switch to a different page table?
How do you figure it would?

I never said it does? What I said was that I am afraid that in kernel mode, address 0x1000 is a different physical location than the same address in user mode, and that it obviously creates a problem where a kernel procedure has to fill out data at an address supplied by a user-level process.

Are you saying that since page tables are not switched (I don't know if they even play a role in the kernel), then 0x1000 points to the same physical location in both kernel and the process that made the syscall?
What do you suppose page tables are for?

They map virtual addresses to physical addresses. It's as simple as that.

Your question would be relevant in a micro-kernel that used separate processes, with their own address spaces, to service - for example - the file system as you would then need some means to translate the addresses of one process to another. Often this is done be sharing a page between processes. But the kernel itself is just a set of functions that the user processes can call, via system calls, and these routines run under the same address space as the user process. (Obviously there's a little more to the kernel than this, but that's it as far as system calls are concerned.)

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 3:23 pm
by amn
Ah, i see now. So when the call "descends" from ring 3 to ring 0, the same virtual address translation still applies.

Thank you for explaining the what now seems obvious.

Could you guys give me some nice links to read up on, since I was not able to find any text on my own? This usually happens when one searches for the wrong keywords, I guess.

I have the Intel triple volume manual, which I too seldom pick up.

Re: x86: how to access data at "user-mode" address, from ker

Posted: Sat Apr 04, 2015 3:56 pm
by iansjack
You've already supplied the best reference. I'd recommend that you make a point of reading those manuals, at least - for present purposes - the chapter on paging. You could also look at this tutorial which you may find simpler: http://www.cirosantilli.com/x86-paging/ . But, in the end, the Intel manuals are the bible on how the processor works.