mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	Ran update_kernel.sh in a fresh clone without any existing toolchains. Manually rebased: bcm27xx/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch layerscape/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch Build system: x86_64 Build-tested: ipq806x/R7800 Run-tested: ipq806x/R7800 No dmesg regressions, everything functional Signed-off-by: John Audia <graysky@archlinux.us> [remove accidental whitespace edit] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From d637252f72998261c9d77c0be57317c73ad77f83 Mon Sep 17 00:00:00 2001
 | |
| From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
 | |
| Date: Tue, 26 Jul 2016 16:38:18 +0300
 | |
| Subject: [PATCH] arm/arm64: KVM: drop qman mmio cacheable mapping hack
 | |
| 
 | |
| Instead of hardcoding checks for qman cacheable
 | |
| mmio region physical addresses extract mapping
 | |
| information from the user-space mapping.
 | |
| The involves several steps;
 | |
|  - get access to a pte part of the user-space mapping
 | |
|    by using get_locked_pte() / pte_unmap_unlock() apis
 | |
|  - extract memtype (normal / device), shareability from
 | |
|    the pte
 | |
|  - convert to S2 translation bits in newly added
 | |
|    function stage1_to_stage2_pgprot()
 | |
|  - finish making the s2 translation with the obtained bits
 | |
| 
 | |
| Another explored option was using vm_area_struct::vm_page_prot
 | |
| which is set in vfio-mc mmap code to the correct page bits.
 | |
| However, experiments show that these bits are later altered
 | |
| in the generic mmap code (e.g. the shareability bit is always
 | |
| set on arm64).
 | |
| The only place where the original bits can still be found
 | |
| is the user-space mapping, using the method described above.
 | |
| 
 | |
| Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
 | |
| [Bharat - Fixed mem_type check issue]
 | |
| [changed "ifdef ARM64" to CONFIG_ARM64]
 | |
| Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
 | |
| [Ioana - added a sanity check for hugepages]
 | |
| Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
 | |
| [Fixed format issues]
 | |
| Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
 | |
| ---
 | |
|  virt/kvm/arm/mmu.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 | |
|  1 file changed, 53 insertions(+), 2 deletions(-)
 | |
| 
 | |
| --- a/virt/kvm/arm/mmu.c
 | |
| +++ b/virt/kvm/arm/mmu.c
 | |
| @@ -1381,6 +1381,30 @@ out:
 | |
|  	return ret;
 | |
|  }
 | |
|  
 | |
| +#ifdef CONFIG_ARM64
 | |
| +static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
 | |
| +{
 | |
| +	switch (pgprot_val(prot) & PTE_ATTRINDX_MASK) {
 | |
| +	case PTE_ATTRINDX(MT_DEVICE_nGnRE):
 | |
| +	case PTE_ATTRINDX(MT_DEVICE_nGnRnE):
 | |
| +	case PTE_ATTRINDX(MT_DEVICE_GRE):
 | |
| +		return PAGE_S2_DEVICE;
 | |
| +	case PTE_ATTRINDX(MT_NORMAL_NC):
 | |
| +	case PTE_ATTRINDX(MT_NORMAL):
 | |
| +		return (pgprot_val(prot) & PTE_SHARED)
 | |
| +			? PAGE_S2
 | |
| +			: PAGE_S2_NS;
 | |
| +	}
 | |
| +
 | |
| +	return PAGE_S2_DEVICE;
 | |
| +}
 | |
| +#else
 | |
| +static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
 | |
| +{
 | |
| +	return PAGE_S2_DEVICE;
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
 | |
|  {
 | |
|  	kvm_pfn_t pfn = *pfnp;
 | |
| @@ -1725,8 +1749,23 @@ static int user_mem_abort(struct kvm_vcp
 | |
|  	 * 3 levels, i.e, PMD is not folded.
 | |
|  	 */
 | |
|  	if (vma_pagesize == PMD_SIZE ||
 | |
| -	    (vma_pagesize == PUD_SIZE && kvm_stage2_has_pmd(kvm)))
 | |
| +	    (vma_pagesize == PUD_SIZE && kvm_stage2_has_pmd(kvm))) {
 | |
|  		gfn = (fault_ipa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT;
 | |
| +	} else {
 | |
| +		if (!is_vm_hugetlb_page(vma)) {
 | |
| +			pte_t *pte;
 | |
| +			spinlock_t *ptl;
 | |
| +			pgprot_t prot;
 | |
| +
 | |
| +			pte = get_locked_pte(current->mm, memslot->userspace_addr, &ptl);
 | |
| +			prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
 | |
| +			pte_unmap_unlock(pte, ptl);
 | |
| +#ifdef CONFIG_ARM64
 | |
| +			if (pgprot_val(prot) == pgprot_val(PAGE_S2_NS))
 | |
| +				mem_type = PAGE_S2_NS;
 | |
| +#endif
 | |
| +		}
 | |
| +	}
 | |
|  	up_read(¤t->mm->mmap_sem);
 | |
|  
 | |
|  	/* We need minimum second+third level pages */
 | |
| @@ -1755,6 +1794,11 @@ static int user_mem_abort(struct kvm_vcp
 | |
|  	if (is_error_noslot_pfn(pfn))
 | |
|  		return -EFAULT;
 | |
|  
 | |
| +#ifdef CONFIG_ARM64
 | |
| +	if (pgprot_val(mem_type) == pgprot_val(PAGE_S2_NS)) {
 | |
| +		flags |= KVM_S2PTE_FLAG_IS_IOMAP;
 | |
| +	} else
 | |
| +#endif
 | |
|  	if (kvm_is_device_pfn(pfn)) {
 | |
|  		mem_type = PAGE_S2_DEVICE;
 | |
|  		flags |= KVM_S2PTE_FLAG_IS_IOMAP;
 | |
| @@ -2351,6 +2395,9 @@ int kvm_arch_prepare_memory_region(struc
 | |
|  			gpa_t gpa = mem->guest_phys_addr +
 | |
|  				    (vm_start - mem->userspace_addr);
 | |
|  			phys_addr_t pa;
 | |
| +			pgprot_t prot;
 | |
| +			pte_t *pte;
 | |
| +			spinlock_t *ptl;
 | |
|  
 | |
|  			pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
 | |
|  			pa += vm_start - vma->vm_start;
 | |
| @@ -2361,9 +2408,13 @@ int kvm_arch_prepare_memory_region(struc
 | |
|  				goto out;
 | |
|  			}
 | |
|  
 | |
| +			pte = get_locked_pte(current->mm, mem->userspace_addr, &ptl);
 | |
| +			prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
 | |
| +			pte_unmap_unlock(pte, ptl);
 | |
| +
 | |
|  			ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
 | |
|  						    vm_end - vm_start,
 | |
| -						    writable, PAGE_S2_DEVICE);
 | |
| +						    writable, prot);
 | |
|  			if (ret)
 | |
|  				break;
 | |
|  		}
 |