diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-03-26 08:43:07 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-03-31 09:32:02 -0400 |
commit | 3f4b87b959eab362b89fce6ceb9d1badd102e5ea (patch) | |
tree | 7059d17f1eebcf2f0e4c62e2a9bba6bbc9f34a11 /drivers/iommu/amd_iommu.c | |
parent | a10315e5efb86c689142a7e7927125889f3682e6 (diff) |
iommu/amd: Make use of domain_alloc and domain_free
Implement the new iommu-ops function pointers and remove the
obsolete domain_init and domain_destroy functions.
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 48882c126245..e8c412dcac21 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -126,6 +126,11 @@ static int __init alloc_passthrough_domain(void); | |||
126 | * | 126 | * |
127 | ****************************************************************************/ | 127 | ****************************************************************************/ |
128 | 128 | ||
129 | static struct protection_domain *to_pdomain(struct iommu_domain *dom) | ||
130 | { | ||
131 | return container_of(dom, struct protection_domain, domain); | ||
132 | } | ||
133 | |||
129 | static struct iommu_dev_data *alloc_dev_data(u16 devid) | 134 | static struct iommu_dev_data *alloc_dev_data(u16 devid) |
130 | { | 135 | { |
131 | struct iommu_dev_data *dev_data; | 136 | struct iommu_dev_data *dev_data; |
@@ -3236,42 +3241,45 @@ static int __init alloc_passthrough_domain(void) | |||
3236 | 3241 | ||
3237 | return 0; | 3242 | return 0; |
3238 | } | 3243 | } |
3239 | static int amd_iommu_domain_init(struct iommu_domain *dom) | 3244 | |
3245 | static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) | ||
3240 | { | 3246 | { |
3241 | struct protection_domain *domain; | 3247 | struct protection_domain *pdomain; |
3242 | 3248 | ||
3243 | domain = protection_domain_alloc(); | 3249 | /* We only support unmanaged domains for now */ |
3244 | if (!domain) | 3250 | if (type != IOMMU_DOMAIN_UNMANAGED) |
3245 | goto out_free; | 3251 | return NULL; |
3246 | 3252 | ||
3247 | domain->mode = PAGE_MODE_3_LEVEL; | 3253 | pdomain = protection_domain_alloc(); |
3248 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 3254 | if (!pdomain) |
3249 | if (!domain->pt_root) | ||
3250 | goto out_free; | 3255 | goto out_free; |
3251 | 3256 | ||
3252 | domain->iommu_domain = dom; | 3257 | pdomain->mode = PAGE_MODE_3_LEVEL; |
3253 | 3258 | pdomain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | |
3254 | dom->priv = domain; | 3259 | if (!pdomain->pt_root) |
3260 | goto out_free; | ||
3255 | 3261 | ||
3256 | dom->geometry.aperture_start = 0; | 3262 | pdomain->domain.geometry.aperture_start = 0; |
3257 | dom->geometry.aperture_end = ~0ULL; | 3263 | pdomain->domain.geometry.aperture_end = ~0ULL; |
3258 | dom->geometry.force_aperture = true; | 3264 | pdomain->domain.geometry.force_aperture = true; |
3259 | 3265 | ||
3260 | return 0; | 3266 | return &pdomain->domain; |
3261 | 3267 | ||
3262 | out_free: | 3268 | out_free: |
3263 | protection_domain_free(domain); | 3269 | protection_domain_free(pdomain); |
3264 | 3270 | ||
3265 | return -ENOMEM; | 3271 | return NULL; |
3266 | } | 3272 | } |
3267 | 3273 | ||
3268 | static void amd_iommu_domain_destroy(struct iommu_domain *dom) | 3274 | static void amd_iommu_domain_free(struct iommu_domain *dom) |
3269 | { | 3275 | { |
3270 | struct protection_domain *domain = dom->priv; | 3276 | struct protection_domain *domain; |
3271 | 3277 | ||
3272 | if (!domain) | 3278 | if (!dom) |
3273 | return; | 3279 | return; |
3274 | 3280 | ||
3281 | domain = to_pdomain(dom); | ||
3282 | |||
3275 | if (domain->dev_cnt > 0) | 3283 | if (domain->dev_cnt > 0) |
3276 | cleanup_domain(domain); | 3284 | cleanup_domain(domain); |
3277 | 3285 | ||
@@ -3284,8 +3292,6 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) | |||
3284 | free_gcr3_table(domain); | 3292 | free_gcr3_table(domain); |
3285 | 3293 | ||
3286 | protection_domain_free(domain); | 3294 | protection_domain_free(domain); |
3287 | |||
3288 | dom->priv = NULL; | ||
3289 | } | 3295 | } |
3290 | 3296 | ||
3291 | static void amd_iommu_detach_device(struct iommu_domain *dom, | 3297 | static void amd_iommu_detach_device(struct iommu_domain *dom, |
@@ -3313,7 +3319,7 @@ static void amd_iommu_detach_device(struct iommu_domain *dom, | |||
3313 | static int amd_iommu_attach_device(struct iommu_domain *dom, | 3319 | static int amd_iommu_attach_device(struct iommu_domain *dom, |
3314 | struct device *dev) | 3320 | struct device *dev) |
3315 | { | 3321 | { |
3316 | struct protection_domain *domain = dom->priv; | 3322 | struct protection_domain *domain = to_pdomain(dom); |
3317 | struct iommu_dev_data *dev_data; | 3323 | struct iommu_dev_data *dev_data; |
3318 | struct amd_iommu *iommu; | 3324 | struct amd_iommu *iommu; |
3319 | int ret; | 3325 | int ret; |
@@ -3340,7 +3346,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, | |||
3340 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | 3346 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, |
3341 | phys_addr_t paddr, size_t page_size, int iommu_prot) | 3347 | phys_addr_t paddr, size_t page_size, int iommu_prot) |
3342 | { | 3348 | { |
3343 | struct protection_domain *domain = dom->priv; | 3349 | struct protection_domain *domain = to_pdomain(dom); |
3344 | int prot = 0; | 3350 | int prot = 0; |
3345 | int ret; | 3351 | int ret; |
3346 | 3352 | ||
@@ -3362,7 +3368,7 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | |||
3362 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | 3368 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, |
3363 | size_t page_size) | 3369 | size_t page_size) |
3364 | { | 3370 | { |
3365 | struct protection_domain *domain = dom->priv; | 3371 | struct protection_domain *domain = to_pdomain(dom); |
3366 | size_t unmap_size; | 3372 | size_t unmap_size; |
3367 | 3373 | ||
3368 | if (domain->mode == PAGE_MODE_NONE) | 3374 | if (domain->mode == PAGE_MODE_NONE) |
@@ -3380,7 +3386,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | |||
3380 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | 3386 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, |
3381 | dma_addr_t iova) | 3387 | dma_addr_t iova) |
3382 | { | 3388 | { |
3383 | struct protection_domain *domain = dom->priv; | 3389 | struct protection_domain *domain = to_pdomain(dom); |
3384 | unsigned long offset_mask; | 3390 | unsigned long offset_mask; |
3385 | phys_addr_t paddr; | 3391 | phys_addr_t paddr; |
3386 | u64 *pte, __pte; | 3392 | u64 *pte, __pte; |
@@ -3420,8 +3426,8 @@ static bool amd_iommu_capable(enum iommu_cap cap) | |||
3420 | 3426 | ||
3421 | static const struct iommu_ops amd_iommu_ops = { | 3427 | static const struct iommu_ops amd_iommu_ops = { |
3422 | .capable = amd_iommu_capable, | 3428 | .capable = amd_iommu_capable, |
3423 | .domain_init = amd_iommu_domain_init, | 3429 | .domain_alloc = amd_iommu_domain_alloc, |
3424 | .domain_destroy = amd_iommu_domain_destroy, | 3430 | .domain_free = amd_iommu_domain_free, |
3425 | .attach_dev = amd_iommu_attach_device, | 3431 | .attach_dev = amd_iommu_attach_device, |
3426 | .detach_dev = amd_iommu_detach_device, | 3432 | .detach_dev = amd_iommu_detach_device, |
3427 | .map = amd_iommu_map, | 3433 | .map = amd_iommu_map, |
@@ -3483,7 +3489,7 @@ EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier); | |||
3483 | 3489 | ||
3484 | void amd_iommu_domain_direct_map(struct iommu_domain *dom) | 3490 | void amd_iommu_domain_direct_map(struct iommu_domain *dom) |
3485 | { | 3491 | { |
3486 | struct protection_domain *domain = dom->priv; | 3492 | struct protection_domain *domain = to_pdomain(dom); |
3487 | unsigned long flags; | 3493 | unsigned long flags; |
3488 | 3494 | ||
3489 | spin_lock_irqsave(&domain->lock, flags); | 3495 | spin_lock_irqsave(&domain->lock, flags); |
@@ -3504,7 +3510,7 @@ EXPORT_SYMBOL(amd_iommu_domain_direct_map); | |||
3504 | 3510 | ||
3505 | int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids) | 3511 | int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids) |
3506 | { | 3512 | { |
3507 | struct protection_domain *domain = dom->priv; | 3513 | struct protection_domain *domain = to_pdomain(dom); |
3508 | unsigned long flags; | 3514 | unsigned long flags; |
3509 | int levels, ret; | 3515 | int levels, ret; |
3510 | 3516 | ||
@@ -3616,7 +3622,7 @@ static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid, | |||
3616 | int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, | 3622 | int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, |
3617 | u64 address) | 3623 | u64 address) |
3618 | { | 3624 | { |
3619 | struct protection_domain *domain = dom->priv; | 3625 | struct protection_domain *domain = to_pdomain(dom); |
3620 | unsigned long flags; | 3626 | unsigned long flags; |
3621 | int ret; | 3627 | int ret; |
3622 | 3628 | ||
@@ -3638,7 +3644,7 @@ static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid) | |||
3638 | 3644 | ||
3639 | int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid) | 3645 | int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid) |
3640 | { | 3646 | { |
3641 | struct protection_domain *domain = dom->priv; | 3647 | struct protection_domain *domain = to_pdomain(dom); |
3642 | unsigned long flags; | 3648 | unsigned long flags; |
3643 | int ret; | 3649 | int ret; |
3644 | 3650 | ||
@@ -3718,7 +3724,7 @@ static int __clear_gcr3(struct protection_domain *domain, int pasid) | |||
3718 | int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, | 3724 | int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, |
3719 | unsigned long cr3) | 3725 | unsigned long cr3) |
3720 | { | 3726 | { |
3721 | struct protection_domain *domain = dom->priv; | 3727 | struct protection_domain *domain = to_pdomain(dom); |
3722 | unsigned long flags; | 3728 | unsigned long flags; |
3723 | int ret; | 3729 | int ret; |
3724 | 3730 | ||
@@ -3732,7 +3738,7 @@ EXPORT_SYMBOL(amd_iommu_domain_set_gcr3); | |||
3732 | 3738 | ||
3733 | int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) | 3739 | int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) |
3734 | { | 3740 | { |
3735 | struct protection_domain *domain = dom->priv; | 3741 | struct protection_domain *domain = to_pdomain(dom); |
3736 | unsigned long flags; | 3742 | unsigned long flags; |
3737 | int ret; | 3743 | int ret; |
3738 | 3744 | ||
@@ -3765,17 +3771,17 @@ EXPORT_SYMBOL(amd_iommu_complete_ppr); | |||
3765 | 3771 | ||
3766 | struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev) | 3772 | struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev) |
3767 | { | 3773 | { |
3768 | struct protection_domain *domain; | 3774 | struct protection_domain *pdomain; |
3769 | 3775 | ||
3770 | domain = get_domain(&pdev->dev); | 3776 | pdomain = get_domain(&pdev->dev); |
3771 | if (IS_ERR(domain)) | 3777 | if (IS_ERR(pdomain)) |
3772 | return NULL; | 3778 | return NULL; |
3773 | 3779 | ||
3774 | /* Only return IOMMUv2 domains */ | 3780 | /* Only return IOMMUv2 domains */ |
3775 | if (!(domain->flags & PD_IOMMUV2_MASK)) | 3781 | if (!(pdomain->flags & PD_IOMMUV2_MASK)) |
3776 | return NULL; | 3782 | return NULL; |
3777 | 3783 | ||
3778 | return domain->iommu_domain; | 3784 | return &pdomain->domain; |
3779 | } | 3785 | } |
3780 | EXPORT_SYMBOL(amd_iommu_get_v2_domain); | 3786 | EXPORT_SYMBOL(amd_iommu_get_v2_domain); |
3781 | 3787 | ||