Example #1
0
// get current process before each bb executes
// which will probably help us actually know the current process
int osi_foo(CPUState *cpu, TranslationBlock *tb) {
    if (panda_in_kernel(cpu)) {
        OsiProc *p = get_current_process(cpu);
        //some sanity checks on what we think the current process is
        // this means we didnt find current task
        if (p->offset == 0) return 0;
        // or the name
        if (p->name == 0) return 0;
        // weird -- this is just not ok
        if (((int) p->pid) == -1) return 0;
        uint32_t n = strnlen(p->name, 32);
        // yuck -- name is one char
        if (n<2) return 0;
        uint32_t np = 0;
        for (uint32_t i=0; i<n; i++) {
            np += (isprint(p->name[i]) != 0);
        }
        // yuck -- name doesnt consist of solely printable characters
        if (np != n) return 0;
        target_ulong asid = panda_current_asid(cpu);
        if (running_procs.count(asid) == 0) {
            if (debug) printf ("adding asid=0x%x to running procs.  cmd=[%s]  task=0x%x\n", (unsigned int)  asid, p->name, (unsigned int) p->offset);
        }
        if (running_procs.count(asid) != 0) {
            /*
            OsiProc *p2 = running_procs[asid];
            // something there already
            if (p2)
                free_osiproc(p2);
            */
        }
        running_procs[asid] = *p;
    }
    return 0;
}
Example #2
0
SYSCALL_HANDLER3(sys_select, uint32_t *fds, size_t n, int *ret) {
	process_t * process = get_current_process();
	int val = 0;
	uint8_t sem = ksemget(SEM_NEW, SEM_CREATE);
	ksemctl(sem, SEM_SET, &val);

	size_t i, j;
	open_file_descriptor *ofd;
	for (i = 0; i < n; i++) {
		ofd = process->fd[fds[i]];
		ofd->select_sem = sem;
		if (ofd->current_octet < ofd->inode->i_size) {
			// Found, exit
			ksemctl(sem, SEM_DEL, NULL); 
			for (j = 0; j <= i; j++) {
				ofd->select_sem = 0;
			}
			*ret = fds[i];
			return;
		}
	}

	ksemP(sem);

	for (i = 0; i < n; i++) {
		ofd = process->fd[fds[i]];
		ofd->select_sem = 0;
		if (ofd->current_octet < ofd->inode->i_size) {
			*ret = fds[i];
		}
	}

	ksemctl(sem, SEM_DEL, NULL);
}
Example #3
0
// get current process before each bb execs
// which will probably help us actually know the current process
int osi_foo(CPUState *env, TranslationBlock *tb) {

    if (panda_in_kernel(env)) {

        OsiProc *p = get_current_process(env);      

        //some sanity checks on what we think the current process is
        // this means we didnt find current task
        if (p->offset == 0) return 0;
        // or the name
        if (p->name == 0) return 0;
        // this is just not ok
        if (((int) p->pid) == -1) return 0;
        uint32_t n = strnlen(p->name, 32);
        // name is one char?
        if (n<2) return 0;
        uint32_t np = 0;
        for (uint32_t i=0; i<n; i++) {
            np += (isprint(p->name[i]) != 0);
        }
        // name doesnt consist of solely printable characters
        //        printf ("np=%d n=%d\n", np, n);
        if (np != n) return 0;
        target_ulong asid = panda_current_asid(env);
        if (running_procs.count(asid) == 0) {
            printf ("adding asid=0x%x to running procs.  cmd=[%s]  task=0x%x\n", (unsigned int)  asid, p->name, (unsigned int) p->offset);
        }
        running_procs[asid] = *p;
    }
    
    return 0;
}
Example #4
0
SYSCALL_HANDLER3(sys_read, uint32_t fd, const void *buf, size_t *c) {
	ssize_t *t = (ssize_t*)c;
	if (buf == NULL) {
		kerr("buffer null !");
		*t = -1;
		return;
	}

	process_t * process = get_current_process();
	
	open_file_descriptor *ofd;

	if (process->fd[fd]) {
		ofd = process->fd[fd];
		
		if(ofd->f_ops->read == NULL) {
			kerr("No \"read\" method for this device.");
			*t = -1;
		} else {
			*t = ofd->f_ops->read(ofd, (void*) buf, *c);
		}
	} else {
		*t = -1;
	}
}
Example #5
0
SYSCALL_HANDLER3(sys_sigprocmask, uint32_t how, sigset_t* set, sigset_t* oldset)
{
	process_t* current = get_current_process();
	
	/* On récupère l'ancien set */
	if (oldset != NULL)
		*oldset = current->signal_data.mask;
	
	/* Si set est null, alors on fait rien. */
	if (set == NULL)
		return;

	/* Et on met à jour le nouveau */
	switch(how)
	{
		case SIG_SETMASK:
			current->signal_data.mask = *set;
			break;
		case SIG_UNBLOCK:
			current->signal_data.mask &= ~(*set);
			break;
		case SIG_BLOCK:
			current->signal_data.mask |= (*set);
			break;
		default:
			kerr("Invalid sigprocmask command (0x%x).", how);
	}
} 
Example #6
0
int sys_psp_read_umd(int unk, void *buf, uint64_t sector, uint64_t ofs, uint64_t size)
{
	uint64_t offset, dummy;
	int ret;
							
	#ifdef DEBUG
	DPRINTF("umd read %lx %lx %lx\n", sector, ofs, size);
	#endif

	if (!mutex)
	{
		object_handle_t obj_handle;
		void *object_table = get_current_process()->object_table;
		
		int ret = open_kernel_object(object_table, *(uint32_t *)(emulator_api_base+umd_mutex_offset), (void **)&mutex, &obj_handle, SYS_MUTEX_OBJECT);
				
		if (ret != 0)
		{
			#ifdef DEBUG
			DPRINTF("Cannot open user mutex, using an own one\n");
			#endif
			mutex_create(&mutex, SYNC_PRIORITY, SYNC_NOT_RECURSIVE);
			user_mutex = 0;
		}
		else
		{
			#ifdef DEBUG
			DPRINTF("user mutex opened succesfully\n");
			#endif
			user_mutex = 1;
			close_kernel_object_handle(object_table, obj_handle);
		}
	}
	
	mutex_lock(mutex, 0);
	offset = sector*0x800;
	
	if (ofs != 0)
	{
		offset = offset+0x800-ofs;
	}
	
	ret = cellFsLseek(umd_fd, offset, SEEK_SET, &dummy);
	if (ret != 0)
	{
		mutex_unlock(mutex);
		return ret;
	}
	
	ret = cellFsRead(umd_fd, get_secure_user_ptr(buf), size, &dummy);
	mutex_unlock(mutex);
	
	if (ret == 0)
		ret = (int)size;
	
	return ret;
}
Example #7
0
int mutex_release(struct mutex_s * mutex) {
    /* Vérification des paramètres */
    if (mutex == NULL || mutex->owner != get_current_process()) {
        return -1;
    }

    mutex->owner = NULL;
    sem_up(&mutex->sem);
    return 0;
}
Example #8
0
SYSCALL_HANDLER3(sys_signal, uint32_t signum, sighandler_t handler, sighandler_t* ret)
{
	process_t* current = get_current_process();

	if (signum <= NSIG)	{
		*ret = current->signal_data.handlers[signum];
		current->signal_data.handlers[signum] = handler;
	} else {
		*ret = 0;
	}
}
Example #9
0
SYSCALL_HANDLER2(sys_dup, int oldfd, int *ret) {
	int i = 0;
	process_t* process = get_current_process();

	// recherche d'une place dans la file descriptor table du process :
	while(process->fd[i]) {
		i++;
	}

	process->fd[i] = process->fd[oldfd];

	*ret = i;
}
Example #10
0
void mutex_lock(mutex_t *mutex)
{
	/* Mutexes only make sense in a preemptable environment */
	if(!is_kernel_preempt()) return;

	/* Return of we already own the lock */
	if(mutex->owner==get_current_process() && mutex->state==MUTEX_LOCKED) return;

	/* Disable kernel preemption */
	disable_kernel_preempt();

	/* Spin while Mutex is locked */
	while(mutex->state==MUTEX_LOCKED){
		mutex_wait();
	}

	/* Finally lock the Mutex */
	mutex->state=MUTEX_LOCKED;
	mutex->owner=get_current_process();

	/* Now we can safely re-enable preemption */
	enable_kernel_preempt();
}
Example #11
0
//pszFilename must have room for at least MaxPath+1 characters
static inline bool get_file_name_from_handle_function
(void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
{
    if(length <= MaxPath) {
        return false;
    }

    void *hiPSAPI = load_library("PSAPI.DLL");
    if (0 == hiPSAPI)
        return 0;

    class library_unloader
    {
        void *lib_;

    public:
        library_unloader(void *module) : lib_(module) {}
        ~library_unloader() {
            free_library(lib_);
        }
    } unloader(hiPSAPI);

    //  Pointer to function getMappedFileName() in PSAPI.DLL
    GetMappedFileName_t pfGMFN =
        (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW");
    if (! pfGMFN) {
        return 0;      //  Failed: unexpected error
    }

    bool bSuccess = false;

    // Create a file mapping object.
    void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0);
    if(hFileMap)
    {
        // Create a file mapping to get the file name.
        void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0);

        if (pMem) {
            out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
            if(out_length) {
                bSuccess = true;
            }
            unmap_view_of_file(pMem);
        }
        close_handle(hFileMap);
    }

    return(bSuccess);
}
Example #12
0
int before_block_exec(CPUState *env, TranslationBlock *tb) {
    int i;

    OsiProc *current = get_current_process(env);
    printf("Current process: %s PID:" TARGET_FMT_ld " PPID:" TARGET_FMT_ld "\n", current->name, current->pid, current->ppid);

    OsiModules *ms = get_libraries(env, current);
    if (ms == NULL) {
        printf("No mapped dynamic libraries.\n");
    }
    else {
        printf("Dynamic libraries list (%d libs):\n", ms->num);
        for (i = 0; i < ms->num; i++)
            printf("\t0x" TARGET_FMT_lx "\t" TARGET_FMT_ld "\t%-24s %s\n", ms->module[i].base, ms->module[i].size, ms->module[i].name, ms->module[i].file);
    }

    printf("\n");

    OsiProcs *ps = get_processes(env);
    if (ps == NULL) {
        printf("Process list not available.\n");
    }
    else {
        printf("Process list (%d procs):\n", ps->num);
        for (i = 0; i < ps->num; i++)
            printf("  %-16s\t" TARGET_FMT_ld "\t" TARGET_FMT_ld "\n", ps->proc[i].name, ps->proc[i].pid, ps->proc[i].ppid);
    }

    printf("\n");

    OsiModules *kms = get_modules(env);
    if (kms == NULL) {
        printf("No mapped kernel modules.\n");
    }
    else {
        printf("Kernel module list (%d modules):\n", kms->num);
        for (i = 0; i < kms->num; i++)
            printf("\t0x" TARGET_FMT_lx "\t" TARGET_FMT_ld "\t%-24s %s\n", kms->module[i].base, kms->module[i].size, kms->module[i].name, kms->module[i].file);
    }

    printf("\n-------------------------------------------------\n\n");

    // Cleanup
    free_osiproc(current);
    free_osiprocs(ps);
    free_osimodules(ms);

    return 0;
}
Example #13
0
int mutex_acquire(struct mutex_s * mutex) {
    /* Vérification des paramètres */
    if (mutex == NULL) {
        return -1;
    }

    /* Processus :
     * - sem_down bloque le process courant si le mutex est déjà bloqué
     * - immédiatement après, on est sûr que le processus courant a
     *   vérouillé le mutex
     */
    /* FIXME fait planter le kernel */
    sem_down(&mutex->sem);
    mutex->owner = get_current_process();
    return 0;
}
Example #14
0
SYSCALL_HANDLER2(sys_dup2, int oldfd, int *newfd) {
	process_t* process = get_current_process();

	if (process->fd[oldfd]) {
		if (process->fd[*newfd]) {
			if (process->fd[*newfd]->f_ops->close != NULL) {
				process->fd[*newfd]->f_ops->close(process->fd[*newfd]);
			}
		}

		process->fd[*newfd] = process->fd[oldfd];

	} else {
		*newfd = -1;
	}
}
Example #15
0
SYSCALL_HANDLER3(sys_ioctl, uint32_t *fd, unsigned int request, void *data) {
	process_t * process = get_current_process();

	open_file_descriptor *ofd;

	if (process->fd[*fd]) {
		ofd = process->fd[*fd];

		if (ofd->f_ops->ioctl == NULL) {
			kerr("No \"ioctl\" method for this device.");
			*fd = -1;
		}
		else {
			*fd = ofd->f_ops->ioctl(ofd, request, data);
		}
	}
}
Example #16
0
SYSCALL_HANDLER3(sys_seek, uint32_t fd, long *offset, int whence) {
	process_t * process = get_current_process();

	open_file_descriptor *ofd;

	if (process->fd[fd]) {
		ofd = process->fd[fd];
		
		if(ofd->f_ops->seek == NULL) {
			kerr("No \"seek\" method for this device.");
			*offset = -1;
		} else {
			ofd->f_ops->seek(ofd, *offset, whence);
			*offset = ofd->current_octet;
		}
	}
}
Example #17
0
SYSCALL_HANDLER3(sys_write, uint32_t fd, const void *buf, size_t *c) {
	process_t * process = get_current_process();
	ssize_t *t = (ssize_t*)c;
	open_file_descriptor *ofd;

	if (process->fd[fd]) {
		ofd = process->fd[fd];
		
		if(ofd->f_ops->write == NULL) {
			kerr("No \"write\" method for this device.");
			*t = -1;
		} else {
			*t = ofd->f_ops->write(ofd, buf, *c);
		}
	} else {
		*t = -1;
	}
}
Example #18
0
/* TODO: d'après POSIX, kill(-1, sig) doit envoyer le signal à tous les processus possibles... */
SYSCALL_HANDLER3(sys_kill, int pid, int signum, int* ret)
{	
	process_t* process = find_process(pid);
	
	int retour = -1;
	
	if(process != NULL)
	{
		retour = sigaddset( &(process->signal_data.pending_set), signum );
		
		klog("%d sending signal %s(%d) to pid %d.", get_current_process()->pid, signal_names[signum], signum, pid);
	}
	else
	{
		kerr("Process not found (%d).", pid);
	}
	
	if(ret!=NULL)
		*ret = retour;
}
Example #19
0
int ksemP(uint8_t key)
{
	int ret = -1;
	sem_t* sem = &semaphores[key];
	
	if (sem->allocated) {	
		/* Si le sémaphore est libre, on le prend, sinon, on attend */
		if(sem->value >= 1) {
			sem->value--;
		} else {
			process_t* proc = get_current_process();
			/* Si on attend, on met le pid dans la file d'attente pour pouvoir traiter le processus quand le semaphore sera libre */
			sem_fifo_put(&(sem->fifo), proc->pid);
			set_state_waiting();
		}

		ret = 0;
	}
	
	return ret;
}
Example #20
0
uintptr_t map_virtual_virtual(uintptr_t* _vastart, uintptr_t vaend, bool readonly) {
    uintptr_t vastart = *_vastart;
    uintptr_t vaoffset = vastart % 0x1000;
    vastart = ALIGN_DOWN(vastart, 0x1000);
    vaend = ALIGN_UP(vaend, 0x1000);

    proc_t* proc = get_current_process();

    mmap_area_t** _hole = find_va_hole(proc, vaend-vastart, 0x1000);
    mmap_area_t* hole = *_hole;
    if (hole == NULL) {
        return 0;
    }
    hole->mtype = kernel_allocated_heap_data;
    uintptr_t temporary = hole->vastart;
    if (!map_range(_vastart, vaend, &temporary, hole->vaend, true, readonly, false, proc->pml4)) {
        free_mmap_area(hole, _hole, proc);
        return 0;
    }
    return hole->vastart+vaoffset;
}
Example #21
0
int coverage_before_block_exec(CPUState *env, TranslationBlock *tb) {
#ifdef CONFIG_SOFTMMU
    OsiProc *p = get_current_process(env);
    uint64_t asid = panda_current_asid(env);    
    if (process_asid == 0) {
        // look for process matching the one we want
        if (p && p->name) {
            if (strcmp(process_name, p->name) == 0) {
                process_asid = asid;
                printf ("coverage plugin: saw cr3=0x%" PRIx64 " for process=[%s]\n",
                        asid, process_name);
            }
        }
    }
    if (process_asid !=0 && process_asid == asid) {
        // collect bb for this asid
        process_bb.insert(tb->pc);
        // and count number of bb executed (regardless of repetetion)
        process_total_bb ++;
    }
    free_osiproc(p);
#endif
    return 0;
}
Example #22
0
void *virtual_alloc(void *addr, uintptr_t size,
    uint32_t allocation_type, uint32_t protection)
{
    return virtual_alloc_ex(get_current_process(), addr, size,
        allocation_type, protection);
}
Example #23
0
int virtual_free(const void *addr, uintptr_t size, uint32_t free_type)
{
    return virtual_free_ex(get_current_process(), addr, size, free_type);
}
Example #24
0
/* Checks if given address range in the context of the current process is under
 * surveillance.
 * Param:
 *  addr - Starting address of a range.
 *  size - Range size.
 * Return:
 *  boolean: 1 if address range contains memory that require access violation
 *  detection, or 0 if given address range is in no interest to the memchecker.
 */
int
memcheck_is_checked(target_ulong addr, uint32_t size) {
    return procdesc_contains_allocs(get_current_process(), addr, size) ? 1 : 0;
}
Example #25
0
NTSTATUS virtual_protect(const void *addr, uintptr_t size,
    uint32_t protection)
{
    return virtual_protect_ex(get_current_process(), addr, size, protection);
}
Example #26
0
/* Validates access to a guest address.
 * Param:
 *  addr - Virtual address in the guest space where memory is accessed.
 *  data_size - Size of the accessed data.
 *  proc_ptr - Upon exit from this routine contains pointer to the process
 *      descriptor for the current process, or NULL, if no such descriptor has
 *      been found.
 *  desc_ptr - Upon exit from this routine contains pointer to the allocation
 *      descriptor matching given address range, or NULL, if allocation
 *      descriptor for the validated memory range has not been found.
 * Return:
 *  0 if access to the given guest address range doesn't violate anything, or
 *  1 if given guest address range doesn't match any entry in the current
 *      process allocation descriptors map, or
 *  -1 if a violation has been detected.
 */
static int
memcheck_common_access_validation(target_ulong addr,
                                  uint32_t data_size,
                                  ProcDesc** proc_ptr,
                                  MallocDescEx** desc_ptr)
{
    MallocDescEx* desc;
    target_ulong validating_range_end;
    target_ulong user_range_end;

    ProcDesc* proc = get_current_process();
    *proc_ptr = proc;
    if (proc == NULL) {
        *desc_ptr = NULL;
        return 1;
    }

    desc = procdesc_find_malloc_for_range(proc, addr, data_size);
    *desc_ptr = desc;
    if (desc == NULL) {
        return 1;
    }

    /* Verify that validating address range doesn't start before the address
     * available to the user. */
    if (addr < mallocdesc_get_user_ptr(&desc->malloc_desc)) {
        // Stepped on the prefix guarding area.
        return -1;
    }

    validating_range_end = addr + data_size;
    user_range_end = mallocdesc_get_user_alloc_end(&desc->malloc_desc);

    /* Verify that validating address range ends inside the user block.
     * We may step on the suffix guarding area because of alignment issue.
     * For example, the application code reads last byte in the allocated block
     * with something like this:
     *
     *      char last_byte_value = *(char*)last_byte_address;
     *
     * and this code got compiled into something like this:
     *
     *      mov eax, [last_byte_address];
     *      mov [last_byte_value], al;
     *
     * In this case we will catch a read from the suffix area, even though
     * there were no errors in the code. So, in order to prevent such "false
     * negative" alarms, lets "forgive" this violation.
     * There is one bad thing about this "forgivness" though, as it may very
     * well be, that in real life some of these "out of bound" bytes will cross
     * page boundaries, marching into a page that has not been mapped to the
     * process.
     */
    if (validating_range_end <= user_range_end) {
        // Validating address range is fully contained inside the user block.
        return 0;
    }

    /* Lets see if this AV is caused by an alignment issue.*/
    if ((validating_range_end - user_range_end) < data_size) {
        /* Could be an alignment. */
        return 0;
    }

    return -1;
}
Example #27
0
NTSTATUS virtual_read(void *addr, void *buffer, uintptr_t *size)
{
    return virtual_read_ex(get_current_process(), addr, buffer, size);
}
Example #28
0
		case BASIC_PLUGINS_HASH:
			return "basic_plugins.sprx";
		break;*/
		
		default:
			return "UNKNOWN";
		break;		
	}
}

#endif

LV2_HOOKED_FUNCTION_PRECALL_2(int, post_lv1_call_99_wrapper, (uint64_t *spu_obj, uint64_t *spu_args))
{
	// This replaces an original patch of psjailbreak, since we need to do more things
	process_t process = get_current_process();

	saved_buf = (void *)spu_args[0x20/8];
	saved_sce_hdr = (void *)spu_args[8/8];

	if (process)
	{
		caller_process = process->pid;
			#ifdef	DEBUG
			//DPRINTF("caller_process = %08X\n", caller_process);
			#endif
	}

	return 0;
}
Example #29
0
/*pgtable sequential scan and count for __access_bits.*/
static int scan_pgtable(void)
{
	pgd_t *pgd = NULL;
	pud_t *pud = NULL;
	pmd_t *pmd = NULL;
	pte_t *ptep, pte;
	spinlock_t *ptl;

	struct mm_struct *mm;
	struct vm_area_struct *vma;
	unsigned long start = 0; /*the start of address.*/
	unsigned long end = 0;   /*the end of address.*/
	unsigned long address = 0; /* the address of vma.*/
	int number_hotpages = 0; /* the number of hot pages */
	int number_vpages = 0;
	int cycle_index = 0; /* the loop counter, which denotes ITERATIONS. */
	/* the array that records the number of hot page in every cycle */
	int hot_page[ITERATIONS];
	int number_current_pg = 0;
	int pg_count = 0;
	int j = 0;
	int times = 0; /* records reuse time*/

	/* some variables that describe page "heat" */
	int hig = 0;
	int mid = 0;
	int low = 0;
	int llow = 0;
	int lllow = 0;
	int llllow = 0;
	int all_pages = 0;/* the total number of pages */
	/*the average number of hot pages in each iteration.*/
	long avg_hotpage=0;
	/*the total number of memory accesses across all pages*/
	long num_access=0;
	/* avg utilization of each page */
	int avg_page_utilization = 0;

	/*get the handle of current running benchmark.*/
	struct task_struct *bench_process = get_current_process();
	if(bench_process == NULL)
	{
		printk("sysmon: get no process handle in scan_pgtable function...exit&trying again...\n");
		return 0;
	}
	else /* get the process*/
		mm = bench_process->mm;
	if(mm == NULL)
	{
		printk("sysmon: error mm is NULL, return back & trying...\n");
		return 0;
	}

	for(j = 0; j < PAGE_ALL; j++)
		page_heat[j] = -1;

	for(j = 0; j < ITERATIONS; j++)
	{
		hot_page[j] = 0;
		reuse_time[j] = 0;
		dirty_page[j] = 0;
	}

	/*yanghao*/
	times = 0;
	for(cycle_index = 0; cycle_index < ITERATIONS; cycle_index++)
	{
		number_hotpages = 0;
		/*scan each vma*/
		for(vma = mm->mmap; vma; vma = vma->vm_next)
		{
			start = vma->vm_start;
			end = vma->vm_end;
			mm = vma->vm_mm;
			/*in each vma, we check all pages*/
			for(address = start; address < end; address += PAGE_SIZE)
			{
				/*scan page table for each page in this VMA*/
				pgd = pgd_offset(mm, address);
				if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
					continue;
				pud = pud_offset(pgd, address);
				if (pud_none(*pud) || unlikely(pud_bad(*pud)))
					continue;
				pmd = pmd_offset(pud, address);
				if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
					continue;
				ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
				pte = *ptep;
				if(pte_present(pte))
				{
					if(pte_young(pte)) /*hot page*/
					{
						/*re-set and clear  _access_bits to 0*/
						pte = pte_mkold(pte);
						set_pte_at(mm, address, ptep, pte);
						/*yanghao:re-set and clear _dirty_bits to 0*/
						pte = pte_mkclean(pte);
						set_pte_at(mm, address, ptep, pte);
					}
				}
				else /*no page pte_none*/
				{
					pte_unmap_unlock(ptep, ptl);
					continue;
				}
				pte_unmap_unlock(ptep, ptl);
				page_counts++;
			}
		}
		/*count the number of hot pages*/
		if(bench_process == NULL)
		{
			printk("sysmon: get no process handle in scan_pgtable function...exit&trying again...\n");
			return 0;
		}
		else /*get the process*/
			mm = bench_process->mm;
		if(mm == NULL)
		{
			printk("sysmon: error mm is NULL, return back & trying...\n");
			return 0;
		}
		number_vpages = 0;

		sampling_interval = page_counts / 250; /*yanghao:*/
		page_counts = 0;

		for(vma = mm->mmap; vma; vma = vma->vm_next)
		{
			start = vma->vm_start;
			end = vma->vm_end;
			/*scan each page in this VMA*/
			mm = vma->vm_mm;
			pg_count = 0;
			for(address = start; address < end; address += PAGE_SIZE)
			{
				/*scan page table for each page in this VMA*/
				pgd = pgd_offset(mm, address);
				if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
					continue;
				pud = pud_offset(pgd, address);
				if (pud_none(*pud) || unlikely(pud_bad(*pud)))
					continue;
				pmd = pmd_offset(pud, address);
				if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
					continue;
				ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
				pte = *ptep;
				if(pte_present(pte))
				{
					if(pte_young(pte)) /* hot pages*/
					{
						number_current_pg = pg_count + number_vpages;
						page_heat[number_current_pg]++;
						hot_page[cycle_index]++;
						/*yanghao:*/
						if (page_counts == random_page)
						{
							times++;
							if (pte_dirty(pte))
								dirty_page[cycle_index] = 1;
						}
					}
					else
					{
						if (page_counts == random_page)
							reuse_time[times]++;
					}
				}
				pg_count++;
				pte_unmap_unlock(ptep, ptl);
				page_counts++;
			}
			number_vpages += (int)(end - start)/PAGE_SIZE;
		}
	}
	/*yanghao:cal. the No. of random_page*/
	random_page += sampling_interval;
	if(random_page >= page_counts)
		random_page=page_counts / 300;
	/*****************************OUTPUT************************************/
	for(j = 0; j < PAGE_ALL; j++)
	{
		if(page_heat[j] < VH && page_heat[j] > H)
			hig++;
		if(page_heat[j] > M && page_heat[j] <= H)
			mid++;
		if(page_heat[j] <= M && page_heat[j] > L)
			low++;
		if(page_heat[j] > VL_MAX && page_heat[j] <= L)
			llow++;
		if(page_heat[j] > VL_MIN && page_heat[j] <= VL_MAX)
			lllow++;
		if(page_heat[j] >= 0 && page_heat[j] <= VL_MIN)
			llllow++;
		if(page_heat[j] > -1)
			all_pages++;
	}

	/*the values reflect the accessing frequency of each physical page.*/
	printk("[LOG: after sampling (%d loops) ...] ",ITERATIONS);
	printk("the values denote the physical page accessing frequence.\n"); 
	printk("-->hig (150,200) is %d. Indicating the number of re-used pages is high.\n",hig);
	printk("-->mid (100,150] is %d.\n",mid);
	printk("-->low (64,100] is %d.\n",low);
	printk("-->llow (10,64] is %d. In locality,no too many re-used pages.\n",llow);
	printk("-->lllow (5,10] is %d.\n",lllow);
	printk("-->llllow [1,5] is %d.\n",llllow);

	for(j = 0;j < ITERATIONS; j++)
		avg_hotpage += hot_page[j];
	avg_hotpage /= (j+1);

	/*
	 * new step@20140704
	 * (1)the different phases of memory utilization
	 * (2)the avg. page accessing utilization
	 * (3)memory pages layout and spectrum
	 */
	for(j = 0; j < PAGE_ALL; j++)
		if(page_heat[j] > -1) /*the page that is accessed at least once.*/
			num_access += (page_heat[j] + 1);

	printk("the total number of memory accesses is %ld, the average is %ld\n",
			num_access, num_access / ITERATIONS);
	avg_page_utilization = num_access / all_pages;
	printk("Avg hot pages num is %ld, all used pages num is %d, avg utilization of each page is %d\n", 
			avg_hotpage, all_pages, avg_page_utilization);
	/*yanghao:print the information about reuse-distance*/
	if ((times == 0) && (reuse_time[0] ==0))
		printk("the page No.%d is not available.",random_page);
	else
	{
		if ((times == 0) && (reuse_time[0] == 0))
			printk("the page No.%d was not used in this 200 loops.",random_page);
		else
		{
			if (times < ITERATIONS)
				times++;
			printk("the reusetime of page No.%d is:",random_page);
			for (j = 0; j < times; j++)
				printk("%d ",reuse_time[j]);
			printk("\n");
			printk("the total number of the digit above denotes the sum that page NO.%d be accessd in %d loops.\n",
					random_page,ITERATIONS);
			printk("each digit means the sum loops that between current loop and the last loop.\n");
		}
	}
	printk("\n\n");
	return 1;
}
Example #30
0
int sys_psp_read_header(int fd, char *buf, uint64_t nbytes, uint64_t *nread)
{
	int ret;
	uint32_t n, unk2;
	uint64_t umd_size;
	sys_prx_id_t *list;
	uint32_t *unk;
	process_t process;
	
	#ifdef DEBUG
	DPRINTF("umd read header: %p %lx\n", buf, nbytes);
	#endif
	
	buf = get_secure_user_ptr(buf);
	nread = get_secure_user_ptr(nread);
		
	if (!umd_file || nbytes != 0x100)
		return EABORT;
	
	pemucorelib_base = 0;
	emulator_api_base = 0;
	list = alloc(SPRX_NUM*sizeof(sys_prx_module_info_t), 0x35);
	unk = alloc(SPRX_NUM*sizeof(uint32_t), 0x35);
	process = get_current_process();	
	
	ret = prx_get_module_list(process, list, unk, SPRX_NUM, &n, &unk2);
	if (ret == 0)
	{
		char *filename = alloc(256, 0x35);
		sys_prx_segment_info_t *segments = alloc(sizeof(sys_prx_segment_info_t), 0x35);
		
		for (int i = 0; i < SPRX_NUM; i++)
		{
			sys_prx_module_info_t modinfo;
			
			memset(&modinfo, 0, sizeof(sys_prx_module_info_t));
			modinfo.filename_size = 256;
			modinfo.segments_num = 1;
			
			if (prx_get_module_info(process, list[i], &modinfo, filename, segments) == 0)
			{
				if (strstr(filename, "/emulator_api.sprx"))
				{
					emulator_api_base = segments[0].base;
					#ifdef DEBUG
					DPRINTF("emulator_api base = %08lx\n", emulator_api_base);
					#endif	
				}
				else if (strstr(filename, "/PEmuCoreLib.sprx"))
				{
					pemucorelib_base = segments[0].base;						
					#ifdef DEBUG
					DPRINTF("PEmuCoreLib base = %08lx\n", pemucorelib_base);
					#endif
				}
			}
		}
		
		if (pemucorelib_base == 0 || emulator_api_base == 0)
			ret = EABORT;
		
		dealloc(filename, 0x35);
		dealloc(segments, 0x35);
	}
	
	dealloc(list, 0x35);
	dealloc(unk, 0x35);
	
	if (ret != 0)
		return ret;
		
	ret = cellFsOpen(umd_file, CELL_FS_O_RDONLY, &umd_fd, 0, NULL, 0);
	if (ret != 0)
		return ret;
	
	cellFsLseek(umd_fd, 0, SEEK_END, &umd_size);
	// Fake header. We will write only values actually used
	memset(buf, 0, 0x100);
	*(uint32_t *)(buf+0x0c) = 0x10;
	*(uint32_t *)(buf+0x64) = (umd_size/0x800)-1; // Last sector of umd	
	strncpy(buf+0x70, psp_id, 10);
						
	#ifdef DEBUG
	DPRINTF("ID: %s\n", psp_id);
	#endif
	
	if (mutex && user_mutex)
	{
		mutex = NULL;
		user_mutex = 0;
	}
	
	*nread = 0x100;
	return 0;
}