title: print the data corresponding to page table entry
body: <p>I am new to systems programming. I wanted to know how to get the data that corresponds to a page table entry (pte).Here is my setup.</p>
  
  <p>I have a page table entry value a601a865 that corresponds to a virtual address bfcdd360 that has content of 6. I needed to get/access the contents using the physical address a601a865. </p>
  
  <p>I am using uint64_t as the data type for pte and virtual address is of type target_ulong. How do I perform it?</p>
  
  <p>This is the code I used  to find the PTE</p>
  
  <pre><code>#define EXCPOE_PAGE 14
  hwaddr x86_cpu_handle_enc_page_fault(CPUState *cs, vaddr addr, 
  int is_write1,int mmu_idx)
  {
  X86CPU *cpu = X86_CPU(cs);
  CPUX86State *env = &amp;cpu-&gt;env;
  uint64_t ptep, pte;
  target_ulong pde_addr, pte_addr;
  int error_code = 0;
  int is_dirty, prot, page_size, is_write, is_user;
  hwaddr paddr;
  
  uint64_t rsvd_mask = PG_HI_RSVD_MASK;
  uint32_t page_offset;
  target_ulong vaddr;
  
  
  is_user = mmu_idx == MMU_USER_IDX;
  
  printf("\n Getting inside the x86_cpu_handle_enc_page_fault -- virtual address %x \n", addr);    
  
  #if defined(DEBUG_MMU)
  printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
         addr, is_write1, is_user, env-&gt;eip);
  #endif
  is_write = is_write1 &amp; 1;
  
  if (!(env-&gt;cr[0] &amp; CR0_PG_MASK)) {
      pte = addr;
  #ifdef TARGET_X86_64
      if (!(env-&gt;hflags &amp; HF_LMA_MASK)) {
          /* Without long mode we can only address 32bits in real mode */
          pte = (uint32_t)pte;
      }
  #endif
      prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
      page_size = 4096;
      goto do_mapping;
  }
  
  if (!(env-&gt;efer &amp; MSR_EFER_NXE)) {
      rsvd_mask |= PG_NX_MASK;
  }
  
  if (env-&gt;cr[4] &amp; CR4_PAE_MASK) {
      uint64_t pde, pdpe;
      target_ulong pdpe_addr;
  
  #ifdef TARGET_X86_64
  
        if (env-&gt;hflags &amp; HF_LMA_MASK) {
          uint64_t pml4e_addr, pml4e;
          int32_t sext;
  
          //printf("Getting inside the env-&gt;hflags &amp; HF_LMA_MASK \n");
  
          /* test virtual address sign extension */
          sext = (int64_t)addr &gt;&gt; 47;
          if (sext != 0 &amp;&amp; sext != -1) {
              env-&gt;error_code = 0;
              cs-&gt;exception_index = EXCP0D_GPF;
              return 1;
          }
  
          pml4e_addr = ((env-&gt;cr[3] &amp; ~0xfff) + (((addr &gt;&gt; 39) &amp; 0x1ff) &lt;&lt; 3)) &amp;
              env-&gt;a20_mask;
          pml4e = ldq_phys(cs-&gt;as, pml4e_addr);
  
          //printf("env-&gt;hflags &amp; HF_LMA_MASK -- pml4e_addr %x \n",pml4e_addr);
          //printf("env-&gt;hflags &amp; HF_LMA_MASK -- pml4e %x \n",pml4e);
  
          if (!(pml4e &amp; PG_PRESENT_MASK)) {
              goto do_fault;
          }
          if (pml4e &amp; (rsvd_mask | PG_PSE_MASK)) {
              goto do_fault_rsvd;
          }
          if (!(pml4e &amp; PG_ACCESSED_MASK)) {
              pml4e |= PG_ACCESSED_MASK;
              stl_phys_notdirty(cs-&gt;as, pml4e_addr, pml4e);
          }
          ptep = pml4e ^ PG_NX_MASK;
          pdpe_addr = ((pml4e &amp; PG_ADDRESS_MASK) + (((addr &gt;&gt; 30) &amp; 0x1ff) &lt;&lt; 3)) &amp;
              env-&gt;a20_mask;
          pdpe = ldq_phys(cs-&gt;as, pdpe_addr);
  
         // printf("env-&gt;hflags &amp; HF_LMA_MASK-- pdpe_addr %x \n",pde_addr);
         // printf("env-&gt;hflags &amp; HF_LMA_MASK -- pdpe %x \n",pde);
  
          if (!(pdpe &amp; PG_PRESENT_MASK)) {
              goto do_fault;
          }
          if (pdpe &amp; rsvd_mask) {
              goto do_fault_rsvd;
          }
          ptep &amp;= pdpe ^ PG_NX_MASK;
          if (!(pdpe &amp; PG_ACCESSED_MASK)) {
              pdpe |= PG_ACCESSED_MASK;
              stl_phys_notdirty(cs-&gt;as, pdpe_addr, pdpe);
          }
          if (pdpe &amp; PG_PSE_MASK) {
              /* 1 GB page */
              page_size = 1024 * 1024 * 1024;
              pte_addr = pdpe_addr;
              pte = pdpe;
              goto do_check_protect;
          }
      } else
      #endif
      {
          printf("\n");
          printf("Getting inside the 64-bit paging \n");
          /* XXX: load them when cr3 is loaded ? */
          pdpe_addr = ((env-&gt;cr[3] &amp; ~0x1f) + ((addr &gt;&gt; 27) &amp; 0x18)) &amp;
              env-&gt;a20_mask;
          pdpe = ldq_phys(cs-&gt;as, pdpe_addr);
  
          printf("64-bit paging -- cr3 loaded -- pdpe_addr %x \n",pdpe_addr);
          printf("64-bit paging -- cr3 loaded -- cs-&gt;as %x \n",cs-&gt;as);
          printf("64-bit paging -- cr3 loaded -- pdpe %x \n",pde);
  
          if (!(pdpe &amp; PG_PRESENT_MASK)) {
              goto do_fault;
          }
          rsvd_mask |= PG_HI_USER_MASK;
          if (pdpe &amp; (rsvd_mask | PG_NX_MASK)) {
              goto do_fault_rsvd;
          }
          ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
      }
  
      pde_addr = ((pdpe &amp; PG_ADDRESS_MASK) + (((addr &gt;&gt; 21) &amp; 0x1ff) &lt;&lt; 3)) &amp;
          env-&gt;a20_mask;
      pde = ldq_phys(cs-&gt;as, pde_addr);
  
          printf("\n");
          printf("64-bit paging -- pde_addr %x \n",pde_addr);
          printf("64-bit paging -- cs-&gt;as %x \n",cs-&gt;as);
          printf("64-bit paging -- pde %x \n",pde);
  
      if (!(pde &amp; PG_PRESENT_MASK)) {
          goto do_fault;
      }
      if (pde &amp; rsvd_mask) {
          goto do_fault_rsvd;
      }
      ptep &amp;= pde ^ PG_NX_MASK;
      if (pde &amp; PG_PSE_MASK) {
          /* 2 MB page */
          page_size = 2048 * 1024;
          pte_addr = pde_addr;
          pte = pde;
          goto do_check_protect;
      }
      /* 4 KB page */
      if (!(pde &amp; PG_ACCESSED_MASK)) {
          pde |= PG_ACCESSED_MASK;
          stl_phys_notdirty(cs-&gt;as, pde_addr, pde);
      }
      pte_addr = ((pde &amp; PG_ADDRESS_MASK) + (((addr &gt;&gt; 12) &amp; 0x1ff) &lt;&lt; 3)) &amp;
          env-&gt;a20_mask;
      pte = ldq_phys(cs-&gt;as, pte_addr);
  
      printf("\n");
      printf("64-bit paging -- pte_addr %x \n",pte_addr);
      printf("64-bit paging -- cs-&gt;as %x \n",cs-&gt;as);
      printf("64-bit paging -- pte %x \n",pte);
  
      if (!(pte &amp; PG_PRESENT_MASK)) {
          goto do_fault;
          //pte |= PG_ENC_MASK;  /* Mark the entries with PG_ENC_MASK */
          //printf("Marked the addresses corresponding to Enclave with PG_ENC_MASK successfuly \n");
      }
      // else {
      //printf("\n");    
      //printf("About to map the PTE %x with enclave page mask \n",pte);    
      //pte |= PG_ENC_MASK;  /* Map the entries with PG_ENC_MASK */
      //printf("After Mapping it with PG_ENC_MASK %x \n",pte);
      //printf("Mapped the PTE that points to 4K physical page corresponding to Enclave virtual address %x with PG_ENC_MASK successfuly \n",addr);
  
      //}
      if (pte &amp; rsvd_mask) {
          goto do_fault_rsvd;
      }
      /* combine pde and pte nx, user and rw protections */
      ptep &amp;= pte ^ PG_NX_MASK;
      page_size = 4096;
  
  } else {
  
      uint32_t pde;
      printf("\n Getting inside the 32-bit paging, virtual address %x \n", addr);
      printf("Value inside the cr3 register is %"PRIx32" \n", env-&gt;cr[3]);
  
      /* page directory entry */
      pde_addr = ((env-&gt;cr[3] &amp; ~0xfff) + ((addr &gt;&gt; 20) &amp; 0xffc)) &amp;
          env-&gt;a20_mask;
      pde = ldl_phys(cs-&gt;as, pde_addr);
  
      printf("32-bit paging -- pde_addr %x \n",pde_addr);
      printf("cs-&gt;as %x\n",cs-&gt;as);
      printf("32-bit paging -- pde %x \n",pde);
  
  
      if (!(pde &amp; PG_PRESENT_MASK)) {
          goto do_fault;
      }
      ptep = pde | PG_NX_MASK;
  
      /* if PSE bit is set, then we use a 4MB page */
      if ((pde &amp; PG_PSE_MASK) &amp;&amp; (env-&gt;cr[4] &amp; CR4_PSE_MASK)) {
          page_size = 4096 * 1024;
          pte_addr = pde_addr;
  
          /* Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
           * Leave bits 20-13 in place for setting accessed/dirty bits below.
           */
          pte = pde | ((pde &amp; 0x1fe000) &lt;&lt; (32 - 13));
          rsvd_mask = 0x200000;
          goto do_check_protect_pse36;
      }
  
      if (!(pde &amp; PG_ACCESSED_MASK)) {
          pde |= PG_ACCESSED_MASK;
          stl_phys_notdirty(cs-&gt;as, pde_addr, pde);
      }
  
      /* page directory entry */
      pte_addr = ((pde &amp; ~0xfff) + ((addr &gt;&gt; 10) &amp; 0xffc)) &amp;
          env-&gt;a20_mask;
      pte = ldl_phys(cs-&gt;as, pte_addr);
  
      printf("32-bit paging -- pte_addr %x\n",pte_addr);
      printf("32-bit paging -- pte %x\n",pte);
  
  
      if (!(pte &amp; PG_PRESENT_MASK)) {
          goto do_fault;
      //pte |= PG_ENC_MASK;                 /* Mark the entries with PG_ENC_MASK */
      //printf("Mapped the addresses corresponding to Enclave with PG_ENC_MASK successfuly \n");    
  
      }
  
  
      /* combine pde and pte user and rw protections */
      ptep &amp;= pte | PG_NX_MASK;
  
      page_size = 4096;
      rsvd_mask = 0;
  }
  
  do_check_protect:
  rsvd_mask |= (page_size - 1) &amp; PG_ADDRESS_MASK &amp; ~PG_PSE_PAT_MASK;
  
  do_check_protect_pse36:
  if (pte &amp; rsvd_mask) {
      goto do_fault_rsvd;
  }
  ptep ^= PG_NX_MASK;
  if ((ptep &amp; PG_NX_MASK) &amp;&amp; is_write1 == 2) {
      goto do_fault_protect;
  }
  
  switch (mmu_idx) {
  case MMU_USER_IDX:
      if (!(ptep &amp; PG_USER_MASK)) {
          goto do_fault_protect;
      }
      if (is_write &amp;&amp; !(ptep &amp; PG_RW_MASK)) {
          goto do_fault_protect;
      }
      break;
  
  case MMU_KSMAP_IDX:
      if (is_write1 != 2 &amp;&amp; (ptep &amp; PG_USER_MASK)) {
          goto do_fault_protect;
      }
      /* fall through */
  case MMU_KNOSMAP_IDX:
      if (is_write1 == 2 &amp;&amp; (env-&gt;cr[4] &amp; CR4_SMEP_MASK) &amp;&amp;
          (ptep &amp; PG_USER_MASK)) {
          goto do_fault_protect;
      }
      if ((env-&gt;cr[0] &amp; CR0_WP_MASK) &amp;&amp;
          is_write &amp;&amp; !(ptep &amp; PG_RW_MASK)) {
          goto do_fault_protect;
      }
      break;
  
  default: /* cannot happen */
      break;
  }
  is_dirty = is_write &amp;&amp; !(pte &amp; PG_DIRTY_MASK);
  if (!(pte &amp; PG_ACCESSED_MASK) || is_dirty) {
      pte |= PG_ACCESSED_MASK;
      if (is_dirty) {
          pte |= PG_DIRTY_MASK;
      }
      stl_phys_notdirty(cs-&gt;as, pte_addr, pte);
  }
  
  /* the page can be put in the TLB */
  prot = PAGE_READ;
  if (!(ptep &amp; PG_NX_MASK) &amp;&amp;
      (mmu_idx == MMU_USER_IDX ||
       !((env-&gt;cr[4] &amp; CR4_SMEP_MASK) &amp;&amp; (ptep &amp; PG_USER_MASK)))) {
      prot |= PAGE_EXEC;
  }
  if (pte &amp; PG_DIRTY_MASK) {
      /* only set write access if already dirty... otherwise wait
         for dirty access */
      if (is_user) {
          if (ptep &amp; PG_RW_MASK)
              prot |= PAGE_WRITE;
      } else {
          if (!(env-&gt;cr[0] &amp; CR0_WP_MASK) ||
              (ptep &amp; PG_RW_MASK))
              prot |= PAGE_WRITE;
      }
  }
  do_mapping:
  printf("\n");
  printf("Inside do_mapping pte is %x\n",pte);
  pte = pte &amp; env-&gt;a20_mask;
  
  pte |= PG_ENC_MASK; 
  printf("PTE after enclave_page_mask %x \n",pte);
  
  /* align to page_size */
  pte &amp;= PG_ADDRESS_MASK &amp; ~(page_size - 1);
  printf("Inside do_mapping pte after alignment is %x\n",pte);
  
  /* Even if 4MB pages, we map only one 4KB page in the cache to
     avoid filling it too fast */
  vaddr = addr &amp; TARGET_PAGE_MASK;
  page_offset = vaddr &amp; (page_size - 1);
  paddr = pte + page_offset;
  
  printf("Physical address is %x\n",paddr);
  //printf("Contents at physical address is %x\n",*;
  
  tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
  return 0;
  do_fault_rsvd:
  error_code |= PG_ERROR_RSVD_MASK;
  do_fault_protect:
  error_code |= PG_ERROR_P_MASK;
  do_fault:
  error_code |= (is_write &lt;&lt; PG_ERROR_W_BIT);
  if (is_user)
      error_code |= PG_ERROR_U_MASK;
  if (is_write1 == 2 &amp;&amp;
      (((env-&gt;efer &amp; MSR_EFER_NXE) &amp;&amp;
        (env-&gt;cr[4] &amp; CR4_PAE_MASK)) ||
       (env-&gt;cr[4] &amp; CR4_SMEP_MASK)))
      error_code |= PG_ERROR_I_D_MASK;
  if (env-&gt;intercept_exceptions &amp; (1 &lt;&lt; EXCP0E_PAGE)) {
      /* cr2 is not modified in case of exceptions */
      stq_phys(cs-&gt;as,
               env-&gt;vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
               addr);
  } else {
      env-&gt;cr[2] = addr;
  }
  env-&gt;error_code = error_code;
  cs-&gt;exception_index = EXCP0E_PAGE;
  return 1;
  }
  </code></pre>