I wrote a sample program to use __kernel_vsyscall for system call 
#include <stdio.h>
#include <sys/auxv.h>
int main()
{
    unsigned long sysinfo = getauxval(AT_SYSINFO);
    unsigned long syscall_num = 1;  // 1 is system call number for exit
    long exit_status = 42;
    asm ("movl %0, %%eax\n"
            "movl %1, %%ebx\n"
            "call *%2"
            :
            :"m" (syscall_num), "m" (exit_status), "m" (sysinfo)
            :"eax", "ebx");
    printf("sysinfo:%lx\n", sysinfo);
    return 0;
}
This code which calls exit(42) works fine.
$gcc userprog.c -o userprog -m32
$ ./userprog 
$ echo $?
42
But when I tried to call write(1, "hello world", 12), it failed
#include <stdio.h>
#include <sys/auxv.h>
int main()
{
    unsigned long sysinfo = getauxval(AT_SYSINFO);
    unsigned long syscall_num = 4;  // 4 is system call number for write
    char buffer[] = "hello world";
        int buffer_length = sizeof(buffer); 
    asm ("movl %0, %%eax\n"
            "movl %1, %%ebx\n"
            "movl %2, %%ecx\n"
            "movl %3, %%edx\n"
            "call *%2"
            :
            :"m" (syscall_num), "i"(1), "m" (buffer), "m"(buffer_length)
            :"eax", "ebx", "ecx");
    printf("sysinfo:%lx\n", sysinfo);
    return 0;
}
It fails with segmentation fault.
dmesg:
[43453.401815] userprog[13528]: segfault at 6c6c6568 ip 000000006c6c6568 sp 00000000ffc647ac error 14 in libc-2.27.so[f7cf3000+1d2000]
[43453.401821] Code: Bad RIP value.
 
    