Skip to content

Commit

Permalink
usermode: add simple printf() system call
Browse files Browse the repository at this point in the history
The printf() system call accepts only 4 parameters: format string and
for parameters for it. There is no variadic parameters support and
there is also no checks for the sanity of the format string vs parameters
list. Use with care.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Jul 22, 2022
1 parent 067f393 commit d120274
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
31 changes: 31 additions & 0 deletions common/usermode.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void __naked syscall_handler(void) {
(void) param1;
register unsigned long param2 asm(STR(_ASM_SI));
(void) param2;
register unsigned long param3 asm(STR(_ASM_BX));
(void) param3;
register unsigned long param4 asm(STR(_ASM_DX));
(void) param4;

SAVE_CLOBBERED_REGS();
switch_address_space(&cr3);
swapgs();
Expand All @@ -107,6 +112,11 @@ void __naked syscall_handler(void) {
_sys_exit();
UNREACHABLE();

case SYSCALL_PRINTF:
printk(_ptr(param1), param2, param3, param4);
syscall_return(0);
break;

case SYSCALL_MMAP: {
void *va = _ptr(param1);
unsigned int order = _u(param2);
Expand Down Expand Up @@ -176,6 +186,22 @@ static inline void __user_text sys_exit(unsigned long exit_code) {
asm volatile("syscall" ::"A"(SYSCALL_EXIT), "D"(exit_code) : STR(_ASM_CX), "r11");
}

static inline long __user_text sys_printf(const char *fmt, unsigned long arg1,
unsigned long arg2, unsigned long arg3) {
register unsigned long rax asm(STR(_ASM_AX));

/* clang-format off */
asm volatile(
"syscall"
: "=A"(rax)
: "0"(SYSCALL_PRINTF), "D"(fmt), "S"(arg1), "b"(arg2), "d"(arg3)
: STR(_ASM_CX), "r11"
);
/* clang-format on */

return rax;
}

static inline long __user_text sys_mmap(void *va, unsigned long order) {
register unsigned long rax asm(STR(_ASM_AX));

Expand Down Expand Up @@ -209,6 +235,11 @@ void __user_text exit(unsigned long exit_code) {
sys_exit(exit_code);
}

void __user_text printf(const char *fmt, unsigned long arg1, unsigned long arg2,
unsigned long arg3) {
sys_printf(fmt, arg1, arg2, arg3);
}

void *__user_text mmap(void *va, unsigned long order) {
return _ptr(sys_mmap(va, order));
}
Expand Down
3 changes: 3 additions & 0 deletions include/usermode.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define KTF_USERMODE_H

#define SYSCALL_EXIT 0
#define SYSCALL_PRINTF 1
#define SYSCALL_MMAP 2
#define SYSCALL_MUNMAP 3

Expand Down Expand Up @@ -53,6 +54,8 @@ extern void __naked syscall_handler(void);
extern void init_usermode(percpu_t *percpu);

extern void __user_text exit(unsigned long exit_code);
extern void __user_text printf(const char *fmt, unsigned long arg1, unsigned long arg2,
unsigned long arg3);
extern void *__user_text mmap(void *va, unsigned long order);
extern void __user_text munmap(void *va, unsigned long order);

Expand Down

0 comments on commit d120274

Please sign in to comment.