On 2016-05-22 20:12, Jan Kiszka wrote: > On 2016-05-22 12:21, David Kiarie wrote: >> +static void amdvi_page_walk(AMDVIAddressSpace *as, uint64_t *dte, >> + IOMMUTLBEntry *ret, unsigned perms, >> + hwaddr addr) >> +{ >> + unsigned level, present, pte_perms, oldlevel; >> + uint64_t pte = dte[0], pte_addr, page_mask; >> + >> + /* make sure the DTE has TV = 1 */ >> + if (pte & AMDVI_DEV_TRANSLATION_VALID) { >> + level = get_pte_translation_mode(pte); >> + if (level >= 7) { >> + AMDVI_DPRINTF(MMU, "error: translation level 0x%"PRIu8 " >> detected" >> + " while translating 0x%"PRIx64, level, addr); >> + return; >> + } >> + if (level == 0) { >> + goto no_remap; >> + } >> + >> + /* we are at the leaf page table or page table encodes a huge page >> */ >> + while (level > 0) { >> + pte_perms = amdvi_get_perms(pte); >> + present = pte & 1; >> + if (!present || perms != (perms & pte_perms)) { >> + amdvi_page_fault(as->iommu_state, as->devfn, addr, perms); >> + AMDVI_DPRINTF(CUSTOM, "error: page fault accessing virtual " >> + "addr 0x%"PRIx64, addr); >> + return; >> + } >> + >> + /* go to the next lower level */ >> + pte_addr = pte & AMDVI_DEV_PT_ROOT_MASK; >> + /* add offset and load pte */ >> + pte_addr += ((addr >> (3 + 9 * level)) & 0x1FF) << 3; >> + pte = ldq_phys(&address_space_memory, pte_addr); > > I think this should be address_space_ldq_le. ldq_phys is for usage by > CPUs only (and it breaks the build over master).
Correction: dma_memory_read, and then you need to do the byte-swapping afterwards. Not the dma_memory_read may return an error if the address points to something invalid. You will have to enable this (like a non-present entry). See also the Intel IOMMU code. Jan
signature.asc
Description: OpenPGP digital signature