Esempio n. 1
0
/*
 * Function: freeSecureMemory()
 *
 * Description:
 *  Free a single page of secure memory.
 *
 * Inputs:
 *  p    - The first virtual address of the secure memory to free.
 *  size - The amount of secure memory to allocate measured in bytes.
 *
 */
void
freeSecureMemory (void) {
  /*
   * Get the current interrupt context; the arguments will be in it.
   */
  sva_icontext_t * icp = getCPUState()->newCurrentIC;

  /*
   * Get the pointer address and size out of the interrupt context.
   */
  unsigned char * p = (unsigned char *)(icp->rdi);
  uintptr_t size = icp->rsi;

  /*
   * Verify that the memory is within the secure memory portion of the
   * address space.
   */
  uintptr_t pint = (uintptr_t) p;
  if ((SECMEMSTART <= pint) &&
     (pint < SECMEMEND) &&
     (SECMEMSTART <= (pint + size)) &&
     ((pint + size) < SECMEMEND)) {
    /*
     * Zero out the memory.
     */
    memset (p, 0, size);

    /*
     * Get the physical address before unmapping the page.  We do this because
     * unmapping the page may remove page table pages that are no longer
     * needed for mapping secure pages.
     */
    uintptr_t paddr = getPhysicalAddr (p);

    /*
     * Unmap the memory from the secure memory virtual address space.
     */
    unmapSecurePage (get_pagetable(), p);

    /*
     * Release the memory to the operating system.  Note that we must first
     * get the physical address of the data page as that is what the OS is
     * expecting.
     */
    releaseSVAMemory (paddr, size);
  }

  return;
}
Esempio n. 2
0
/*
 * Function: ghostFree()
 *
 * Description:
 *  Free the physical frames backing ghost memory at the specified virtual
 *  address.  This function frees entire frames and returns the physical memory
 *  to the operating system kernel.
 *
 *  Note that this function may be called upon to unmap ghost memory from a
 *  thread *other* than the one currently running on the CPU.
 *
 * Inputs:
 *  threadp - A pointer to the SVA Thread for which we should release the frame
 *            of secure memory.
 *  p        - A pointer to the virtual address of the ghost memory to free.
 *  size     - The amount of ghost memory in bytes to free.
 *
 */
void
ghostFree (struct SVAThread * threadp, unsigned char * p, intptr_t size) {
  /* Per-CPU data structure maintained by SVA */
  struct CPUState * cpup;

  /* Pointer to thread currently executing on the CPU */
  struct SVAThread * currentThread;

  /*
   * If the amount of memory to free is zero, do nothing.
   */
  if (size == 0) {
    return;
  }

  /*
   * Get a pointer to the thread currently running on the CPU.
   */
  cpup = getCPUState();
  currentThread = cpup->currentThread;

  /*
   * Get the PML4E entry for the Ghost Memory for the thread.
   */
  pml4e_t * secmemPML4Ep = &(threadp->secmemPML4e);

  /*
   * Verify that the memory is within the secure memory portion of the
   * address space.
   */
  uintptr_t pint = (uintptr_t) p;
  if ((SECMEMSTART <= pint) && (pint < SECMEMEND) &&
     (SECMEMSTART <= (pint + size)) && ((pint + size) < SECMEMEND)) {
    /*
     * Loop through each page of the ghost memory until all of the frames
     * have been returned to the operating system kernel.
     */
    for (unsigned char * ptr = p; ptr < (p + size); ptr += X86_PAGE_SIZE) {
      /*
       * Get the physical address before unmapping the page.  We do this
       * because unmapping the page may remove page table pages that are no
       * longer needed for mapping secure pages.
       */
      uintptr_t paddr;
      if (getPhysicalAddrFromPML4E (ptr, secmemPML4Ep, &paddr)) {

        /*
         * Unmap the memory from the secure memory virtual address space.
         */
        unmapSecurePage (threadp, ptr);

        /*
         * Release the memory to the operating system.  Note that we must first
         * get the physical address of the data page as that is what the OS is
         * expecting.
         *
         * TODO:
         *  This code works around a limitation in the releaseSVAMemory()
         *  implementation in which it only releases one page at a time to the
         *  OS.
         */
	if(getPageDescPtr(paddr)->count == 0) {

      	  /*
           * Zero out the contents of the ghost memory if it has been mapped
           * in the current address space.
           */
	  if(threadp == currentThread){
	    unsigned char * dmapAddr = getVirtualSVADMAP (paddr);
            memset (dmapAddr, 0, X86_PAGE_SIZE);

	  }
	  free_frame(paddr);
	}
      }
    }
  }

  return;
}