コード例 #1
0
int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
		       unsigned long pfn, unsigned long size, pgprot_t prot)
{
	int error = 0;
	pgd_t * dir;
	unsigned long beg = from;
	unsigned long end = from + size;
	struct mm_struct *mm = vma->vm_mm;
	int space = GET_IOSPACE(pfn);
	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;

	/* See comment in mm/memory.c remap_pfn_range */
	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
	vma->vm_pgoff = (offset >> PAGE_SHIFT) |
		((unsigned long)space << 28UL);

	offset -= from;
	dir = pgd_offset(mm, from);
	flush_cache_range(vma, beg, end);

	while (from < end) {
		pmd_t *pmd = pmd_alloc(mm, dir, from);
		error = -ENOMEM;
		if (!pmd)
			break;
		error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space);
		if (error)
			break;
		from = (from + PGDIR_SIZE) & PGDIR_MASK;
		dir++;
	}

	flush_tlb_range(vma, beg, end);
	return error;
}
コード例 #2
0
int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
		unsigned long pfn, unsigned long size, pgprot_t prot)
{
	int error = 0;
	pgd_t * dir;
	unsigned long beg = from;
	unsigned long end = from + size;
	struct mm_struct *mm = vma->vm_mm;
	int space = GET_IOSPACE(pfn);
	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;

	prot = __pgprot(pg_iobits);
	offset -= from;
	dir = pgd_offset(mm, from);
	flush_cache_range(vma, beg, end);

	spin_lock(&mm->page_table_lock);
	while (from < end) {
		pud_t *pud = pud_alloc(current->mm, dir, from);
		error = -ENOMEM;
		if (!pud)
			break;
		error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space);
		if (error)
			break;
		from = (from + PGDIR_SIZE) & PGDIR_MASK;
		dir++;
	}
	flush_tlb_range(vma, beg, end);
	spin_unlock(&mm->page_table_lock);

	return error;
}
コード例 #3
0
int get_phy_addr(ull *out_phy_addr, ull pid, ull virt_addr) {
	int pagemap_fd;
	char pagemap_path[256];
	ull pagesize;
	ull pagesizemask;
	ull index;
	ull offset;
	ull seek_result;

	if (pid > 0) {
		sprintf(pagemap_path, "/proc/%llu/pagemap", pid);
	} else {	// pid == 0
		sprintf(pagemap_path, "/proc/self/pagemap");
	}

	pagemap_fd = open(pagemap_path, O_RDONLY);
	if (pagemap_fd == -1) {
		fprintf(stderr, "failed to open %s\n", pagemap_path);
		return -1;
	}

	pagesize = (ull)memtester_pagesize();
	pagesizemask = ~(pagesize - 1);

	index = (((virt_addr & pagesizemask) / pagesize) * sizeof(ull));
	offset = (virt_addr & (~pagesizemask));

	seek_result = (ull)lseek64(pagemap_fd, (off64_t)index, SEEK_SET);
	if (seek_result != index) {
		fprintf(stderr, "failed to seek\n");
		close(pagemap_fd);
		return -2;
	}

	if (read(pagemap_fd, (void *)out_phy_addr, (size_t)sizeof(ull)) != sizeof(ull)) {
		fprintf(stderr, "failed to read\n");
		close(pagemap_fd);
		return -3;
	}

	close(pagemap_fd);

	if (IS_PRESENT(*out_phy_addr)) {

		*out_phy_addr = GET_PFN(*out_phy_addr);
		*out_phy_addr = *out_phy_addr * pagesize;
		*out_phy_addr = *out_phy_addr + offset;

		return 0;

	} else {
		fprintf(stderr, "invalide pfn\n");
		return -4;
	}
}
コード例 #4
0
ファイル: pagemap.c プロジェクト: weehowe-z/Backup
int read_pagemap(char * path_buf, unsigned long virt_addr){
   printf("Big endian? %d\n", is_bigendian());
   f = fopen(path_buf, "rb");
   if(!f){
      printf("Error! Cannot open %s\n", path_buf);
      return -1;
   }
   
   //Shifting by virt-addr-offset number of bytes
   //and multiplying by the size of an address (the size of an entry in pagemap file)
   file_offset = virt_addr / getpagesize() * PAGEMAP_ENTRY;
   printf("Vaddr: 0x%lx, Page_size: %d, Entry_size: %d\n", virt_addr, getpagesize(), PAGEMAP_ENTRY);
   printf("Reading %s at 0x%llx\n", path_buf, (unsigned long long) file_offset);
   status = fseek(f, file_offset, SEEK_SET);
   if(status){
      perror("Failed to do fseek!");
      return -1;
   }
   errno = 0;
   read_val = 0;
   unsigned char c_buf[PAGEMAP_ENTRY];
   for(i=0; i < PAGEMAP_ENTRY; i++){
      c = getc(f);
      if(c==EOF){
         printf("\nReached end of the file\n");
         return 0;
      }
      if(is_bigendian())
           c_buf[i] = c;
      else
           c_buf[PAGEMAP_ENTRY - i - 1] = c;
      printf("[%d]0x%x ", i, c);
   }
   for(i=0; i < PAGEMAP_ENTRY; i++){
      //printf("%d ",c_buf[i]);
      read_val = (read_val << 8) + c_buf[i];
   }
   printf("\n");
   printf("Result: 0x%llx\n", (unsigned long long) read_val);
   //if(GET_BIT(read_val, 63))
   if(GET_BIT(read_val, 63))
      printf("PFN: 0x%llx\n",(unsigned long long) GET_PFN(read_val));
   else
      printf("Page not present\n");
   if(GET_BIT(read_val, 62))
      printf("Page swapped\n");
   fclose(f);
   return 0;
}
コード例 #5
0
ファイル: pagemap_read.c プロジェクト: dkohlbre/dram-hammers
unsigned long long read_pagemap(void* virt_addr){
  int i, c, status;
  uint64_t read_val, file_offset;
  if(!f){
    f = fopen("/proc/self/pagemap","rb");
  }
  if(!f){
    printf("Pagemap Read Error! Cannot open\n");
    return 0;
  }

  //Shifting by virt-addr-offset number of bytes
  //and multiplying by the size of an address (the size of an entry in pagemap file)
  file_offset = ((unsigned long long)virt_addr) / getpagesize() * PAGEMAP_ENTRY;
  status = fseek(f, file_offset, SEEK_SET);
  if(status){
    perror("Failed to do fseek!");
    return 0;
  }
  errno = 0;
  read_val = 0;
  unsigned char c_buf[PAGEMAP_ENTRY];
  for(i=0; i < PAGEMAP_ENTRY; i++){
    c = getc(f);
    if(c==EOF){
      return 0;
    }
    c_buf[PAGEMAP_ENTRY - i - 1] = c;
  }
  for(i=0; i < PAGEMAP_ENTRY; i++){
    read_val = (read_val << 8) + c_buf[i];
  }
  if(GET_BIT(read_val, 63))
    return (unsigned long long) GET_PFN(read_val);
  else
    return 0;

  fseek(f,0,SEEK_SET);
  return 0;
}