Subject: Re: UVM - Kernel & User access question
To: Stephan Uphoff <ups@stups.com>
From: Eric Circlaeys <eric.c@mac.com>
List: tech-kern
Date: 10/18/2003 00:23:14
> error = uvm_map(&p->p_vmspace->vm_map, &handler, segment_size,
>> *object, 0, 0,
>> UVM_MAPFLAG(prot, prot, UVM_INH_SHARE, UVM_ADV_RANDOM, 0));
>
> p->p_vmspace->vm_map is the user space map of the process p.
> Since you want kernel space you need to use kernel_map instead
> error = uvm_map(kernel_map,....
I though as I called this from a kernel process p->p_vmspace->vm_map
was like kernel_map.
> I would also replace UVM_INH_SHARE with UVM_INH_NONE.
> ( Not that inheritance matters in the kernel ... )
I try in a second with all of that!!
>> strncpy(pointeur, "toto\0", 5);
>
> strncpy(pointeur, "toto\0", 5); is a dangerous way to access the
> memory.
> If the buffer is paged out and the swap is bad (disk error) you will
> get
> a kernel panic.
> Using kcopy/uiomove you can try to copy the memory - and the functions
> will
> just return an error on failure (no kernel panic).
You say that kcopy will avoid kernel panic if page is out,
how can I be sure that all the time I can read or write to my pageable
kernel memory.
Because as I understand kcopy will return an error if the page is out
but will not force the page to be up and wait for it to copy the data?
>> BUT questions:
>> Is that new allocated pointer available at any time physically?
>
> The memory is pageable and in kernel space.
> Since accessing it can cause a (major) page fault (sleep) the memory
> can
> not be accessed from interrupt context. (Unless wired before - making
> it
> non pageable)
> It should only be accessed using special functions (unless temporarily
> wired)
> to avoid kernel panics on swap space errors.
Is kcopy one of those functions?
What kind of other functions can I use to play with that memory and be
sure it is wired at a time for usage?
>> Is this using virtual space, or physical?
>
> pageable virtual space - physical pages are allocated by page faults
> and
> can change.
>
>> Is it similar to malloc used in kernel?
>
> malloc memory is not pageable.
Thank you a lot,
I am learning so much with you guys!!
Thanks for you time answering my poor questions!
Eric.
> Stephan
>
> Eric Circlaeys wrote:
>> Here the code I used:
>>
>> TEST is a test call used in a kthread.
>> And get a page fault...
>>
>> TEST
>> {
>> struct uvm_object *o;
>> char *pointeur;
>>
>> pointeur = (char *)nm_core_uvm_allocate(curproc, 6, &o);
>>
>> // tried
>> strncpy(pointeur, "toto\0", 5);
>> // or
>> copyout("toto\0", pointeur, 5);
>>
>> printf("%s", pointeur);
>>
>> nm_core_uvm_deallocate(p, 5, pointeur, o);
>> }
>>
>> void *nm_core_uvm_allocate(struct proc *p, int size,
>> struct uvm_object **object)
>> {
>> size_t segment_size;
>> vaddr_t handler;
>> vm_prot_t prot;
>> int error;
>>
>> segment_size = (size + PGOFSET) & ~PGOFSET;
>> *object = uao_create(segment_size, 0);
>> prot = VM_PROT_READ | VM_PROT_WRITE;
>> handler = round_page((vaddr_t)p->p_vmspace->vm_taddr + MAXTSIZ +
>> MAXDSIZ);
>>
>> uao_reference(*object);
>> error = uvm_map(&p->p_vmspace->vm_map, &handler, segment_size,
>> *object, 0, 0,
>> UVM_MAPFLAG(prot, prot, UVM_INH_SHARE, UVM_ADV_RANDOM, 0));
>> if (error)
>> {
>> printf("uvm_map failed\n");
>>
>> return (NULL);
>> }
>>
>> return ((void *)handler);
>> }
>>
>> void nm_core_uvm_deallocate(struct proc *p, int size, void *handler,
>> struct uvm_object *object)
>> {
>> size_t segment_size;
>>
>> segment_size = (size + PGOFSET) & ~PGOFSET;
>> uao_detach(object);
>> uvm_deallocate(&p->p_vmspace->vm_map, (vaddr_t)handler,
>> segment_size);
>> }
>>
>>
>> I just tried the following with your help and it works:
>>
>> TEST
>> {
>> char *pointeur;
>>
>> pointeur = (char *)uvm_km_valloc_wait(kernel_map, 10);
>>
>> strcpy(pointeur, "toto\0");
>>
>> printf("%s\n", pointeur);
>> }
>>
>> BUT questions:
>> Is that new allocated pointer available at any time physically?
>> Is this using virtual space, or physical?
>> Is it similar to malloc used in kernel?
>>
>> What I would like is to allocate large amount of data without using
>> physical kernel memory but using the vm, all of this in a kernel
>> process.
>> This data should be able to access in the kernel process for read and
>> write...
>>
>> Thank you a lot for your help.
>> Eric.
>>
>> On 17 oct. 03, at 03:49, Stephan Uphoff wrote:
>>
>>>
>>>> der Mouse wrote:
>>>>> Eric Circlaeys wrote:
>>>>> I would like to use UVM to allocate large memory in kernel land. I
>>>>> used uao_create, round_page, uvm_map to allocate virtual space.
>>>>
>>>> As I understand it, those allocate userland VM.
>>>
>>> Depends on the map passed to uvm_map().
>>> A kernel (sub) map will result in kernel virtual space.
>>>
>>> Do you need more than uvm_km_valloc_wait(kernel_map,
>>> sizeOfYourBuffer)
>>> ?
>>>
>>>>
>>>>> But now I would like to write and read inside those pages still
>>>>> being
>>>>> in kernel land. When I tried with copyout to write buffer inside
>>>>> it
>>>>> I got a page fault...
>>>
>>> copyin/copyin_proc from userspace to your buffer
>>> or kcopy from/to "normal" kernel space to/from your buffer.
>>> (or uiomove() as a parameter based wrapper around the functions
>>> above)
>>>
>>> You can also temporary wire the memory to access it without special
>>> functions.
>>> ( The only way to access it from interrupt context)
>>>
>>> Without more information is is hard to guess your problem.
>>>
>>>
>>> Stephan
>>>
>
>