1*433d6423SLionel Sambuc/* sections */ 2*433d6423SLionel Sambuc 3*433d6423SLionel Sambuc 4*433d6423SLionel Sambuc#include <minix/config.h> 5*433d6423SLionel Sambuc#include <minix/const.h> 6*433d6423SLionel Sambuc#include <machine/asm.h> 7*433d6423SLionel Sambuc#include <machine/interrupt.h> 8*433d6423SLionel Sambuc#include <machine/vm.h> 9*433d6423SLionel Sambuc#include "archconst.h" 10*433d6423SLionel Sambuc#include "kernel/const.h" 11*433d6423SLionel Sambuc#include "sconst.h" 12*433d6423SLionel Sambuc#include <machine/multiboot.h> 13*433d6423SLionel Sambuc 14*433d6423SLionel Sambuc 15*433d6423SLionel Sambuc/*===========================================================================*/ 16*433d6423SLionel Sambuc/* copy_msg_from_user */ 17*433d6423SLionel Sambuc/*===========================================================================*/ 18*433d6423SLionel Sambuc/* 19*433d6423SLionel Sambuc * int copy_msg_from_user(message * user_mbuf, message * dst); 20*433d6423SLionel Sambuc * 21*433d6423SLionel Sambuc * Copies a message of 64 bytes from user process space to a kernel buffer. This 22*433d6423SLionel Sambuc * function assumes that the process address space is installed (ttbr loaded). 23*433d6423SLionel Sambuc * 24*433d6423SLionel Sambuc * This function from the callers point of view either succeeds or returns an 25*433d6423SLionel Sambuc * error which gives the caller a chance to respond accordingly. In fact it 26*433d6423SLionel Sambuc * either succeeds or if it generates a pagefault, general protection or other 27*433d6423SLionel Sambuc * exception, the trap handler has to redirect the execution to 28*433d6423SLionel Sambuc * __user_copy_msg_pointer_failure where the error is reported to the caller 29*433d6423SLionel Sambuc * without resolving the pagefault. It is not kernel's problem to deal with 30*433d6423SLionel Sambuc * wrong pointers from userspace and the caller should return an error to 31*433d6423SLionel Sambuc * userspace as if wrong values or request were passed to the kernel 32*433d6423SLionel Sambuc */ 33*433d6423SLionel SambucENTRY(copy_msg_from_user) 34*433d6423SLionel Sambuc push {r4-r10, lr} 35*433d6423SLionel Sambuc /* load the source pointer */ 36*433d6423SLionel Sambuc mov r9, r0 37*433d6423SLionel Sambuc /* load the destination pointer */ 38*433d6423SLionel Sambuc mov r10, r1 39*433d6423SLionel Sambuc /* do the copy, first 32 bytes */ 40*433d6423SLionel Sambuc ldm r9, {r0-r7} 41*433d6423SLionel Sambuc stm r10, {r0-r7} 42*433d6423SLionel Sambuc 43*433d6423SLionel Sambuc /* next 32 bytes */ 44*433d6423SLionel Sambuc add r9, r9, #32 45*433d6423SLionel Sambuc add r10, r10, #32 46*433d6423SLionel Sambuc ldm r9, {r0-r7} 47*433d6423SLionel Sambuc stm r10, {r0-r7} 48*433d6423SLionel Sambuc 49*433d6423SLionel SambucLABEL(__copy_msg_from_user_end) 50*433d6423SLionel Sambuc pop {r4-r10, lr} 51*433d6423SLionel Sambuc mov r0, #0 52*433d6423SLionel Sambuc bx lr 53*433d6423SLionel Sambuc 54*433d6423SLionel Sambuc/*===========================================================================*/ 55*433d6423SLionel Sambuc/* copy_msg_to_user */ 56*433d6423SLionel Sambuc/*===========================================================================*/ 57*433d6423SLionel Sambuc/* 58*433d6423SLionel Sambuc * void copy_msg_to_user(message * src, message * user_mbuf); 59*433d6423SLionel Sambuc * 60*433d6423SLionel Sambuc * Copies a message of 64 bytes to user process space from a kernel buffer. 61*433d6423SLionel Sambuc * 62*433d6423SLionel Sambuc * All the other copy_msg_from_user() comments apply here as well! 63*433d6423SLionel Sambuc */ 64*433d6423SLionel SambucENTRY(copy_msg_to_user) 65*433d6423SLionel Sambuc push {r4-r10, lr} 66*433d6423SLionel Sambuc /* load the source pointer */ 67*433d6423SLionel Sambuc mov r9, r0 68*433d6423SLionel Sambuc /* load the destination pointer */ 69*433d6423SLionel Sambuc mov r10, r1 70*433d6423SLionel Sambuc /* do the copy, first 32 bytes */ 71*433d6423SLionel Sambuc ldm r9, {r0-r7} 72*433d6423SLionel Sambuc stm r10, {r0-r7} 73*433d6423SLionel Sambuc 74*433d6423SLionel Sambuc /* next 32 bytes */ 75*433d6423SLionel Sambuc add r9, r9, #32 76*433d6423SLionel Sambuc add r10, r10, #32 77*433d6423SLionel Sambuc ldm r9, {r0-r7} 78*433d6423SLionel Sambuc stm r10, {r0-r7} 79*433d6423SLionel Sambuc 80*433d6423SLionel SambucLABEL(__copy_msg_to_user_end) 81*433d6423SLionel Sambuc pop {r4-r10, lr} 82*433d6423SLionel Sambuc mov r0, #0 83*433d6423SLionel Sambuc bx lr 84*433d6423SLionel Sambuc 85*433d6423SLionel Sambuc/* 86*433d6423SLionel Sambuc * if a function from a selected set of copies from or to userspace fails, it is 87*433d6423SLionel Sambuc * because of a wrong pointer supplied by the userspace. We have to clean up and 88*433d6423SLionel Sambuc * and return -1 to indicated that something wrong has happend. The place it was 89*433d6423SLionel Sambuc * called from has to handle this situation. The exception handler redirect us 90*433d6423SLionel Sambuc * here to continue, clean up and report the error 91*433d6423SLionel Sambuc */ 92*433d6423SLionel SambucENTRY(__user_copy_msg_pointer_failure) 93*433d6423SLionel Sambuc pop {r4-r10, lr} 94*433d6423SLionel Sambuc mov r0, #-1 95*433d6423SLionel Sambuc bx lr 96*433d6423SLionel Sambuc 97*433d6423SLionel SambucENTRY(intr_enable) 98*433d6423SLionel SambucENTRY(interrupts_enable) 99*433d6423SLionel Sambuc dsb 100*433d6423SLionel Sambuc cpsie if 101*433d6423SLionel Sambuc bx lr 102*433d6423SLionel Sambuc 103*433d6423SLionel SambucENTRY(intr_disable) 104*433d6423SLionel SambucENTRY(interrupts_disable) 105*433d6423SLionel Sambuc dsb 106*433d6423SLionel Sambuc cpsid if 107*433d6423SLionel Sambuc bx lr 108