From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZaiTQ-0002Qv-V2 for qemu-devel@nongnu.org; Sat, 12 Sep 2015 06:56:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZaiTM-0002Uc-0N for qemu-devel@nongnu.org; Sat, 12 Sep 2015 06:56:00 -0400 Received: from mail-la0-x232.google.com ([2a00:1450:4010:c03::232]:33743) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZaiTL-0002UX-Ob for qemu-devel@nongnu.org; Sat, 12 Sep 2015 06:55:55 -0400 Received: by lamp12 with SMTP id p12so60736893lam.0 for ; Sat, 12 Sep 2015 03:55:53 -0700 (PDT) References: <1440458369-7384-1-git-send-email-davidkiarie4@gmail.com> <1440458369-7384-3-git-send-email-davidkiarie4@gmail.com> <55ED871C.8090704@gmail.com> From: Valentine Sinitsyn Message-ID: <55F404B7.2090408@gmail.com> Date: Sat, 12 Sep 2015 15:55:51 +0500 MIME-Version: 1.0 In-Reply-To: <55ED871C.8090704@gmail.com> Content-Type: text/plain; charset=koi8-r; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC 2/4] hw/i386: Introduce AMD IOMMU List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: David Kiarie , qemu-devel@nongnu.org Cc: jan.kiszka@web.de, mst@redhat.com Hi David, On 07.09.2015 17:46, Valentine Sinitsyn wrote: ...snip... >> +/* TODO : Mark addresses as Accessed and Dirty */ >> +static void amd_iommu_do_translate(AMDIOMMUAddressSpace *as, hwaddr >> addr, bool is_write, IOMMUTLBEntry *ret) >> +{ >> + AMDIOMMUState *s = as->iommu_state; >> + >> + int present; >> + dma_addr_t pte_addr; >> + uint64_t entry[4], pte, pte_perms; >> + unsigned level; >> + unsigned perms; >> + >> + if(!amd_iommu_get_dte(s, as->devfn, entry)){ >> + goto no_translation; >> + } >> + >> + pte = entry[0]; >> + >> + /* >> + * It's okay to check for either read or write permissions >> + * even for memory maps, since we don't support R/W maps. >> + */ >> + perms = is_write ? IOMMU_PERM_WRITE : IOMMU_PERM_READ; >> + >> + if(!(level = get_pte_translation_mode(pte))){ >> + goto no_translation; >> + } >> + >> + while(level > 0){ >> + /* >> + * check permissions: the bitwise >> + * implication perms -> entry_perms must be true. Pages must >> be present >> + * and permissions on all levels must be similar >> + */ >> + pte_perms = amd_iommu_get_perms(pte); >> + present = pte & 1; >> + if(!present || perms != (perms & pte_perms)){ >> + amd_iommu_page_fault(s, as->devfn, entry[1] & >> DEV_DOMID_ID_MASK, addr, present, >> + !!(perms & IOMMU_PERM_WRITE)); >> + return; >> + } >> + >> + /* go to the next lower level */ >> + pte_addr = pte & DEV_PT_ROOT_MASK; >> + pte_addr += ((addr >> ( 9 * level)) & 0xff8); > Does this work for six level page tables? The highest level has > different bit size there IIRC. > >> + pte = ldq_phys(&address_space_memory, pte_addr); >> + level = (pte >> DEV_MODE_RSHIFT) & DEV_MODE_MASK; >> + } >> + >> + ret->iova = addr & IOMMU_PAGE_MASK_4K; >> + ret->translated_addr = (pte & DEV_PT_ROOT_MASK) & >> IOMMU_PAGE_MASK_4K; >> + ret->addr_mask = ~IOMMU_PAGE_MASK_4K; >> + ret->perm = IOMMU_RW; >> + return; >> + >> +no_translation: >> + ret->iova = addr; >> + ret->translated_addr = addr & IOMMU_PAGE_MASK_4K; >> + ret->addr_mask = ~IOMMU_PAGE_MASK_4K; >> + ret->perm = IOMMU_RW; >> + return; > Are you sure these transactions needs to be passed through rather than > target-aborted? FYI: They are indeed passed-through; see Table 9 in the spec. Valentine