Skip to content

Commit 8c47ce3

Browse files
ankita-nvoupton
authored andcommitted
KVM: arm64: Set io memory s2 pte as normalnc for vfio pci device
To provide VM with the ability to get device IO memory with NormalNC property, map device MMIO in KVM for ARM64 at stage2 as NormalNC. Having NormalNC S2 default puts guests in control (based on [1], "Combining stage 1 and stage 2 memory type attributes") of device MMIO regions memory mappings. The rules are summarized below: ([(S1) - stage1], [(S2) - stage 2]) S1 | S2 | Result NORMAL-WB | NORMAL-NC | NORMAL-NC NORMAL-WT | NORMAL-NC | NORMAL-NC NORMAL-NC | NORMAL-NC | NORMAL-NC DEVICE<attr> | NORMAL-NC | DEVICE<attr> Still this cannot be generalized to non PCI devices such as GICv2. There is insufficient information and uncertainity in the behavior of non PCI driver. A driver must indicate support using the new flag VM_ALLOW_ANY_UNCACHED. Adapt KVM to make use of the flag VM_ALLOW_ANY_UNCACHED as indicator to activate the S2 setting to NormalNc. [1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf Suggested-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Ankit Agrawal <ankita@nvidia.com> Link: https://lore.kernel.org/r/20240224150546.368-4-ankita@nvidia.com Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent 5c656fc commit 8c47ce3

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

arch/arm64/kvm/mmu.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
13811381
int ret = 0;
13821382
bool write_fault, writable, force_pte = false;
13831383
bool exec_fault, mte_allowed;
1384-
bool device = false;
1384+
bool device = false, vfio_allow_any_uc = false;
13851385
unsigned long mmu_seq;
13861386
struct kvm *kvm = vcpu->kvm;
13871387
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
14721472
gfn = fault_ipa >> PAGE_SHIFT;
14731473
mte_allowed = kvm_vma_mte_allowed(vma);
14741474

1475+
vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
1476+
14751477
/* Don't use the VMA after the unlock -- it may have vanished */
14761478
vma = NULL;
14771479

@@ -1557,10 +1559,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
15571559
if (exec_fault)
15581560
prot |= KVM_PGTABLE_PROT_X;
15591561

1560-
if (device)
1561-
prot |= KVM_PGTABLE_PROT_DEVICE;
1562-
else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
1562+
if (device) {
1563+
if (vfio_allow_any_uc)
1564+
prot |= KVM_PGTABLE_PROT_NORMAL_NC;
1565+
else
1566+
prot |= KVM_PGTABLE_PROT_DEVICE;
1567+
} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
15631568
prot |= KVM_PGTABLE_PROT_X;
1569+
}
15641570

15651571
/*
15661572
* Under the premise of getting a FSC_PERM fault, we just need to relax

0 commit comments

Comments
 (0)