KVM: Device Assignment: Map mmio pages into VT-d page table
Assigned device could DMA to mmio pages, so also need to map mmio pages into VT-d page table. Signed-off-by: Weidong Han <weidong.han@intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
@@ -36,23 +36,21 @@ int kvm_iommu_map_pages(struct kvm *kvm,
|
|||||||
{
|
{
|
||||||
gfn_t gfn = base_gfn;
|
gfn_t gfn = base_gfn;
|
||||||
pfn_t pfn;
|
pfn_t pfn;
|
||||||
int i, r;
|
int i, r = 0;
|
||||||
struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
|
struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
|
||||||
|
|
||||||
/* check if iommu exists and in use */
|
/* check if iommu exists and in use */
|
||||||
if (!domain)
|
if (!domain)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = -EINVAL;
|
|
||||||
for (i = 0; i < npages; i++) {
|
for (i = 0; i < npages; i++) {
|
||||||
/* check if already mapped */
|
/* check if already mapped */
|
||||||
pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
|
pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
|
||||||
gfn_to_gpa(gfn));
|
gfn_to_gpa(gfn));
|
||||||
if (pfn && !is_mmio_pfn(pfn))
|
if (pfn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pfn = gfn_to_pfn(kvm, gfn);
|
pfn = gfn_to_pfn(kvm, gfn);
|
||||||
if (!is_mmio_pfn(pfn)) {
|
|
||||||
r = intel_iommu_page_mapping(domain,
|
r = intel_iommu_page_mapping(domain,
|
||||||
gfn_to_gpa(gfn),
|
gfn_to_gpa(gfn),
|
||||||
pfn_to_hpa(pfn),
|
pfn_to_hpa(pfn),
|
||||||
@@ -60,15 +58,10 @@ int kvm_iommu_map_pages(struct kvm *kvm,
|
|||||||
DMA_PTE_READ |
|
DMA_PTE_READ |
|
||||||
DMA_PTE_WRITE);
|
DMA_PTE_WRITE);
|
||||||
if (r) {
|
if (r) {
|
||||||
printk(KERN_DEBUG "kvm_iommu_map_pages:"
|
printk(KERN_ERR "kvm_iommu_map_pages:"
|
||||||
"iommu failed to map pfn=%lx\n", pfn);
|
"iommu failed to map pfn=%lx\n", pfn);
|
||||||
goto unmap_pages;
|
goto unmap_pages;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
printk(KERN_DEBUG "kvm_iommu_map_page:"
|
|
||||||
"invalid pfn=%lx\n", pfn);
|
|
||||||
goto unmap_pages;
|
|
||||||
}
|
|
||||||
gfn++;
|
gfn++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -502,8 +502,6 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
|
|||||||
int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
|
int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
|
||||||
gpa_t addr, unsigned long *ret);
|
gpa_t addr, unsigned long *ret);
|
||||||
|
|
||||||
int is_mmio_pfn(pfn_t pfn);
|
|
||||||
|
|
||||||
extern bool tdp_enabled;
|
extern bool tdp_enabled;
|
||||||
|
|
||||||
enum emulation_result {
|
enum emulation_result {
|
||||||
|
@@ -76,7 +76,7 @@ static inline int valid_vcpu(int n)
|
|||||||
return likely(n >= 0 && n < KVM_MAX_VCPUS);
|
return likely(n >= 0 && n < KVM_MAX_VCPUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int is_mmio_pfn(pfn_t pfn)
|
static inline int is_mmio_pfn(pfn_t pfn)
|
||||||
{
|
{
|
||||||
if (pfn_valid(pfn))
|
if (pfn_valid(pfn))
|
||||||
return PageReserved(pfn_to_page(pfn));
|
return PageReserved(pfn_to_page(pfn));
|
||||||
|
Reference in New Issue
Block a user