Example #1
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned short *data, *ptr;
    char *bits;
    pixel_set_t pixel_set;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}
    
    switch (info->var.bits_per_pixel) {
    case 16:
        pixel_set = memset16;
        break;
    case 32:
        pixel_set = pixel_set_rgba;
        break;
    default:
		printk(KERN_WARNING "%s: Can not find pixel_set operation\n",
			__func__);    
		return -EDOM;
    }

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	bits = info->screen_base;
	while (count > 3) {
		unsigned n = ptr[0];
		if (n > max)
			break;
		bits += pixel_set(bits, ptr[1], n);
		max -= n;
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
int ts_calibration_for_touch_key_region(char *filename, int *cal_data)
{
    int fd, err = 0;
    int count, i,j,ii, count1 = 0;
    int cal_data_count = 0;

    char data1[50]= {0,};
    char data2[10]= {0,};
    int  value = 0, value1 = 0;
    mm_segment_t old_fs = get_fs();

    set_fs(KERNEL_DS);

    printk("[SWIFT]TS_CAL. sys_open-- for READ........\n");
    fd = sys_open(filename, O_RDWR, 0);
    if (fd < 0) {
        printk(KERN_WARNING "%s: Can not open %s\n",
               __func__, filename);
        return -ENOENT;
    }

    printk("[SWIFT]TS_CAL. sys_lseek........\n");
    count = sys_lseek(fd, (off_t)0, 2);
    if (count == 0) {
        printk("[SWIFT]TS_CAL. sys_lseek ERROR count == 0........\n");
        err = -EIO;
        goto err_close_file;
    }

    sys_lseek(fd, (off_t)0, 0);

    printk("[SWIFT]TS_CAL. kmalloc......count[%d]..\n",count);
    printk("[SWIFT] sys_read........\n");

    (unsigned)sys_read(fd, (char *)data1, count);

    count1 = 0;
    for(i =0 ; i < count ; i++) {
        //printk("data[%d]=0x%x\n",i,data1[i]);
        if((data1[i]== 0x2C)||(data1[i]== 0x0D)||data1[i]== 0x0A) {
            ii = 0;
            value = 0;

            while(count1 > 0) {
                count1-=1;

                for(j=0, value1=1; j < count1 ; j++)
                    value1*= 10;

                value +=(data2[ii]-0x30)*value1;
                //printk("[SWIFT]ii[%d] FIND value[%d]..data2[%d]... count1[%d]\n",ii,value,data2[ii],count1);

                if (count1 == 0) {
                    cal_data[cal_data_count] = value;
                    cal_data_count++;
                }

                ii++;
            }

            memset(data2,0x00,sizeof(data2));
            count1 = 0;
        }
        else {
            data2[count1]= data1[i];
            //printk("[SWIFT] count1[%d]..data2[0x%x]....data1[0x%x]..i[%d]...\n",count1,data2[count1],data1[i],i);
            count1+=1;
        }
    }

    printk("[SWIFT]TS_CAL. sys_close........\n");
    sys_close(fd);
    set_fs(old_fs);

    return 0;

err_close_file:
    printk("[SWIFT]err_close_file!!........\n");
    sys_close(fd);
    set_fs(old_fs);
    return err;

}
Example #3
0
static int syscall_dispatch(uint32_t sysnum, uint32_t args, regs_t *regs)
{
        switch (sysnum) {
                case SYS_waitpid:
                        return sys_waitpid((waitpid_args_t *)args);

                case SYS_exit:
                        do_exit((int)args);
                        panic("exit failed!\n");
                        return 0;

                case SYS_thr_exit:
                        kthread_exit((void *)args);
                        panic("thr_exit failed!\n");
                        return 0;

                case SYS_thr_yield:
                        sched_make_runnable(curthr);
                        sched_switch();
                        return 0;

                case SYS_fork:
                        return sys_fork(regs);

                case SYS_getpid:
                        return curproc->p_pid;

                case SYS_sync:
                        sys_sync();
                        return 0;

#ifdef __MOUNTING__
                case SYS_mount:
                        return sys_mount((mount_args_t *) args);

                case SYS_umount:
                        return sys_umount((argstr_t *) args);
#endif

                case SYS_mmap:
                        return (int) sys_mmap((mmap_args_t *) args);

                case SYS_munmap:
                        return sys_munmap((munmap_args_t *) args);

                case SYS_open:
                        return sys_open((open_args_t *) args);

                case SYS_close:
                        return sys_close((int)args);

                case SYS_read:
                        return sys_read((read_args_t *)args);

                case SYS_write:
                        return sys_write((write_args_t *)args);

                case SYS_dup:
                        return sys_dup((int)args);

                case SYS_dup2:
                        return sys_dup2((dup2_args_t *)args);

                case SYS_mkdir:
                        return sys_mkdir((mkdir_args_t *)args);

                case SYS_rmdir:
                        return sys_rmdir((argstr_t *)args);

                case SYS_unlink:
                        return sys_unlink((argstr_t *)args);

                case SYS_link:
                        return sys_link((link_args_t *)args);

                case SYS_rename:
                        return sys_rename((rename_args_t *)args);

                case SYS_chdir:
                        return sys_chdir((argstr_t *)args);

                case SYS_getdents:
                        return sys_getdents((getdents_args_t *)args);

                case SYS_brk:
                        return (int) sys_brk((void *)args);

                case SYS_lseek:
                        return sys_lseek((lseek_args_t *)args);

                case SYS_halt:
                        sys_halt();
                        return -1;

                case SYS_set_errno:
                        curthr->kt_errno = (int)args;
                        return 0;

                case SYS_errno:
                        return curthr->kt_errno;

                case SYS_execve:
                        return sys_execve((execve_args_t *)args, regs);

                case SYS_stat:
                        return sys_stat((stat_args_t *)args);

                case SYS_uname:
                        return sys_uname((struct utsname *)args);

                case SYS_debug:
                        return sys_debug((argstr_t *)args);
                case SYS_kshell:
                        return sys_kshell((int)args);
                default:
                        dbg(DBG_ERROR, "ERROR: unknown system call: %d (args: %#08x)\n", sysnum, args);
                        curthr->kt_errno = ENOSYS;
                        return -1;
        }
}
Example #4
0
COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence)
{
	return sys_lseek(fd, offset, whence);
}
Example #5
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename, bool bf_supported)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned short *data, *bits, *ptr;
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
	struct module *owner;
#endif
	int pad;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
	owner = info->fbops->owner;
	if (!try_module_get(owner))
		return -ENODEV;
	if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) {
		module_put(owner);
		return -ENODEV;
	}
#endif

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	if (bf_supported && (info->node == 1 || info->node == 2)) {
		err = -EPERM;
		pr_err("%s:%d no info->creen_base on fb%d!\n",
		       __func__, __LINE__, info->node);
		goto err_logo_free_data;
	}
	if (info->screen_base) {
		bits = (unsigned short *)(info->screen_base);
		while (count > 3) {
			unsigned n = ptr[0];
			if (n > max)
				break;
			if (info->var.bits_per_pixel >= 24) {
				pad = memset16_rgb8888(bits, ptr[1], n << 1, info);
				bits += n << 1;
				bits += pad;
			} else {
			memset16(bits, ptr[1], n << 1);
			bits += n;
			}
			max -= n;
			ptr += 2;
			count -= 4;
		}
	}
	err = 0;
err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
Example #6
0
/*****************************************************************************
 函 数 名  : power_on_log_save
 功能描述  : 保存开机log
 输入参数  :
 输出参数  : 无
 返 回 值  :
 调用函数  :
 被调函数  :
*****************************************************************************/
static int power_on_log_save( void )
{
    long pos;
    unsigned int pf;
    mm_segment_t old_fs;
    ssize_t rt = 0;
    char buf[128] = {0};
    struct rtc_time tm;
    char *power_on_reason[4];
#if (MBB_CHARGE == FEATURE_ON)
    char *power_on_mode[5];
#else
    char *power_on_mode[3];
#endif
    BATT_LEVEL_ENUM  battery_level;

    tm = power_item_info.time;
    battery_level = chg_get_batt_level();


    power_on_reason[0] = "Charger";
    power_on_reason[1] = "Power Key";
    power_on_reason[2] = "Warm Reset";
    power_on_reason[3] = "Unknown";
#if (MBB_CHG_PLATFORM_V7R2 == FEATURE_ON)
    power_on_mode[0] = "EXCEPTION";
    power_on_mode[1] = "NORMAL";
    power_on_mode[2] = "PWN CHARGING";
	power_on_mode[3] = "UPDATE";
    power_on_mode[4] = "INVALID";
#else
    power_on_mode[0] = "PWN CHARGING";
    power_on_mode[1] = "NORMAL";
    power_on_mode[2] = "UPDATE";
#endif
    /* 记录开机信息(时间、次数、关机原因) */
    snprintf(buf, sizeof(buf) - 1, "power on reason(E5): %s, power on mode : %s, current battery voltage: %d, current time: %4d-%02d-%02d %02d:%02d:%02d\r\n", \
            power_on_reason[power_item_info.reason], power_on_mode[power_item_info.mode], battery_level, tm.tm_year, tm.tm_mon, \
            tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

    #if ( FEATURE_ON == MBB_MLOG )
    mlog_print(MLOG_POWER, mlog_lv_info, "POWERON mode %s\n" ,power_on_mode[power_item_info.mode]);
    mlog_print(MLOG_POWER, mlog_lv_info, "POWERON due to %s\n" ,power_on_reason[power_item_info.reason]);
    mlog_set_statis_info("on_times",1); 
    #endif

    old_fs = get_fs(); //lint !e63

    set_fs(KERNEL_DS);

    /*coverity[check_return] */
    pf = (unsigned int)sys_open(EXCH_POWER_LOG_PATH, O_RDWR | O_CREAT, 0666);
    /*coverity[unchecked_value] */
    if(IS_ERR((const void*)pf))
    {
        pr_dbg( "error occured happened when open file %s, exiting.\n", EXCH_POWER_LOG_PATH);
        return (int)pf;
    }

    /*coverity[unchecked_value] */
    pos = sys_lseek(pf, 0, SEEK_END);
    if(pos > EXCH_ONOFF_LOG_MAX){
        /* 文件超过 16k,删除重新打开 */
        sys_rmdir(EXCH_POWER_LOG_PATH);
        /*coverity[check_return] */
        pf = (unsigned int)sys_open(EXCH_POWER_LOG_PATH, O_RDWR | O_CREAT, 0666);
        /*coverity[unchecked_value] */
        if(IS_ERR((const void*)pf))
        {
            pr_dbg( "error occured happened when open file %s, exiting.\n", EXCH_POWER_LOG_PATH);
            return (int)pf;
        }
    }
    else{
        /*coverity[unchecked_value] */
        sys_lseek(pf, pos, SEEK_SET);
    }

    /*coverity[unchecked_value] */
    rt = sys_write(pf, (const char*)buf, strlen(buf));
    if(rt<0)
    {
        pr_dbg("error occured happened when write file %s, exiting.\n", EXCH_POWER_LOG_PATH);
        /*coverity[unchecked_value] */
        sys_close(pf);
        set_fs(old_fs);
        return (int)rt;
    }

    /*coverity[unchecked_value] */
    sys_close(pf);
    set_fs(old_fs);

    pr_dbg(KERN_DEBUG "power on log save.\n ");

    return (int)rt;
}
Example #7
0
int load_565rle_image(char *filename, bool bf_supported)
{
    int fd, err = 0;
    unsigned count, max;
    unsigned short *data, *bits, *ptr;
    struct fb_info *info;
#if 0
    struct module *owner;
#endif
    info = registered_fb[0];

    if (!info) {
        printk(KERN_WARNING "%s: Can not access framebuffer\n",
               __func__);
        return -ENODEV;
    }
#if 0
    owner = info->fbops->owner;
    if (!try_module_get(owner))
        return NULL;
    if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) {
        module_put(owner);
        return NULL;
    }
#endif
    fd = sys_open(filename, O_RDONLY, 0);
    if (fd < 0) {
        printk(KERN_WARNING "%s: Can not open %s\n",
               __func__, filename);
        return -ENOENT;
    }
    printk("%s: open OK! %s\n",__func__, filename);
    count = (unsigned)sys_lseek(fd, (off_t)0, 2);
    if (count == 0) {
        sys_close(fd);
        err = -EIO;
        goto err_logo_close_file;
    }
    printk("%s: count %d\n",__func__, count);
    sys_lseek(fd, (off_t)0, 0);
    data = kmalloc(count, GFP_KERNEL);
    if (!data) {
        printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
        err = -ENOMEM;
        goto err_logo_close_file;
    }
    if ((unsigned)sys_read(fd, (char *)data, count) != count) {
        err = -EIO;
        goto err_logo_free_data;
    }

    max = fb_width(info) * fb_height(info);

    ptr = data;
    bits = (unsigned short *)(info->screen_base);
    printk("%s: max %d, n %d 0x%x\n",__func__, max, ptr[0], (unsigned int)bits);
    while (count > 3) {
        unsigned n = ptr[0];
        if (n > max)
            break;

        memset16_rgb8888(bits, ptr[1], n << 1);
        bits += n*2; // for rgb8888
        max -= n;
        ptr += 2;
        count -= 4;
    }
#if !defined (CONFIG_USA_OPERATOR_ATT) && !defined (CONFIG_JPN_MODEL_SC_03D) && !defined (CONFIG_CAN_OPERATOR_RWC)
    if (!is_lpcharging_state() && !sec_debug_is_recovery_mode())
        s3cfb_start_progress(info);
#endif

err_logo_free_data:
    kfree(data);
err_logo_close_file:
    sys_close(fd);
    return err;
}
Example #8
0
int smbrun(char *cmd, int *outfd)
{
	pid_t pid;
	uid_t uid = current_user.uid;
	gid_t gid = current_user.gid;
	
	/*
	 * Lose any kernel oplock capabilities we may have.
	 */
	oplock_set_capability(False, False);

	/* point our stdout at the file we want output to go into */

	if (outfd && ((*outfd = setup_out_fd()) == -1)) {
		return -1;
	}

	/* in this method we will exec /bin/sh with the correct
	   arguments, after first setting stdout to point at the file */

	/*
	 * We need to temporarily stop CatchChild from eating
	 * SIGCLD signals as it also eats the exit status code. JRA.
	 */

	CatchChildLeaveStatus();
                                   	
	if ((pid=sys_fork()) < 0) {
		DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
		CatchChild(); 
		if (outfd) {
			close(*outfd);
			*outfd = -1;
		}
		return errno;
    }

	if (pid) {
		/*
		 * Parent.
		 */
		int status=0;
		pid_t wpid;

		
		/* the parent just waits for the child to exit */
		while((wpid = sys_waitpid(pid,&status,0)) < 0) {
			if(errno == EINTR) {
				errno = 0;
				continue;
			}
			break;
		}

		CatchChild(); 

		if (wpid != pid) {
			DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
			if (outfd) {
				close(*outfd);
				*outfd = -1;
			}
			return -1;
		}

		/* Reset the seek pointer. */
		if (outfd) {
			sys_lseek(*outfd, 0, SEEK_SET);
		}

#if defined(WIFEXITED) && defined(WEXITSTATUS)
		if (WIFEXITED(status)) {
			return WEXITSTATUS(status);
		}
#endif

		return status;
	}
	
	CatchChild(); 
	
	/* we are in the child. we exec /bin/sh to do the work for us. we
	   don't directly exec the command we want because it may be a
	   pipeline or anything else the config file specifies */
	
	/* point our stdout at the file we want output to go into */
	if (outfd) {
		close(1);
		if (dup2(*outfd,1) != 1) {
			DEBUG(2,("Failed to create stdout file descriptor\n"));
			close(*outfd);
			exit(80);
		}
	}

	/* now completely lose our privileges. This is a fairly paranoid
	   way of doing it, but it does work on all systems that I know of */

	become_user_permanently(uid, gid);

	if (getuid() != uid || geteuid() != uid ||
	    getgid() != gid || getegid() != gid) {
		/* we failed to lose our privileges - do not execute
                   the command */
		exit(81); /* we can't print stuff at this stage,
			     instead use exit codes for debugging */
	}
	
#ifndef __INSURE__
	/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
	   2 point to /dev/null from the startup code */
	{
	int fd;
	for (fd=3;fd<256;fd++) close(fd);
	}
#endif

	execl("/bin/sh","sh","-c",cmd,NULL);  
	
	/* not reached */
	exit(82);
	return 1;
}
Example #9
0
/*
 *  Generic syscall handler.
 *
 *  Returns 0 if syscall number is not handled by this
 *  module, 1 otherwise. This allows applications to
 *  extend the syscall handler by using exception chaining.
 */
int
_bsp_do_syscall(int func,		/* syscall function number */
		long arg1, long arg2,	/* up to four args.        */
		long arg3, long arg4,
		int *retval)		/* syscall return value    */
{
    int err = 0;

    switch (func) {

      case SYS_read:
	err = sys_read((int)arg1, (char *)arg2, (int)arg3);
	break;

      case SYS_write:
	err = sys_write((int)arg1, (char *)arg2, (int)arg3);
	break;

      case SYS_open:
	err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
	break;

      case SYS_close:
	err = sys_close((int)arg1);
	break;

      case SYS_lseek:
	err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
	break;

      case BSP_GET_SHARED:
	*(bsp_shared_t **)arg1 = bsp_shared_data;
	break;

      case SYS_meminfo:
        {
          // Return the top and size of memory.
          struct bsp_mem_info      mem;
          int                      i;
          unsigned long            u, totmem, topmem, numbanks;

          i = totmem = topmem = numbanks = 0;
          while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0)
            {
              if (mem.kind == BSP_MEM_RAM)
                {
                  numbanks++;
                  totmem += mem.nbytes;
                  u = (unsigned long)mem.virt_start + mem.nbytes;
                  if (u > topmem)
                    topmem = u;
                }
            }
          *(unsigned long *)arg1 = totmem;
          *(unsigned long *)arg2 = topmem;
          *retval = numbanks;
        }
        return 1;
        break;

      default:
	return 0;
    }    

    *retval = err;
    return 1;
}
Example #10
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	/* note the casts to userptr_t */

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;


	    /* process calls */

	    case SYS_fork:
		err = sys_fork(tf, &retval);
		break;

	    case SYS_execv:
		err = sys_execv(
			(userptr_t)tf->tf_a0,
			(userptr_t)tf->tf_a1);
		break;

	    case SYS__exit:
		sys__exit(tf->tf_a0);
		panic("Returning from exit\n");

	    case SYS_waitpid:
		err = sys_waitpid(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2, 
			&retval);
		break;

	    case SYS_getpid:
		err = sys_getpid(&retval);
		break;


	    /* file calls */

	    case SYS_open:
		err = sys_open(
			(userptr_t)tf->tf_a0,
			tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;

	    case SYS_dup2:
		err = sys_dup2(
			tf->tf_a0,
			tf->tf_a1,
			&retval);
		break;

	    case SYS_close:
		err = sys_close(tf->tf_a0);
		break;

	    case SYS_read:
		err = sys_read(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;
	    case SYS_write:
		err = sys_write(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;
	    case SYS_lseek:
		{
			/*
			 * Because the position argument is 64 bits wide,
			 * it goes in the a2/a3 registers and we have to
			 * get "whence" from the stack. Furthermore, the
			 * return value is 64 bits wide, so the extra
			 * part of it goes in the v1 register.
			 *
			 * This is a trifle messy.
			 */
			uint64_t offset;
			int whence;
			off_t retval64;

			join32to64(tf->tf_a2, tf->tf_a3, &offset);

			err = copyin((userptr_t)tf->tf_sp + 16,
				     &whence, sizeof(int));
			if (err) {
				break;
			}

			err = sys_lseek(tf->tf_a0, offset, whence, &retval64);
			if (err) {
				break;
			}

			split64to32(retval64, &tf->tf_v0, &tf->tf_v1);
			retval = tf->tf_v0;
		}	
		break;

	    case SYS_chdir:
		err = sys_chdir((userptr_t)tf->tf_a0);
		break;

	    case SYS___getcwd:
		err = sys___getcwd(
			(userptr_t)tf->tf_a0,
			tf->tf_a1,
			&retval);
		break;


	    /* Even more system calls will go here */

 
	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
Example #11
0
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	uint32_t v0, v1;
	off_t pos;
	int whence;
	//userptr_t *status;

	struct stat statbuf;


	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);	 /* the syscall ov*/
		break;

	    case SYS_open:
	    err = sys_open((const_userptr_t)tf->tf_a0, tf->tf_a1, (mode_t)tf ->tf_a2, &retval);
	    break;

	    case SYS_close:
	    err = sys_close((tf->tf_a0),&retval);
	    break;

	    case SYS_read:
	    	err = sys_read(tf->tf_a0, (userptr_t)tf->tf_a1, (size_t)tf -> tf_a2, &retval);
	    	//retval = (int32_t)bytes;
	    	break;

	    case SYS_write:
	   	    err = sys_write(tf->tf_a0, (userptr_t)tf->tf_a1, (size_t)tf -> tf_a2, &retval);
	   	    //retval = (int32_t)bytes;
	   	    break;

	    case SYS_lseek:
	    	pos = tf->tf_a2;
	    	pos = pos << 32;
	    	pos += tf -> tf_a3;
	    	err = copyin((const_userptr_t)tf->tf_sp+16,&whence,sizeof(int));
	    	if(err)
	    	{
	    		break;
	    	}
	    	err = sys_lseek(tf->tf_a0, pos, whence, &v0, &v1);
	    	if(err)
	    	{
	    		break;
	    	}
	    	retval = v0;
	    	tf->tf_v1 = v1;
	    	break;

	    case SYS__exit:

	    	sys__exit(tf->tf_a0);


//			We are only here because of one of 2 reasons. We tried to kill the initial thread
//			while there was/were (an) immediate child(ren) of it running.

//			*NOTE* I'm actually NOT sure if that's a valid reason to be here

//			Second reason? Something went horribly, horribly wrong
	    	err = 0;
	    	break;
 
	    case SYS_dup2:

	    	err = sys_dup2(tf->tf_a0,tf->tf_a1,&retval);
	    	break;

	    case SYS_fstat:

	    	err = sys_fstat(tf->tf_a0, &statbuf);
	    	break;

	    case SYS_fork:
	    	err = sys_fork(tf, &retval);
	    	break;

	    case SYS_getpid:
	    	err = sys_getpid(&retval);
	    	break;

	    case SYS_waitpid:
	    	err = sys_waitpid(tf->tf_a0, (int*)tf->tf_a1, (int)tf->tf_a2, &retval);
	    	break;

	    case SYS___getcwd:

	    	err = sys___getcwd((char*)tf->tf_a0,(size_t)tf->tf_a1,&retval);
	    	break;

	    case SYS_chdir:
	    	err = sys_chdir((char*)tf->tf_a0,&retval);
	    	break;

	    case SYS_execv:
	    	err = sys_execv((const char*)tf->tf_a0, (char**)tf->tf_a1);
	    	break;
	    case SYS_sbrk:
	    	err = sbrk((int)tf->tf_a0,&retval);
	    	break;

	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);


}
Example #12
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception-*.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	int whence = 0;
    off_t position = 0;
	int32_t retval2 = 0; 

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;

	    /* Add stuff here */
	    case SYS_write:
		err = sys_write((int)tf->tf_a0,(const void *)tf->tf_a1,(size_t)tf->tf_a2, &retval);
		break;

 		case SYS_read:
		err = sys_read(tf->tf_a0, (void *) tf->tf_a1, (size_t) tf->tf_a2, &retval);
		break;
		
		case SYS_open:
		err = sys_open((char *)tf->tf_a0, tf->tf_a1, (mode_t)tf->tf_a2, &retval);
		break;

		case SYS_close:
		err = sys_close(tf->tf_a0);
		break;

		case SYS_dup2:
		err = sys_dup2(tf->tf_a0, tf->tf_a1, &retval);
		break;

   	    case SYS_lseek:
    	position |= (off_t)tf->tf_a2;
    	position <<= 32;
    	position |= (off_t)tf->tf_a3;

    	err = copyin((const userptr_t)tf->tf_sp+16, &whence, sizeof(whence));
    	if (err)
    		break;
    	err = sys_lseek((int)tf->tf_a0, position, (int)whence, &retval, &retval2);
    	if(!err) 
			tf->tf_v1 = retval2;
   	    break;

		case SYS_fork:
		err = sys_fork(tf,&retval);
		break;

		case SYS_getpid:
		err = sys_getpid((pid_t *)&retval);
		break;
		case SYS_waitpid:
		  err = sys_waitpid((pid_t)tf->tf_a0, (userptr_t)tf->tf_a1, (int)tf->tf_a2, (pid_t *)&retval);
	  	break;

		case SYS__exit:
	  	sys__exit((int)tf->tf_a0);
	  	err = -1;
	  	//will never come here as it doesnt return
	  	break;
		
		case SYS_execv:
		err=sys_execv((const char *)tf->tf_a0,(char **)tf->tf_a1);
		break;

		case SYS_sbrk:
		err=(int)sys_sbrk((intptr_t)tf->tf_a0, (vaddr_t *)&retval);
		break;
	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
Example #13
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err = 0;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
			err = sys_reboot(tf->tf_a0);
			break;

	    case SYS___time:
			err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
			break;

	    /* Add stuff here */

	    case SYS_read:
			err = sys_read((int)tf->tf_a0,	// filehandle
				(void*)tf->tf_a1,	// buffer
				(size_t)tf->tf_a2,	// size
				&retval);		// return value
			break;

	    case SYS_write:
			err = sys_write((int)tf->tf_a0,	// filehandle
				(const void*)tf->tf_a1,	// buffer
				(size_t)tf->tf_a2,	// size
				&retval);		// return value
			break;

	    case SYS_open:
			err = sys_open((const char*)tf->tf_a0,	// filename
				(int)tf->tf_a1,		// flags
				&retval);		// return value
			break;

	    case SYS_close:
			err = sys_close((int)tf->tf_a0);	// filehandle
			break;

	    case SYS_dup2:
			err = sys_dup2((int)tf->tf_a0,		// old_filehandle
				(int)tf->tf_a1,		// new_filehandle
				&retval);		// return value
			break;

	   case SYS__exit:
			sys_exit((int)tf->tf_a0);	// exitcode
			break;

	   case SYS_getpid:
			retval = sys_getpid();	// exitcode
			break;
 
	   case SYS_waitpid:
			err = sys_waitpid((pid_t)tf->tf_a0, (int*)tf->tf_a1, tf->tf_a2, &retval);
			break;

	   case SYS_fork:
			err = sys_fork(tf, &retval);
			break;

	   case SYS_execv:
			err = sys_execv((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1);
			break;

		case SYS_sbrk:
			err = sys_sbrk((intptr_t)tf->tf_a0, &retval);
			break;
		
	    case SYS_lseek: {
			off_t offset = tf->tf_a2;
			offset = offset<<32;
			offset = offset|tf->tf_a3;


			int whence;
			int err_copyin = copyin((userptr_t)tf->tf_sp+16,&whence,sizeof(whence));

			if (err_copyin) {
				break;
			}

			off_t retoffset;
			err = sys_lseek((int)tf->tf_a0,	// filehandle
				offset,			// desired offset
				whence,
				&retoffset);		// return value

			if (!err) {
				retval = retoffset>>32;
				tf->tf_v1 = retoffset;
			}
			break;
	}	break;

	   case SYS___getcwd:
			err = sys___getcwd((char*)tf->tf_a0,	// buffer
				(size_t)tf->tf_a1,		// size
				&retval);			// return value
		break;

	   case SYS_chdir:
			err = sys_chdir((char*)tf->tf_a0);	// path
		break;

	    default:
			kprintf("Unknown syscall %d\n", callno);
			err = ENOSYS;
			break;
	}
int bsp_om_append_file(char *filename, void * address, u32 length, u32 max_size)
{
    int ret = BSP_OK;
    int fd;
    int bytes;
    int len;
    mm_segment_t old_fs;

    old_fs = get_fs();
    set_fs(KERNEL_DS);

    ret = om_create_dir(OM_ROOT_PATH);
    if(BSP_OK != ret)
    {
        om_error("<bsp_om_append_file>, create dir failed! ret = %d\n", ret);
        goto out;
    }

    /* open file */
    ret = sys_access(filename, 0);
    if(BSP_OK != ret)
    {
        /*create file */
        fd = sys_open(filename, O_CREAT|O_RDWR, 0755);
        if(fd < 0)
        {
            om_error("<bsp_om_append_file>, open failed while mode is create, ret = %d\n", fd);
            goto out;
        }
    }
    else
    {
        fd = sys_open(filename, O_APPEND|O_RDWR, 0755);
        if(fd < 0)
        {
            om_error("<bsp_om_append_file>, open failed while mode is append, ret = %d\n", fd);
            goto out;
        }
    }

    len = sys_lseek(fd, 0, SEEK_END);
    if(ERROR == len)
    {
        om_error("<bsp_om_append_file>, seek failed! ret = %d\n", len);
        (void)sys_close(fd);
        goto out;
    }

    if (len >= max_size)
    {
        sys_close(fd);
        ret = sys_unlink(filename);
        if (OK != ret)
        {
            om_error("<bsp_om_append_file>, remove failed! ret = %d\n", ret);
	        goto out;
        }

        /*重新建立reset文件*/
        fd = sys_open(filename, O_CREAT|O_RDWR, 0755);
        if(fd < 0)
        {
            om_error("<bsp_om_append_file>, create failed! ret = %d\n", fd);
            goto out;
        }
    }

    bytes = sys_write(fd, address, length);
    if(bytes != length)
    {
        om_error("<bsp_om_append_file>, write data failed! ret = %d\n", bytes);
        ret = BSP_ERROR;
        (void)sys_close(fd);
        goto out;
    }

    ret = sys_close(fd);
    if(0 != ret)
    {
        om_error("<bsp_om_append_file>, close failed! ret = %d\n", ret);
        ret = BSP_ERROR;
        goto out;
    }

    ret = BSP_OK;

out:
    set_fs(old_fs);
    return ret;
}
off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
{
	/* sign extend n */
	return sys_lseek(fd, (int)offset, origin);
}
Example #16
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned short *data, *ptr;
#ifdef CONFIG_LGE_I_DISP_BOOTLOGO
	char *bits;
#else
	unsigned int *bits;
#endif

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
#ifdef CONFIG_LGE_I_DISP_BOOTLOGO
	bits = (char *)(info->screen_base);
#else
	bits = (unsigned short *)(info->screen_base);
#endif

	while (count > 3) {
		unsigned n = ptr[0];
		if (n > max)
			break;
#ifdef CONFIG_LGE_I_DISP_BOOTLOGO
		if(info->var.bits_per_pixel/8 == 4){
			memset32(bits, ptr[1], n << 1);
		}
		else{
			memset16(bits, ptr[1], n << 1);
		}
		bits += info->var.bits_per_pixel/8*n;
#else
		memset16(bits, ptr[1], n << 1);
		bits += n;
#endif

		max -= n;
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
/******************************************************************************
*  Function:  power_off_log_save
*  Description: save the power off log( reason and battery voltage ).
*  Input:
*         None
*  Output:
*         None
*  Return:
*         None
*  Note  :
********************************************************************************/
LOCAL_1 int power_off_log_save( void )
{
    long pos;
    unsigned int pf;
    mm_segment_t old_fs;
    struct rtc_time tm;
    struct timespec ts;
    int     rt;
    char    buf[128];
    char    *reboot_reason[] = {"NORMAL", "BAD BATTERY", "LOWBATTERY", "OVERTEMP", \
                                    "RM_CHARGER", "UPDATE", "REBOOT", "INVALID"};

    BATT_LEVEL_ENUM                 battery_level = chg_get_batt_level();
    DRV_SHUTDOWN_REASON_ENUM        rb;

    getnstimeofday(&ts);

    rtc_time_to_tm((unsigned long)ts.tv_sec, &tm);

    power_off_ctrl.time = tm;
    rb = power_off_ctrl.reason;

    pr_dbg("%4d-%02d-%02d %02d:%02d:%02d\n",tm.tm_year, tm.tm_mon, \
        tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

    /* 记录关机信息(时间、次数、关机原因) */
    snprintf(buf, sizeof(buf) - 1, "system close reason(E5): %s, current battery voltage: %d, current time: %4d-%02d-%02d %02d:%02d:%02d\n", \
        reboot_reason[rb], battery_level, tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

    old_fs = get_fs(); //lint !e63

    set_fs(KERNEL_DS);

    /*coverity[check_return] */
    pf = (unsigned int)sys_open(EXCH_RESET_LOG_PATH, O_RDWR | O_CREAT, 0666);
    /*coverity[unchecked_value] */
    if(IS_ERR((const void*)pf))
    {
        pr_dbg( "error occured happened when open file %s, exiting.\n", EXCH_RESET_LOG_PATH);
        return (int)pf;
    }

    /*coverity[unchecked_value] */
    pos = sys_lseek(pf, 0, SEEK_END);
    if(pos > EXCH_ONOFF_LOG_MAX){
        /* 文件超过 16k,删除重新打开 */
        sys_rmdir(EXCH_RESET_LOG_PATH);
        /*coverity[check_return] */
        pf = (unsigned int)sys_open(EXCH_RESET_LOG_PATH, O_RDWR | O_CREAT, 0666);
        /*coverity[unchecked_value] */
        if(IS_ERR((const void*)pf))
        {
            pr_dbg( "error occured happened when open file %s, exiting.\n", EXCH_RESET_LOG_PATH);
            return (int)pf;
        }
    }
    else{
        /*coverity[unchecked_value] */
        sys_lseek(pf, pos, SEEK_SET);
    }

    /*coverity[unchecked_value] */
    rt = sys_write(pf, (const char*)buf, strlen(buf));
    if(rt<0)
    {
        pr_dbg("error occured happened when write file %s, exiting.\n", EXCH_RESET_LOG_PATH);
        /*coverity[unchecked_value] */
        sys_close( pf );
        set_fs(old_fs);
        return rt;
    }

    pr_dbg(KERN_DEBUG "power off log save.");

    /*coverity[unchecked_value] */
    sys_close( pf );
    set_fs(old_fs);

    return rt;
}
Example #18
0
/*
 * The main routine to restore task via sigreturn.
 * This one is very special, we never return there
 * but use sigreturn facility to restore core registers
 * and jump execution to some predefined ip read from
 * core file.
 */
long __export_restore_task(struct task_restore_args *args)
{
	long ret = -1;
	int i;
	VmaEntry *vma_entry;
	unsigned long va;

	struct rt_sigframe *rt_sigframe;
	unsigned long new_sp;
	k_rtsigset_t to_block;
	pid_t my_pid = sys_getpid();
	rt_sigaction_t act;

	bootstrap_start = args->bootstrap_start;
	bootstrap_len	= args->bootstrap_len;

#ifdef CONFIG_VDSO
	vdso_rt_size	= args->vdso_rt_size;
#endif

	task_entries = args->task_entries;
	helpers = args->helpers;
	n_helpers = args->n_helpers;
	*args->breakpoint = rst_sigreturn;

	ksigfillset(&act.rt_sa_mask);
	act.rt_sa_handler = sigchld_handler;
	act.rt_sa_flags = SA_SIGINFO | SA_RESTORER | SA_RESTART;
	act.rt_sa_restorer = cr_restore_rt;
	sys_sigaction(SIGCHLD, &act, NULL, sizeof(k_rtsigset_t));

	log_set_fd(args->logfd);
	log_set_loglevel(args->loglevel);

	cap_last_cap = args->cap_last_cap;

	pr_info("Switched to the restorer %d\n", my_pid);

#ifdef CONFIG_VDSO
	if (vdso_do_park(&args->vdso_sym_rt, args->vdso_rt_parked_at, vdso_rt_size))
		goto core_restore_end;
#endif

	if (unmap_old_vmas((void *)args->premmapped_addr, args->premmapped_len,
				bootstrap_start, bootstrap_len))
		goto core_restore_end;

	/* Shift private vma-s to the left */
	for (i = 0; i < args->nr_vmas; i++) {
		vma_entry = args->tgt_vmas + i;

		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
			continue;

		if (!vma_priv(vma_entry))
			continue;

		if (vma_entry->end >= TASK_SIZE)
			continue;

		if (vma_entry->start > vma_entry->shmid)
			break;

		if (vma_remap(vma_premmaped_start(vma_entry),
				vma_entry->start, vma_entry_len(vma_entry)))
			goto core_restore_end;
	}

	/* Shift private vma-s to the right */
	for (i = args->nr_vmas - 1; i >= 0; i--) {
		vma_entry = args->tgt_vmas + i;

		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
			continue;

		if (!vma_priv(vma_entry))
			continue;

		if (vma_entry->start > TASK_SIZE)
			continue;

		if (vma_entry->start < vma_entry->shmid)
			break;

		if (vma_remap(vma_premmaped_start(vma_entry),
				vma_entry->start, vma_entry_len(vma_entry)))
			goto core_restore_end;
	}

	/*
	 * OK, lets try to map new one.
	 */
	for (i = 0; i < args->nr_vmas; i++) {
		vma_entry = args->tgt_vmas + i;

		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
			continue;

		if (vma_priv(vma_entry))
			continue;

		va = restore_mapping(vma_entry);

		if (va != vma_entry->start) {
			pr_err("Can't restore %"PRIx64" mapping with %lx\n", vma_entry->start, va);
			goto core_restore_end;
		}
	}

#ifdef CONFIG_VDSO
	/*
	 * Proxify vDSO.
	 */
	for (i = 0; i < args->nr_vmas; i++) {
		if (vma_entry_is(&args->tgt_vmas[i], VMA_AREA_VDSO) ||
		    vma_entry_is(&args->tgt_vmas[i], VMA_AREA_VVAR)) {
			if (vdso_proxify("dumpee", &args->vdso_sym_rt,
					 args->vdso_rt_parked_at,
					 i, args->tgt_vmas, args->nr_vmas))
				goto core_restore_end;
			break;
		}
	}
#endif

	/*
	 * Walk though all VMAs again to drop PROT_WRITE
	 * if it was not there.
	 */
	for (i = 0; i < args->nr_vmas; i++) {
		vma_entry = args->tgt_vmas + i;

		if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR)))
			continue;

		if (vma_entry_is(vma_entry, VMA_ANON_SHARED)) {
			struct shmem_info *entry;

			entry = find_shmem(args->shmems, args->nr_shmems,
						  vma_entry->shmid);
			if (entry && entry->pid == my_pid &&
			    entry->start == vma_entry->start)
				futex_set_and_wake(&entry->lock, 1);
		}

		if (vma_entry->prot & PROT_WRITE)
			continue;

		sys_mprotect(decode_pointer(vma_entry->start),
			     vma_entry_len(vma_entry),
			     vma_entry->prot);
	}

	/*
	 * Finally restore madivse() bits
	 */
	for (i = 0; i < args->nr_vmas; i++) {
		unsigned long m;

		vma_entry = args->tgt_vmas + i;
		if (!vma_entry->has_madv || !vma_entry->madv)
			continue;

		for (m = 0; m < sizeof(vma_entry->madv) * 8; m++) {
			if (vma_entry->madv & (1ul << m)) {
				ret = sys_madvise(vma_entry->start,
						  vma_entry_len(vma_entry),
						  m);
				if (ret) {
					pr_err("madvise(%"PRIx64", %"PRIu64", %ld) "
					       "failed with %ld\n",
						vma_entry->start,
						vma_entry_len(vma_entry),
						m, ret);
					goto core_restore_end;
				}
			}
		}
	}

	ret = 0;

	/*
	 * Tune up the task fields.
	 */
	ret |= sys_prctl_safe(PR_SET_NAME, (long)args->comm, 0, 0);

	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE,	(long)args->mm.mm_start_code, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE,	(long)args->mm.mm_end_code, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_DATA,	(long)args->mm.mm_start_data, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_DATA,	(long)args->mm.mm_end_data, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_STACK,	(long)args->mm.mm_start_stack, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_BRK,	(long)args->mm.mm_start_brk, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_BRK,		(long)args->mm.mm_brk, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_START,	(long)args->mm.mm_arg_start, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END,	(long)args->mm.mm_arg_end, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_START,	(long)args->mm.mm_env_start, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_END,	(long)args->mm.mm_env_end, 0);
	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_AUXV,	(long)args->mm_saved_auxv, args->mm_saved_auxv_size);
	if (ret)
		goto core_restore_end;

	/*
	 * Because of requirements applied from kernel side
	 * we need to restore /proc/pid/exe symlink late,
	 * after old existing VMAs are superseded with
	 * new ones from image file.
	 */
	ret = restore_self_exe_late(args);
	if (ret)
		goto core_restore_end;

	/*
	 * We need to prepare a valid sigframe here, so
	 * after sigreturn the kernel will pick up the
	 * registers from the frame, set them up and
	 * finally pass execution to the new IP.
	 */
	rt_sigframe = (void *)args->t->mem_zone.rt_sigframe;

	if (restore_thread_common(rt_sigframe, args->t))
		goto core_restore_end;

	/*
	 * Threads restoration. This requires some more comments. This
	 * restorer routine and thread restorer routine has the following
	 * memory map, prepared by a caller code.
	 *
	 * | <-- low addresses                                          high addresses --> |
	 * +-------------------------------------------------------+-----------------------+
	 * | this proc body | own stack | rt_sigframe space | thread restore zone   |
	 * +-------------------------------------------------------+-----------------------+
	 *
	 * where each thread restore zone is the following
	 *
	 * | <-- low addresses                                     high addresses --> |
	 * +--------------------------------------------------------------------------+
	 * | thread restore proc | thread1 stack | thread1 rt_sigframe |
	 * +--------------------------------------------------------------------------+
	 */

	if (args->nr_threads > 1) {
		struct thread_restore_args *thread_args = args->thread_args;
		long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND	|
				   CLONE_THREAD | CLONE_SYSVSEM;
		long last_pid_len;
		long parent_tid;
		int i, fd;

		fd = args->fd_last_pid;
		ret = sys_flock(fd, LOCK_EX);
		if (ret) {
			pr_err("Can't lock last_pid %d\n", fd);
			goto core_restore_end;
		}

		for (i = 0; i < args->nr_threads; i++) {
			char last_pid_buf[16], *s;

			/* skip self */
			if (thread_args[i].pid == args->t->pid)
				continue;

			new_sp = restorer_stack(thread_args + i);
			last_pid_len = vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1, &s);
			sys_lseek(fd, 0, SEEK_SET);
			ret = sys_write(fd, s, last_pid_len);
			if (ret < 0) {
				pr_err("Can't set last_pid %ld/%s\n", ret, last_pid_buf);
				goto core_restore_end;
			}

			/*
			 * To achieve functionality like libc's clone()
			 * we need a pure assembly here, because clone()'ed
			 * thread will run with own stack and we must not
			 * have any additional instructions... oh, dear...
			 */

			RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, thread_args, args->clone_restore_fn);
		}

		ret = sys_flock(fd, LOCK_UN);
		if (ret) {
			pr_err("Can't unlock last_pid %ld\n", ret);
			goto core_restore_end;
		}

	}

	sys_close(args->fd_last_pid);

	restore_rlims(args);

	ret = create_posix_timers(args);
	if (ret < 0) {
		pr_err("Can't restore posix timers %ld\n", ret);
		goto core_restore_end;
	}

	ret = timerfd_arm(args);
	if (ret < 0) {
		pr_err("Can't restore timerfd %ld\n", ret);
		goto core_restore_end;
	}

	pr_info("%ld: Restored\n", sys_getpid());

	futex_set(&zombies_inprogress, args->nr_zombies);

	restore_finish_stage(CR_STATE_RESTORE);

	futex_wait_while_gt(&zombies_inprogress, 0);

	if (wait_helpers(args) < 0)
		goto core_restore_end;

	ksigfillset(&to_block);
	ret = sys_sigprocmask(SIG_SETMASK, &to_block, NULL, sizeof(k_rtsigset_t));
	if (ret) {
		pr_err("Unable to block signals %ld", ret);
		goto core_restore_end;
	}

	sys_sigaction(SIGCHLD, &args->sigchld_act, NULL, sizeof(k_rtsigset_t));

	ret = restore_signals(args->siginfo, args->siginfo_nr, true);
	if (ret)
		goto core_restore_end;

	ret = restore_signals(args->t->siginfo, args->t->siginfo_nr, false);
	if (ret)
		goto core_restore_end;

	restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);

	rst_tcp_socks_all(args);

	/*
	 * Writing to last-pid is CAP_SYS_ADMIN protected,
	 * turning off TCP repair is CAP_SYS_NED_ADMIN protected,
	 * thus restore* creds _after_ all of the above.
	 */

	ret = restore_creds(&args->creds);
	ret = ret || restore_dumpable_flag(&args->mm);
	ret = ret || restore_pdeath_sig(args->t);

	futex_set_and_wake(&thread_inprogress, args->nr_threads);

	restore_finish_stage(CR_STATE_RESTORE_CREDS);

	if (ret)
		BUG();

	/* Wait until children stop to use args->task_entries */
	futex_wait_while_gt(&thread_inprogress, 1);

	log_set_fd(-1);

	/*
	 * The code that prepared the itimers makes shure the
	 * code below doesn't fail due to bad timing values.
	 */

#define itimer_armed(args, i)				\
		(args->itimers[i].it_interval.tv_sec ||	\
		 args->itimers[i].it_interval.tv_usec)

	if (itimer_armed(args, 0))
		sys_setitimer(ITIMER_REAL, &args->itimers[0], NULL);
	if (itimer_armed(args, 1))
		sys_setitimer(ITIMER_VIRTUAL, &args->itimers[1], NULL);
	if (itimer_armed(args, 2))
		sys_setitimer(ITIMER_PROF, &args->itimers[2], NULL);

	restore_posix_timers(args);

	sys_munmap(args->rst_mem, args->rst_mem_size);

	/*
	 * Sigframe stack.
	 */
	new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;

	/*
	 * Prepare the stack and call for sigreturn,
	 * pure assembly since we don't need any additional
	 * code insns from gcc.
	 */
	rst_sigreturn(new_sp);

core_restore_end:
	futex_abort_and_wake(&task_entries->nr_in_progress);
	pr_err("Restorer fail %ld\n", sys_getpid());
	sys_exit_group(1);
	return -1;
}
Example #19
0
int
cloudabi_sys_fd_seek(struct thread *td, struct cloudabi_sys_fd_seek_args *uap)
{
	struct lseek_args lseek_args = {
		.fd	= uap->fd,
		.offset	= uap->offset
	};

	switch (uap->whence) {
	case CLOUDABI_WHENCE_CUR:
		lseek_args.whence = SEEK_CUR;
		break;
	case CLOUDABI_WHENCE_END:
		lseek_args.whence = SEEK_END;
		break;
	case CLOUDABI_WHENCE_SET:
		lseek_args.whence = SEEK_SET;
		break;
	default:
		return (EINVAL);
	}

	return (sys_lseek(td, &lseek_args));
}

/* Converts a file descriptor to a CloudABI file descriptor type. */
cloudabi_filetype_t
cloudabi_convert_filetype(const struct file *fp)
{
	struct socket *so;
	struct vnode *vp;

	switch (fp->f_type) {
	case DTYPE_FIFO:
		return (CLOUDABI_FILETYPE_FIFO);
	case DTYPE_KQUEUE:
		return (CLOUDABI_FILETYPE_POLL);
	case DTYPE_PIPE:
		return (CLOUDABI_FILETYPE_FIFO);
	case DTYPE_PROCDESC:
		return (CLOUDABI_FILETYPE_PROCESS);
	case DTYPE_SHM:
		return (CLOUDABI_FILETYPE_SHARED_MEMORY);
	case DTYPE_SOCKET:
		so = fp->f_data;
		switch (so->so_type) {
		case SOCK_DGRAM:
			return (CLOUDABI_FILETYPE_SOCKET_DGRAM);
		case SOCK_SEQPACKET:
			return (CLOUDABI_FILETYPE_SOCKET_SEQPACKET);
		case SOCK_STREAM:
			return (CLOUDABI_FILETYPE_SOCKET_STREAM);
		default:
			return (CLOUDABI_FILETYPE_UNKNOWN);
		}
	case DTYPE_VNODE:
		vp = fp->f_vnode;
		switch (vp->v_type) {
		case VBLK:
			return (CLOUDABI_FILETYPE_BLOCK_DEVICE);
		case VCHR:
			return (CLOUDABI_FILETYPE_CHARACTER_DEVICE);
		case VDIR:
			return (CLOUDABI_FILETYPE_DIRECTORY);
		case VFIFO:
			return (CLOUDABI_FILETYPE_FIFO);
		case VLNK:
			return (CLOUDABI_FILETYPE_SYMBOLIC_LINK);
		case VREG:
			return (CLOUDABI_FILETYPE_REGULAR_FILE);
		case VSOCK:
			return (CLOUDABI_FILETYPE_SOCKET_STREAM);
		default:
			return (CLOUDABI_FILETYPE_UNKNOWN);
		}
	default:
		return (CLOUDABI_FILETYPE_UNKNOWN);
	}
}

/* Removes rights that conflict with the file descriptor type. */
void
cloudabi_remove_conflicting_rights(cloudabi_filetype_t filetype,
    cloudabi_rights_t *base, cloudabi_rights_t *inheriting)
{

	/*
	 * CloudABI has a small number of additional rights bits to
	 * disambiguate between multiple purposes. Remove the bits that
	 * don't apply to the type of the file descriptor.
	 *
	 * As file descriptor access modes (O_ACCMODE) has been fully
	 * replaced by rights bits, CloudABI distinguishes between
	 * rights that apply to the file descriptor itself (base) versus
	 * rights of new file descriptors derived from them
	 * (inheriting). The code below approximates the pair by
	 * decomposing depending on the file descriptor type.
	 *
	 * We need to be somewhat accurate about which actions can
	 * actually be performed on the file descriptor, as functions
	 * like fcntl(fd, F_GETFL) are emulated on top of this.
	 */
	switch (filetype) {
	case CLOUDABI_FILETYPE_DIRECTORY:
		*base &= CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC | CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY |
		    CLOUDABI_RIGHT_FILE_CREATE_FILE |
		    CLOUDABI_RIGHT_FILE_CREATE_FIFO |
		    CLOUDABI_RIGHT_FILE_LINK_SOURCE |
		    CLOUDABI_RIGHT_FILE_LINK_TARGET |
		    CLOUDABI_RIGHT_FILE_OPEN |
		    CLOUDABI_RIGHT_FILE_READDIR |
		    CLOUDABI_RIGHT_FILE_READLINK |
		    CLOUDABI_RIGHT_FILE_RENAME_SOURCE |
		    CLOUDABI_RIGHT_FILE_RENAME_TARGET |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_FILE_STAT_GET |
		    CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES |
		    CLOUDABI_RIGHT_FILE_SYMLINK |
		    CLOUDABI_RIGHT_FILE_UNLINK |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY |
		    CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY;
		*inheriting &= CLOUDABI_RIGHT_FD_DATASYNC |
		    CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY |
		    CLOUDABI_RIGHT_FILE_CREATE_FILE |
		    CLOUDABI_RIGHT_FILE_CREATE_FIFO |
		    CLOUDABI_RIGHT_FILE_LINK_SOURCE |
		    CLOUDABI_RIGHT_FILE_LINK_TARGET |
		    CLOUDABI_RIGHT_FILE_OPEN |
		    CLOUDABI_RIGHT_FILE_READDIR |
		    CLOUDABI_RIGHT_FILE_READLINK |
		    CLOUDABI_RIGHT_FILE_RENAME_SOURCE |
		    CLOUDABI_RIGHT_FILE_RENAME_TARGET |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_FILE_STAT_GET |
		    CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES |
		    CLOUDABI_RIGHT_FILE_SYMLINK |
		    CLOUDABI_RIGHT_FILE_UNLINK |
		    CLOUDABI_RIGHT_MEM_MAP |
		    CLOUDABI_RIGHT_MEM_MAP_EXEC |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_PROC_EXEC |
		    CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY |
		    CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY;
		break;
	case CLOUDABI_FILETYPE_FIFO:
		*base &= CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_POLL:
		*base &= ~CLOUDABI_RIGHT_FILE_ADVISE;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_PROCESS:
		*base &= ~(CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE);
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_REGULAR_FILE:
		*base &= CLOUDABI_RIGHT_FD_DATASYNC |
		    CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_MEM_MAP |
		    CLOUDABI_RIGHT_MEM_MAP_EXEC |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_PROC_EXEC;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_SHARED_MEMORY:
		*base &= ~(CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_READDIR);
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_SOCKET_DGRAM:
	case CLOUDABI_FILETYPE_SOCKET_SEQPACKET:
	case CLOUDABI_FILETYPE_SOCKET_STREAM:
		*base &= CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_SOCK_ACCEPT |
		    CLOUDABI_RIGHT_SOCK_BIND_SOCKET |
		    CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET |
		    CLOUDABI_RIGHT_SOCK_LISTEN |
		    CLOUDABI_RIGHT_SOCK_SHUTDOWN |
		    CLOUDABI_RIGHT_SOCK_STAT_GET;
		break;
	default:
		*inheriting = 0;
		break;
	}
}

/* Converts FreeBSD's Capsicum rights to CloudABI's set of rights. */
static void
convert_capabilities(const cap_rights_t *capabilities,
    cloudabi_filetype_t filetype, cloudabi_rights_t *base,
    cloudabi_rights_t *inheriting)
{
	cloudabi_rights_t rights;

	/* Convert FreeBSD bits to CloudABI bits. */
	rights = 0;
#define MAPPING(cloudabi, ...) do {				\
	if (cap_rights_is_set(capabilities, ##__VA_ARGS__))	\
		rights |= (cloudabi);				\
} while (0);
	RIGHTS_MAPPINGS
#undef MAPPING

	*base = rights;
	*inheriting = rights;
	cloudabi_remove_conflicting_rights(filetype, base, inheriting);
}
//
//  Generic syscall handler.
//
//  Returns 0 if syscall number is not handled by this
//  module, 1 otherwise. This allows applications to
//  extend the syscall handler by using exception chaining.
//
CYG_ADDRWORD
__do_syscall(CYG_ADDRWORD func,                 // syscall function number
             CYG_ADDRWORD arg1, CYG_ADDRWORD arg2,      // up to four args.
             CYG_ADDRWORD arg3, CYG_ADDRWORD arg4,
             CYG_ADDRWORD *retval, CYG_ADDRWORD *sig)   // syscall return value
{
    int err = 0;
    *sig = 0;

    switch (func) {

    case SYS_open:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_open( const char *name, int flags,
                                              int mode, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_open((const char *)arg1, (int)arg2, (int)arg3,
                                         (int *)sig);
        else
#endif
            err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
        break;
    }
    case SYS_read:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_read( int fd, void *buf, size_t count,
                                              int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_read((int)arg1, (void *)arg2, (size_t)arg3,
                                         (int *)sig);
        else
#endif
            err = sys_read((int)arg1, (char *)arg2, (int)arg3);
        break;
    }
    case SYS_write:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_write( int fd, const void *buf,
                                               size_t count, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_write((int)arg1, (const void *)arg2,
                                          (size_t)arg3, (int *)sig);
        else
#endif
            err = sys_write((int)arg1, (char *)arg2, (int)arg3);
        break;
    }
    case SYS_close:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_close( int fd, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_close((int)arg1, (int *)sig);
        else
#endif
            err = sys_close((int)arg1);
        break;
    }
    case SYS_lseek:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_lseek( int fd, long offset,
                                               int whence, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_lseek((int)arg1, (long)arg2, (int)arg3,
                                          (int *)sig);
        else
#endif
            err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
        break;
    }
    case SYS_stat:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_stat( const char *pathname,
                                              void *statbuf, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_stat((const char *)arg1, (void *)arg2,
                                         (int *)sig);
        else
#endif
            err = -NEWLIB_ENOSYS;
        break;
    }
    case SYS_fstat:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_fstat( int fd, void *statbuf,
                                               int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_fstat((int)arg1, (void *)arg2,
                                          (int *)sig);
        else
#endif
        {
            struct newlib_stat *st = (struct newlib_stat *)arg2;
            st->st_mode = NEWLIB_S_IFCHR;
            st->st_blksize = 4096;
            err = 0;
        }
        break;
    }
    case SYS_rename:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_rename( const char *oldpath,
                                                const char *newpath,
                                                int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_rename((const char *)arg1, (const char *)arg2,
                                           (int *)sig);
        else
#endif
            err = -NEWLIB_ENOSYS;
        break;
    }
    case SYS_unlink:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_unlink( const char *pathname,
                                                int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_unlink((const char *)arg1, (int *)sig);
        else
#endif
            err = -NEWLIB_ENOSYS;
        break;
    }
    case SYS_isatty:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_isatty( int fd, int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_isatty((int)arg1, (int *)sig);
        else
#endif
            err = 1;
        break;
    }
    case SYS_system:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_system( const char *command,
                                                int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_system((const char *)arg1, (int *)sig);
        else
#endif
            err = -1;
        break;
    }
    case SYS_gettimeofday:
    {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
        __externC int cyg_hal_gdbfileio_gettimeofday( void *tv, void *tz,
                int *sig );
        if (gdb_active)
            err = cyg_hal_gdbfileio_gettimeofday((void *)arg1, (void *)arg2,
                                                 (int *)sig);
        else
#endif
            err = 0;
        break;
    }
    case SYS_utime:
        // FIXME. Some libglosses depend on this behavior.
        err = sys_times((unsigned long *)arg1);
        break;

    case SYS_times:
        err = sys_times((unsigned long *)arg1);
        break;

    case SYS_meminfo:
        err = 1;
        *(unsigned long *)arg1 = (unsigned long)(ram_end-ram_start);
        *(unsigned long *)arg2 = (unsigned long)ram_end;
        break;
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    case SYS_timer_call_back:
        sys_profile_call_back( (char *)arg1, (char **)arg2 );
        break;

    case SYS_timer_frequency:
        sys_profile_frequency( (int)arg1, (unsigned int *)arg2 );
        break;

    case SYS_timer_reset:
        sys_profile_reset();
        break;

#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    case __GET_SHARED:
        *(__shared_t **)arg1 = &__shared_data;
        break;

    case SYS_exit:
        *sig = -1;    // signal exit
        err = arg1;

        if (gdb_active) {
#ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
            __send_exit_status((int)arg1);
#else
            *sig = SIGTRAP;
            err = func;
#endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
        }
        break;

    default:
        return 0;
    }

    *retval = err;
    return 1;
}
// unbounded_channels <= 0 means no, > 0 means yes
// -1 means advance.
void check_channel(char threadsafe, qio_chtype_t type, int64_t start, int64_t len, int64_t chunksz, qio_hint_t file_hints, qio_hint_t ch_hints, char unbounded_channels, char reopen)
{
  qio_file_t* f;
  qio_channel_t* writing;
  qio_channel_t* reading;
  int64_t offset;
  int64_t usesz;
  int64_t end = start + len;
  int err;
  unsigned char* chunk;
  unsigned char* got_chunk;
  int64_t k;
  ssize_t amt_written;
  ssize_t amt_read;
  char* chhints;
  char* fhints;
  FILE* writefp = NULL;
  FILE* readfp = NULL;
  int memory;
  int64_t ch_end = end;
  char filename[128];
  int fd = -1;

  strcpy(filename,"/tmp/qio_testXXXXXX");

  if( unbounded_channels > 0 ) ch_end = INT64_MAX;

  ch_hints = (ch_hints & ~ QIO_CHTYPEMASK) | type;

  memory = 0;

  if( (file_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY ||
      (ch_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY ) {
    memory = 1;
  }
  if( memory ) {
    file_hints = (file_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY;
    ch_hints = (ch_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY;
  }
  if( memory && type == QIO_CH_ALWAYS_UNBUFFERED ) return;
  if( memory && reopen ) return;
  if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_FREADFWRITE ) {
    if( (file_hints & QIO_METHODMASK) != QIO_METHOD_FREADFWRITE ) return;
  }
  if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_MMAP ) {
    if( (file_hints & QIO_METHODMASK) != QIO_METHOD_MMAP ) return;
  }

  fhints = qio_hints_to_string(file_hints);
  chhints = qio_hints_to_string(ch_hints);
  printf("check_channel(threadsafe=%i, type=%i, start=%lli, len=%lli, chunksz=%lli, file_hints=%s, ch_hints=%s, unbounded=%i, reopen=%i)\n",
         (int) threadsafe,
         (int) type,
         (long long int) start,
         (long long int) len,
         (long long int) chunksz,
         fhints,
         chhints,
         (int) unbounded_channels,
         (int) reopen );
  free(fhints);
  free(chhints);

  chunk = malloc(chunksz);
  got_chunk = malloc(chunksz);

  assert(chunk);
  assert(got_chunk);

  if( memory ) {
    err = qio_file_open_mem_ext(&f, NULL, QIO_FDFLAG_READABLE|QIO_FDFLAG_WRITEABLE|QIO_FDFLAG_SEEKABLE, file_hints, NULL);
    assert(!err);
  } else {
    // Open a temporary file.
    if( reopen ) {
      fd = mkstemp(filename);
      close(fd);
      err = qio_file_open_access(&f, filename, "w", file_hints, NULL);
      assert(!err);
    } else {
      err = qio_file_open_tmp(&f, file_hints, NULL);
      assert(!err);
    }

    // Rewind the file
    if (f->fp ) {
      int got;
      got = fseek(f->fp, start, SEEK_SET);
      assert( got == 0 );
    } else {
      off_t off;

      err = sys_lseek(f->fd, start, SEEK_SET, &off);
      assert(!err);
    }
  }

  // Create a "write to file" channel.
  err = qio_channel_create(&writing, f, ch_hints, 0, 1, start, ch_end, NULL);
  assert(!err);

  // Write stuff to the file.
  for( offset = start; offset < end; offset += usesz ) {
    usesz = chunksz;
    if( offset + usesz > end ) usesz = end - offset;
    // Fill chunk.
    fill_testdata(offset, usesz, chunk);
    // Write chunk.
    if( writefp ) {
      amt_written = fwrite(chunk, 1, usesz, writefp);
    } else {
      err = qio_channel_write(threadsafe, writing, chunk, usesz, &amt_written);
      assert(!err);
    }
    assert(amt_written == usesz);

  }

  // Attempt to write 1 more byte; we should get EEOF
  // if we've restricted the range of the channel.
  // Write chunk.
  if( unbounded_channels > 0) {
    // do nothing
  } else {
    if( writefp ) {
      int got;
      got = fflush(writefp);
      assert(got == 0);
      amt_written = fwrite(chunk, 1, 1, writefp);
      // fwrite might buffer on its own.
      if( amt_written != 0 ) {
        got = fflush(writefp);
        assert(got == EOF);
      }
      assert(errno == EEOF);
    } else {
      if( unbounded_channels < 0 ) {
        int times = -unbounded_channels;
        for( int z = 0; z < times; z++ ) {
          err = qio_channel_advance(threadsafe, writing, 1);
          assert( !err );
        }
      }

      err = qio_channel_write(threadsafe, writing, chunk, 1, &amt_written);
      assert(amt_written == 0);
      assert( err == EEOF );
    }
  }

  qio_channel_release(writing);

  // Reopen the file if we're doing reopen
  if( reopen ) {
    // Close the file.
    qio_file_release(f);
    err = qio_file_open_access(&f, filename, "r", file_hints, NULL);
    assert(!err);
  }

  // Check that the file is the right length.
  if( !memory ) {
    struct stat stats;
    err = sys_fstat(f->fd, &stats);
    assert(!err);
    assert(stats.st_size == end);
  }

  // That was fun. Now start at the beginning of the file
  // and read the data.
  
  // Rewind the file 
  if( !memory ) {
    off_t off;

    sys_lseek(f->fd, start, SEEK_SET, &off);
    assert(!err);
  }

  // Read the data.
  //err = qio_channel_init_file(&reading, type, f, ch_hints, 1, 0, start, end);
  err = qio_channel_create(&reading, f, ch_hints, 1, 0, start, ch_end, NULL);
  assert(!err);

  // Read stuff from the file.
  for( offset = start; offset < end; offset += usesz ) {
    usesz = chunksz;
    if( offset + usesz > end ) usesz = end - offset;
    // Fill chunk.
    fill_testdata(offset, usesz, chunk);
    memset(got_chunk, 0xff, usesz);
    // Read chunk.
    if( readfp ) {
      amt_read = fread(got_chunk, 1, usesz, readfp);
    } else {
      err = qio_channel_read(threadsafe, reading, got_chunk, usesz, &amt_read);
      assert( err == EEOF || err == 0);
    }
    assert(amt_read == usesz);

    // Compare chunk.
    for( k = 0; k < usesz; k++ ) {
      assert(got_chunk[k] == chunk[k]);
    }
  }

  if( readfp ) {
    amt_read = fread(got_chunk, 1, 1, readfp);
    assert( amt_read == 0 );
    assert( feof(readfp) );
  } else {
    if( unbounded_channels < 0 ) {
      int times = -unbounded_channels;
      for( int z = 0; z < times; z++ ) {
        err = qio_channel_advance(threadsafe, reading, 1);
        assert( !err );
      }

      err = qio_channel_advance(threadsafe, reading, -unbounded_channels);
      assert( !err );
    }

    err = qio_channel_read(threadsafe, reading, got_chunk, 1, &amt_read);
    assert( err == EEOF );
  }

  qio_channel_release(reading);
  //err = qio_channel_destroy(&reading);

  // Close the file.
  qio_file_release(f);

  if( reopen ) {
    unlink(filename);
  }

  free(chunk);
  free(got_chunk);
}
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, err = 0;
	unsigned count, max, width, stride, line_pos = 0;
	unsigned short *data, *ptr;
	unsigned char *bits;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	if (!info->screen_base) {
		printk(KERN_WARNING "Framebuffer memory not allocated\n");
		return -ENOMEM;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}
	width = fb_width(info);
	stride = fb_linewidth(info);
	max = width * fb_height(info);
	ptr = data;
	bits = (unsigned char *)(info->screen_base);

	while (count > 3) {
		int n = ptr[0];

		if (n > max)
			break;
		max -= n;
		while (n > 0) {
			unsigned int j =
				(line_pos + n > width ? width-line_pos : n);

			if (fb_depth(info) == 2)
				memset16(bits, ptr[1], j << 1);
			else {
				unsigned int widepixel = ptr[1];
				/*
				 * Format is RGBA, but fb is big
				 * endian so we should make widepixel
				 * as ABGR.
				 */
				widepixel =
					/* red :   f800 -> 000000f8 */
					(widepixel & 0xf800) >> 8 |
					/* green : 07e0 -> 0000fc00 */
					(widepixel & 0x07e0) << 5 |
					/* blue :  001f -> 00f80000 */
					(widepixel & 0x001f) << 19;
				memset32(bits, widepixel, j << 2);
			}
			bits += j * fb_depth(info);
			line_pos += j;
			n -= j;
			if (line_pos == width) {
				bits += (stride-width) * fb_depth(info);
				line_pos = 0;
			}
		}
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);

	return err;
}
Example #23
0
asmlinkage int sys32_lseek(unsigned int fd, int offset, unsigned int origin)
{
	return sys_lseek(fd, offset, origin);
}
Example #24
0
static void ListerThread(struct ListerParams *args) {
  int                found_parent = 0;
  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
  char               proc_self_task[80], marker_name[48], *marker_path;
  const char         *proc_paths[3];
  const char *const  *proc_path = proc_paths;
  int                proc = -1, marker = -1, num_threads = 0;
  int                max_threads = 0, sig;
  struct kernel_stat marker_sb, proc_sb;
  stack_t            altstack;

  /* Create "marker" that we can use to detect threads sharing the same
   * address space and the same file handles. By setting the FD_CLOEXEC flag
   * we minimize the risk of misidentifying child processes as threads;
   * and since there is still a race condition,  we will filter those out
   * later, anyway.
   */
  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
  failure:
    args->result = -1;
    args->err    = errno;
    if (marker >= 0)
      NO_INTR(sys_close(marker));
    sig_marker = marker = -1;
    if (proc >= 0)
      NO_INTR(sys_close(proc));
    sig_proc = proc = -1;
    sys__exit(1);
  }

  /* Compute search paths for finding thread directories in /proc            */
  local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
  strcpy(marker_name, proc_self_task);
  marker_path = marker_name + strlen(marker_name);
  strcat(proc_self_task, "/task/");
  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
  proc_paths[1] = "/proc/";       /* /proc/                                  */
  proc_paths[2] = NULL;

  /* Compute path for marker socket in /proc                                 */
  local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
  if (sys_stat(marker_name, &marker_sb) < 0) {
    goto failure;
  }

  /* Catch signals on an alternate pre-allocated stack. This way, we can
   * safely execute the signal handler even if we ran out of memory.
   */
  memset(&altstack, 0, sizeof(altstack));
  altstack.ss_sp    = args->altstack_mem;
  altstack.ss_flags = 0;
  altstack.ss_size  = ALT_STACKSIZE;
  sys_sigaltstack(&altstack, (const stack_t *)NULL);

  /* Some kernels forget to wake up traced processes, when the
   * tracer dies.  So, intercept synchronous signals and make sure
   * that we wake up our tracees before dying. It is the caller's
   * responsibility to ensure that asynchronous signals do not
   * interfere with this function.
   */
  sig_marker = marker;
  sig_proc   = -1;
  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    struct kernel_sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_sigaction_ = SignalHandler;
    sys_sigfillset(&sa.sa_mask);
    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
  }
  
  /* Read process directories in /proc/...                                   */
  for (;;) {
    /* Some kernels know about threads, and hide them in "/proc"
     * (although they are still there, if you know the process
     * id). Threads are moved into a separate "task" directory. We
     * check there first, and then fall back on the older naming
     * convention if necessary.
     */
    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
      if (*++proc_path != NULL)
        continue;
      goto failure;
    }
    if (sys_fstat(proc, &proc_sb) < 0)
      goto failure;
    
    /* Since we are suspending threads, we cannot call any libc
     * functions that might acquire locks. Most notably, we cannot
     * call malloc(). So, we have to allocate memory on the stack,
     * instead. Since we do not know how much memory we need, we
     * make a best guess. And if we guessed incorrectly we retry on
     * a second iteration (by jumping to "detach_threads").
     *
     * Unless the number of threads is increasing very rapidly, we
     * should never need to do so, though, as our guestimate is very
     * conservative.
     */
    if (max_threads < proc_sb.st_nlink + 100)
      max_threads = proc_sb.st_nlink + 100;
    
    /* scope */ {
      pid_t pids[max_threads];
      int   added_entries = 0;
      sig_num_threads     = num_threads;
      sig_pids            = pids;
      for (;;) {
        struct kernel_dirent *entry;
        char buf[4096];
        ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,
                                      sizeof(buf));
        if (nbytes < 0)
          goto failure;
        else if (nbytes == 0) {
          if (added_entries) {
            /* Need to keep iterating over "/proc" in multiple
             * passes until we no longer find any more threads. This
             * algorithm eventually completes, when all threads have
             * been suspended.
             */
            added_entries = 0;
            sys_lseek(proc, 0, SEEK_SET);
            continue;
          }
          break;
        }
        for (entry = (struct kernel_dirent *)buf;
             entry < (struct kernel_dirent *)&buf[nbytes];
             entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {
          if (entry->d_ino != 0) {
            const char *ptr = entry->d_name;
            pid_t pid;
            
            /* Some kernels hide threads by preceding the pid with a '.'     */
            if (*ptr == '.')
              ptr++;
            
            /* If the directory is not numeric, it cannot be a
             * process/thread
             */
            if (*ptr < '0' || *ptr > '9')
              continue;
            pid = local_atoi(ptr);

            /* Attach (and suspend) all threads                              */
            if (pid && pid != clone_pid) {
              struct kernel_stat tmp_sb;
              char fname[entry->d_reclen + 48];
              strcat(strcat(strcpy(fname, "/proc/"),
                            entry->d_name), marker_path);
              
              /* Check if the marker is identical to the one we created      */
              if (sys_stat(fname, &tmp_sb) >= 0 &&
                  marker_sb.st_ino == tmp_sb.st_ino) {
                long i, j;

                /* Found one of our threads, make sure it is no duplicate    */
                for (i = 0; i < num_threads; i++) {
                  /* Linear search is slow, but should not matter much for
                   * the typically small number of threads.
                   */
                  if (pids[i] == pid) {
                    /* Found a duplicate; most likely on second pass         */
                    goto next_entry;
                  }
                }
                
                /* Check whether data structure needs growing                */
                if (num_threads >= max_threads) {
                  /* Back to square one, this time with more memory          */
                  NO_INTR(sys_close(proc));
                  goto detach_threads;
                }

                /* Attaching to thread suspends it                           */
                pids[num_threads++] = pid;
                sig_num_threads     = num_threads;
                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
                               (void *)0) < 0) {
                  /* If operation failed, ignore thread. Maybe it
                   * just died?  There might also be a race
                   * condition with a concurrent core dumper or
                   * with a debugger. In that case, we will just
                   * make a best effort, rather than failing
                   * entirely.
                   */
                  num_threads--;
                  sig_num_threads = num_threads;
                  goto next_entry;
                }
                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
                  if (errno != EINTR) {
                    sys_ptrace_detach(pid);
                    num_threads--;
                    sig_num_threads = num_threads;
                    goto next_entry;
                  }
                }
                
                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
                  /* Address spaces are distinct, even though both
                   * processes show the "marker". This is probably
                   * a forked child process rather than a thread.
                   */
                  sys_ptrace_detach(pid);
                  num_threads--;
                  sig_num_threads = num_threads;
                } else {
                  found_parent |= pid == ppid;
                  added_entries++;
                }
              }
            }
          }
        next_entry:;
        }
      }
      NO_INTR(sys_close(proc));
      sig_proc = proc = -1;

      /* If we failed to find any threads, try looking somewhere else in
       * /proc. Maybe, threads are reported differently on this system.
       */
      if (num_threads > 1 || !*++proc_path) {
        NO_INTR(sys_close(marker));
        sig_marker = marker = -1;

        /* If we never found the parent process, something is very wrong.
         * Most likely, we are running in debugger. Any attempt to operate
         * on the threads would be very incomplete. Let's just report an
         * error to the caller.
         */
        if (!found_parent) {
          ResumeAllProcessThreads(num_threads, pids);
          sys__exit(3);
        }

        /* Now we are ready to call the callback,
         * which takes care of resuming the threads for us.
         */
        args->result = args->callback(args->parameter, num_threads,
                                      pids, args->ap);
        args->err = errno;

        /* Callback should have resumed threads, but better safe than sorry  */
        if (ResumeAllProcessThreads(num_threads, pids)) {
          /* Callback forgot to resume at least one thread, report error     */
          args->err    = EINVAL;
          args->result = -1;
        }

        sys__exit(0);
      }
    detach_threads:
      /* Resume all threads prior to retrying the operation                  */
      ResumeAllProcessThreads(num_threads, pids);
      sig_pids = NULL;
      num_threads = 0;
      sig_num_threads = num_threads;
      max_threads += 100;
    }
  }
}
Example #25
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, err = 0;
	unsigned count, max;
	unsigned short *data, *bits, *ptr;

	printk(KERN_WARNING "~~  %s:  %s\n",__func__, filename);
	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = (unsigned)sys_lseek(fd, (off_t)0, 2);
	if (count == 0) {
		sys_close(fd);
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if ((unsigned)sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	bits = (unsigned short *)(info->screen_base);
	while (count > 3) {
		unsigned n = ptr[0];
		if (n > max)
			break;
		memset16(bits, ptr[1], n << 1);
		bits += n;
		max -= n;
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);

err_logo_close_file:
	sys_close(fd);

	printk(KERN_WARNING "~~  %s:  %s  err:%d end \n",__func__, filename, err);

	return err;
}
int external_memory_test(void)
{
	int return_value = 0;
	char *src = NULL, *dest = NULL;
	off_t fd_offset;
	int fd = -1;
	mm_segment_t old_fs;
	int ret;

	old_fs = get_fs();

	set_fs(KERNEL_DS);
	fd = sys_open((const char __user *) "/sdcard/SDTest.txt", O_CREAT | O_RDWR, 0);
	set_fs(old_fs);
	if ( fd < 0 ) {
		printk(KERN_ERR "[ATCMD_EMT] Can not access SD card\n");
		return return_value;
	}

	src = kmalloc(10, GFP_KERNEL);
	if (NULL == src) {
		printk(KERN_ERR "[ATCMD_EMT] memory allocation is failed\n");
		goto file_fail;
	}
	sprintf(src,"TEST");

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	ret = sys_write(fd, (const char __user *) src, 5);
	set_fs(old_fs);
	if(ret < 0) {
		printk(KERN_ERR "[ATCMD_EMT] Can not write SD card \n");
		goto file_fail;
	}
	fd_offset = sys_lseek(fd, 0, 0);

	dest = kmalloc(10, GFP_KERNEL);
	if (NULL == dest) {
		printk(KERN_ERR "[ATCMD_EMT] memory allocation is failed\n");
		goto file_fail;
	}

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	ret = sys_read(fd, (char __user *) dest, 5);
	set_fs(old_fs);

	if(ret < 0) {
		printk(KERN_ERR "[ATCMD_EMT]Can not read SD card \n");
		goto file_fail;
	}
	if ((memcmp(src, dest, 4)) == 0)
		return_value = 1;
	else
		return_value = 0;

file_fail:
	if (fd > 0) {
		sys_close(fd);
		sys_unlink((const char __user *)"/sdcard/SDTest.txt");
	}
	if (src) 
		kfree(src);
	if (dest)
		kfree(dest);

	return return_value;
}
Example #27
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
static int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, err = 0;
	unsigned max, width, stride, line_pos = 0;
	unsigned short *data, *ptr;
	unsigned char *bits;
	signed count;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_ERR "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_ERR "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		printk(KERN_ERR "%s: sys_lseek failed %s\n",
			__func__, filename);
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_ERR "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		printk(KERN_ERR "%s: sys_read failed %s\n",
			__func__, filename);
		goto err_logo_free_data;
	}
	width = fb_width(info);
	stride = fb_linewidth(info);
	max = width * fb_height(info);
	ptr = data;
	bits = (unsigned char *)(info->screen_base);
	while (count > 3) {
		int n = ptr[0];

		if (n > max)
			break;
		max -= n;
		while (n > 0) {
			unsigned int j =
				(line_pos+n > width ? width-line_pos : n);

			if (fb_depth(info) == 2) {
				memset16(bits, ptr[1], j << 1);
			} else {
				/* Should probably add check for framebuffer
				 * format here*/
				unsigned int widepixel = ptr[1];
				widepixel = (widepixel & 0xf800) << (19-11) |
					(widepixel & 0x07e0) << (10-5) |
					(widepixel & 0x001f) << (3-0) |
					0xff000000; /* Set alpha channel*/
				memset32(bits, widepixel, j << 2);
			}
			bits += j * fb_depth(info);
			line_pos += j;
			n -= j;
			if (line_pos == width) {
				bits += (stride-width) * fb_depth(info);
				line_pos = 0;
			}
		}
		ptr += 2;
		count -= 4;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);

	return err;
}
Example #28
0
/**
 * SPB & FAR
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno, err;
	int32_t retval;

	off_t pos = 0;
	off_t lsret;
	int whence;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */
	retval = 0;

	switch (callno) {
	    case SYS_reboot:
	    	err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
	    	err = sys___time((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1);
		break;

	    case SYS_open:
	    	err = sys_open((const char*)tf->tf_a0, tf->tf_a1, &retval);
	    break;

	    case SYS_read:
	    	err = sys_read((int)tf->tf_a0,(void*)tf->tf_a1,(size_t)tf->tf_a2,&retval);
	    break;

	    case SYS_write:
	    	err = sys_write((int)tf->tf_a0,(const void*)tf->tf_a1,(size_t)tf->tf_a2,&retval);	
	    break;

	    case SYS_close:
	    	err = sys_close((int)tf->tf_a0, &retval);
   	    break;

   	    case SYS_lseek:

   	    	pos |= (off_t)tf->tf_a2;
   	    	pos <<= 32;			//puts a2 and a3 into one var.
   	    	pos |= (off_t)tf->tf_a3;

   	    	err = copyin((const userptr_t)tf->tf_sp+16, &whence, sizeof(whence));
   	    	if (err)
   	    		break;

   	    	err = sys_lseek((int)tf->tf_a0, pos, (int)whence, &lsret);
   	    	if(!err){
   	    		retval = lsret>>32;
   	    		tf->tf_v1 = lsret;
   	    	}
   	    break;

   	    case SYS_dup2:
   	    	err = sys_dup2((int)tf->tf_a0 , (int)tf->tf_a1, &retval);
   	    break;

   	    case SYS_chdir:
   	    	err = sys_chdir((const char*)tf->tf_a0);
   	    break;

   	    case SYS___getcwd:
   	    	err = sys___getcwd((char*)tf->tf_a0, (size_t)tf->tf_a1, &retval);
   	    break;

   	    case SYS_fork:
   	    	err = sys_fork(tf, &retval);
   	    break;

   	    case SYS_getpid:
   	    	err = sys_getpid(&retval);
   	    break;

   	    case SYS__exit:
   	    	err = sys__exit((int)tf->tf_a0, &retval);
   	    break;

   	    case SYS_waitpid:
   	    	err = sys_waitpid((int) tf->tf_a0, (int*) tf->tf_a1, tf->tf_a2, &retval);
   	    break;

   	    case SYS_execv:
   	    	err = sys_execv((const char*) tf->tf_a0, (char**) tf->tf_a1, &retval);
   	    break;

	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}
Example #29
0
/* 888RLE image format: [count(2 bytes), rle(3 bytes)] */
int load_565rle_image(char *filename)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned char *data, *ptr;
	unsigned int *bits;
	unsigned int pixel;


	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	bits = (unsigned int *)(info->screen_base);
	while (count > 4) {
		unsigned n = ptr[0] | ptr[1] << 8;
		if (n > max)
			break;

		pixel = (0xff<<24)|(ptr[4]<<16)|(ptr[3]<<8)|ptr[2];

		memset32(bits, pixel, n << 1);
		bits += n;
		max -= n;
		ptr += 5;
		count -= 5;
	}

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
Example #30
0
}

void creat_lseek_read_write_open_close_file_test(void)
{
	int count = 0;
	char buff_in[100] = "Hello world!\nI'm writing a small OS.\nThanks.";
	char buff_out[100] = {0};
	char filename[50] = {0};
	unsigned short oldfs;

	/* 已创建了内核默认的最多磁盘存储文件数,则停止 */
	while((++count) < NR_D_INODE) {

		_k_printf("This is the content will be written: \n%s\n\n", buff_in);

		
		sprintf(filename, "/hello--%d.txt", count);
		_k_printf("%s\n", filename);
		/* 创建文件并写入 */
		oldfs = set_fs_kernel();
		FILEDESC desc = sys_creat(filename, FILE_FILE | FILE_RW);
		set_fs(oldfs);
		if(-1 == desc) {
			k_printf("creat_lseek_...: Create file failed!");
			return;
		}
		d_printf("Create file return.\n");
		if(-1 == sys_lseek(desc, 995920, SEEK_SET)) {
			k_printf("creat_lseek_...: Lseek file failed!");
			return;
		}
		d_printf("Lseek file return.\n");
		oldfs = set_fs_kernel();
		if(-1 == sys_write(desc, buff_in, 1 + strlen(buff_in))) {
			set_fs(oldfs);
			k_printf("creat_lseek_...: Write file failed!");
			return;
		}
		set_fs(oldfs);
		d_printf("Write file return.\n");
		if(-1 == sys_close(desc)) {
			k_printf("creat_lseek_...: Close file failed!");
			return;
		}
		d_printf("Close file return.\n");


		/* 打印根目录含有的文件 */
		print_dir("/");

		/* 打开之前创建的文件,读取 */
		oldfs = set_fs_kernel();
		if(-1 == (desc = sys_open(filename, O_RW))) {
			set_fs(oldfs);
			k_printf("creat_lseek_...: Open file failed!");
			return;
		}
		set_fs(oldfs);
		d_printf("Open file return.\n");
		if(-1 == sys_lseek(desc, 995920, SEEK_SET)) {
			k_printf("creat_lseek_...: Lseek file failed!");
			return;
		}
		d_printf("Lseek file return.\n");
		oldfs = set_fs_kernel();
		if(-1 == sys_read(desc, buff_out, 1 + strlen(buff_in))) {
			set_fs(oldfs);
			k_printf("creat_lseek_...: Read file failed!");
			return;
		}
		set_fs(oldfs);
		d_printf("Read file return.\n");
		if(-1 == sys_close(desc)) {
			k_printf("creat_lseek_...: Close file failed!");
			return;
		}
		d_printf("Close file return.\n");

		
		_k_printf("This is the content of READ file: \n%s\n\n", buff_out);