* [PATCH 1/5] vfio/iommu_type1: support for platform bus devices on ARM
[not found] <1413205748-6300-1-git-send-email-a.motakis@virtualopensystems.com>
@ 2014-10-13 13:09 ` Antonios Motakis
2014-10-13 13:09 ` [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
` (3 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-13 13:09 UTC (permalink / raw)
To: kvmarm, iommu, alex.williamson
Cc: will.deacon, tech, christoffer.dall, eric.auger, kim.phillips,
marc.zyngier, Antonios Motakis, open list:VFIO DRIVER, open list
This allows to make use of the VFIO_IOMMU_TYPE1 driver with platform
devices on ARM. The driver can then be used with an Exynos SMMU, or
ARM SMMU driver.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
drivers/vfio/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index d8c5763..a0abe04 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -16,7 +16,7 @@ config VFIO_SPAPR_EEH
menuconfig VFIO
tristate "VFIO Non-Privileged userspace driver framework"
depends on IOMMU_API
- select VFIO_IOMMU_TYPE1 if X86
+ select VFIO_IOMMU_TYPE1 if X86 || ARM
select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES)
select ANON_INODES
--
2.1.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
[not found] <1413205748-6300-1-git-send-email-a.motakis@virtualopensystems.com>
2014-10-13 13:09 ` [PATCH 1/5] vfio/iommu_type1: support for platform bus devices on ARM Antonios Motakis
@ 2014-10-13 13:09 ` Antonios Motakis
2014-10-20 21:29 ` Alex Williamson
2014-10-20 21:37 ` Andy Lutomirski
2014-10-13 13:09 ` [PATCH 3/5] vfio: type1: replace domain wide protection flags with supported capabilities Antonios Motakis
` (2 subsequent siblings)
4 siblings, 2 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-13 13:09 UTC (permalink / raw)
To: kvmarm, iommu, alex.williamson
Cc: will.deacon, tech, christoffer.dall, eric.auger, kim.phillips,
marc.zyngier, Antonios Motakis, open list:VFIO DRIVER,
open list:ABI/API, open list
We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
This way the user can control whether the XN flag will be set on the
requested mappings. The IOMMU_NOEXEC flag needs to be available for all
the IOMMUs of the container used.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
include/uapi/linux/vfio.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 6612974..111b5e8 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -29,6 +29,7 @@
* capability is subject to change as groups are added or removed.
*/
#define VFIO_DMA_CC_IOMMU 4
+#define VFIO_DMA_NOEXEC_IOMMU 5
/* Check if EEH is supported */
#define VFIO_EEH 5
@@ -401,6 +402,7 @@ struct vfio_iommu_type1_dma_map {
__u32 flags;
#define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
#define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
+#define VFIO_DMA_MAP_FLAG_NOEXEC (1 << 2) /* not executable from device */
__u64 vaddr; /* Process virtual address */
__u64 iova; /* IO virtual address */
__u64 size; /* Size of mapping (bytes) */
--
2.1.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-13 13:09 ` [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
@ 2014-10-20 21:29 ` Alex Williamson
2014-10-21 12:17 ` Antonios Motakis
2014-10-20 21:37 ` Andy Lutomirski
1 sibling, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2014-10-20 21:29 UTC (permalink / raw)
To: Antonios Motakis
Cc: kvmarm, iommu, will.deacon, tech, christoffer.dall, eric.auger,
kim.phillips, marc.zyngier, open list:VFIO DRIVER,
open list:ABI/API, open list
On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
> This way the user can control whether the XN flag will be set on the
> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
> the IOMMUs of the container used.
>
> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
> ---
> include/uapi/linux/vfio.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 6612974..111b5e8 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -29,6 +29,7 @@
> * capability is subject to change as groups are added or removed.
> */
> #define VFIO_DMA_CC_IOMMU 4
> +#define VFIO_DMA_NOEXEC_IOMMU 5
>
> /* Check if EEH is supported */
> #define VFIO_EEH 5
^^
5 is still already used. Feel free to convert to enum so we stop making
this mistake.
> @@ -401,6 +402,7 @@ struct vfio_iommu_type1_dma_map {
> __u32 flags;
> #define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
> #define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
> +#define VFIO_DMA_MAP_FLAG_NOEXEC (1 << 2) /* not executable from device */
> __u64 vaddr; /* Process virtual address */
> __u64 iova; /* IO virtual address */
> __u64 size; /* Size of mapping (bytes) */
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-20 21:29 ` Alex Williamson
@ 2014-10-21 12:17 ` Antonios Motakis
0 siblings, 0 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-21 12:17 UTC (permalink / raw)
To: Alex Williamson
Cc: kvm-arm, Linux IOMMU, Will Deacon,
VirtualOpenSystems Technical Team, Christoffer Dall, Eric Auger,
Kim Phillips, Marc Zyngier, open list:VFIO DRIVER,
open list:ABI/API, open list
On Mon, Oct 20, 2014 at 11:29 PM, Alex Williamson
<alex.williamson@redhat.com> wrote:
> On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
>> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
>> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
>> This way the user can control whether the XN flag will be set on the
>> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
>> the IOMMUs of the container used.
>>
>> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
>> ---
>> include/uapi/linux/vfio.h | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>> index 6612974..111b5e8 100644
>> --- a/include/uapi/linux/vfio.h
>> +++ b/include/uapi/linux/vfio.h
>> @@ -29,6 +29,7 @@
>> * capability is subject to change as groups are added or removed.
>> */
>> #define VFIO_DMA_CC_IOMMU 4
>> +#define VFIO_DMA_NOEXEC_IOMMU 5
>>
>> /* Check if EEH is supported */
>> #define VFIO_EEH 5
> ^^
> 5 is still already used. Feel free to convert to enum so we stop making
> this mistake.
Oops :) will do.
>
>> @@ -401,6 +402,7 @@ struct vfio_iommu_type1_dma_map {
>> __u32 flags;
>> #define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
>> #define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
>> +#define VFIO_DMA_MAP_FLAG_NOEXEC (1 << 2) /* not executable from device */
>> __u64 vaddr; /* Process virtual address */
>> __u64 iova; /* IO virtual address */
>> __u64 size; /* Size of mapping (bytes) */
>
>
>
--
Antonios Motakis
Virtual Open Systems
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-13 13:09 ` [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
2014-10-20 21:29 ` Alex Williamson
@ 2014-10-20 21:37 ` Andy Lutomirski
2014-10-21 12:23 ` Antonios Motakis
1 sibling, 1 reply; 14+ messages in thread
From: Andy Lutomirski @ 2014-10-20 21:37 UTC (permalink / raw)
To: Antonios Motakis
Cc: kvmarm, iommu, Alex Williamson, Will Deacon, tech,
christoffer.dall, eric.auger, kim.phillips, marc.zyngier,
open list:VFIO DRIVER, open list:ABI/API, open list
On Mon, Oct 13, 2014 at 6:09 AM, Antonios Motakis
<a.motakis@virtualopensystems.com> wrote:
> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
> This way the user can control whether the XN flag will be set on the
> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
> the IOMMUs of the container used.
Since you sent this to the linux-api list, I'll bite: what's the XN
flag? I know what PROT_EXEC does when you mmap something, and I
presume that vfio is mmappable, but I don't actually have any clue
what this patch does.
I assume that this does not have anything to do with a non-CPU DMA
master executing code in main memory, because that makes rather little
sense. (Or maybe it really does, in which case: weird.)
--Andy
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-20 21:37 ` Andy Lutomirski
@ 2014-10-21 12:23 ` Antonios Motakis
0 siblings, 0 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-21 12:23 UTC (permalink / raw)
To: Andy Lutomirski
Cc: kvm-arm, Linux IOMMU, Alex Williamson, Will Deacon,
VirtualOpenSystems Technical Team, Christoffer Dall, Eric Auger,
Kim Phillips, Marc Zyngier, open list:VFIO DRIVER,
open list:ABI/API, open list
On Mon, Oct 20, 2014 at 11:37 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Mon, Oct 13, 2014 at 6:09 AM, Antonios Motakis
> <a.motakis@virtualopensystems.com> wrote:
>> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
>> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
>> This way the user can control whether the XN flag will be set on the
>> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
>> the IOMMUs of the container used.
>
> Since you sent this to the linux-api list, I'll bite: what's the XN
> flag? I know what PROT_EXEC does when you mmap something, and I
> presume that vfio is mmappable, but I don't actually have any clue
> what this patch does.
>
> I assume that this does not have anything to do with a non-CPU DMA
> master executing code in main memory, because that makes rather little
> sense. (Or maybe it really does, in which case: weird.)
It does actually. For example, the ARM PL330 DMA controller will fetch
from memory code with DMA instructions, and it will respect this flag.
It is not code that can be executed on the CPU of course, but it is
executable on the DMAC.
>
> --Andy
--
Antonios Motakis
Virtual Open Systems
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/5] vfio: type1: replace domain wide protection flags with supported capabilities
[not found] <1413205748-6300-1-git-send-email-a.motakis@virtualopensystems.com>
2014-10-13 13:09 ` [PATCH 1/5] vfio/iommu_type1: support for platform bus devices on ARM Antonios Motakis
2014-10-13 13:09 ` [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
@ 2014-10-13 13:09 ` Antonios Motakis
[not found] ` <5447742A.8070705@linaro.org>
2014-10-13 13:09 ` [PATCH 4/5] vfio: type1: replace vfio_domains_have_iommu_cache with generic function Antonios Motakis
2014-10-13 13:09 ` [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
4 siblings, 1 reply; 14+ messages in thread
From: Antonios Motakis @ 2014-10-13 13:09 UTC (permalink / raw)
To: kvmarm, iommu, alex.williamson
Cc: will.deacon, tech, christoffer.dall, eric.auger, kim.phillips,
marc.zyngier, Antonios Motakis, open list:VFIO DRIVER, open list
VFIO_IOMMU_TYPE1 keeps track for each domain it knows a list of protection
flags it always applies to all mappings in the domain. This is used for
domains that support IOMMU_CAP_CACHE_COHERENCY.
Refactor this slightly, by keeping track instead that a given domain
supports the capability, and applying the IOMMU_CACHE protection flag when
doing the actual DMA mappings.
This will allow us to reuse the behavior for IOMMU_CAP_NOEXEC, which we
also want to keep track of, but without applying it to all domains that
support it unless the user explicitly requests it.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
drivers/vfio/vfio_iommu_type1.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 562f686..62a8b4d 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -64,7 +64,7 @@ struct vfio_domain {
struct iommu_domain *domain;
struct list_head next;
struct list_head group_list;
- int prot; /* IOMMU_CACHE */
+ int caps;
};
struct vfio_dma {
@@ -485,7 +485,7 @@ static int map_try_harder(struct vfio_domain *domain, dma_addr_t iova,
for (i = 0; i < npage; i++, pfn++, iova += PAGE_SIZE) {
ret = iommu_map(domain->domain, iova,
(phys_addr_t)pfn << PAGE_SHIFT,
- PAGE_SIZE, prot | domain->prot);
+ PAGE_SIZE, prot);
if (ret)
break;
}
@@ -503,11 +503,16 @@ static int vfio_iommu_map(struct vfio_iommu *iommu, dma_addr_t iova,
int ret;
list_for_each_entry(d, &iommu->domain_list, next) {
+ int dprot = prot;
+
+ if (d->caps | IOMMU_CAP_CACHE_COHERENCY)
+ dprot |= IOMMU_CACHE;
+
ret = iommu_map(d->domain, iova, (phys_addr_t)pfn << PAGE_SHIFT,
- npage << PAGE_SHIFT, prot | d->prot);
+ npage << PAGE_SHIFT, dprot);
if (ret) {
if (ret != -EBUSY ||
- map_try_harder(d, iova, pfn, npage, prot))
+ map_try_harder(d, iova, pfn, npage, dprot))
goto unwind;
}
}
@@ -620,6 +625,10 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
struct vfio_domain *d;
struct rb_node *n;
int ret;
+ int dprot = 0;
+
+ if (domain->caps | IOMMU_CAP_CACHE_COHERENCY)
+ dprot |= IOMMU_CACHE;
/* Arbitrarily pick the first domain in the list for lookups */
d = list_first_entry(&iommu->domain_list, struct vfio_domain, next);
@@ -653,7 +662,7 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
size += PAGE_SIZE;
ret = iommu_map(domain->domain, iova, phys,
- size, dma->prot | domain->prot);
+ size, dma->prot | dprot);
if (ret)
return ret;
@@ -721,7 +730,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
}
if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
- domain->prot |= IOMMU_CACHE;
+ domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
/*
* Try to match an existing compatible domain. We don't want to
@@ -732,7 +741,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
*/
list_for_each_entry(d, &iommu->domain_list, next) {
if (d->domain->ops == domain->domain->ops &&
- d->prot == domain->prot) {
+ d->caps == domain->caps) {
iommu_detach_group(domain->domain, iommu_group);
if (!iommu_attach_group(d->domain, iommu_group)) {
list_add(&group->next, &d->group_list);
@@ -865,7 +874,7 @@ static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu)
mutex_lock(&iommu->lock);
list_for_each_entry(domain, &iommu->domain_list, next) {
- if (!(domain->prot & IOMMU_CACHE)) {
+ if (!(domain->caps & IOMMU_CAP_CACHE_COHERENCY)) {
ret = 0;
break;
}
--
2.1.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/5] vfio: type1: replace vfio_domains_have_iommu_cache with generic function
[not found] <1413205748-6300-1-git-send-email-a.motakis@virtualopensystems.com>
` (2 preceding siblings ...)
2014-10-13 13:09 ` [PATCH 3/5] vfio: type1: replace domain wide protection flags with supported capabilities Antonios Motakis
@ 2014-10-13 13:09 ` Antonios Motakis
2014-10-13 13:09 ` [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
4 siblings, 0 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-13 13:09 UTC (permalink / raw)
To: kvmarm, iommu, alex.williamson
Cc: will.deacon, tech, christoffer.dall, eric.auger, kim.phillips,
marc.zyngier, Antonios Motakis, open list:VFIO DRIVER, open list
Replace the function vfio_domains_have_iommu_cache() with a more generic
function vfio_domains_have_iommu_cap() which allows to check all domains
of an vfio_iommu structure for a given cached capability.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
drivers/vfio/vfio_iommu_type1.c | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 62a8b4d..8b4202a 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -80,6 +80,23 @@ struct vfio_group {
struct list_head next;
};
+static int vfio_domains_have_iommu_cap(struct vfio_iommu *iommu, int cap)
+{
+ struct vfio_domain *domain;
+ int ret = 1;
+
+ mutex_lock(&iommu->lock);
+ list_for_each_entry(domain, &iommu->domain_list, next) {
+ if (!(domain->caps & cap)) {
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&iommu->lock);
+
+ return ret;
+}
+
/*
* This code handles mapping and unmapping of user data buffers
* into DMA'ble space using the IOMMU
@@ -867,23 +884,6 @@ static void vfio_iommu_type1_release(void *iommu_data)
kfree(iommu);
}
-static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu)
-{
- struct vfio_domain *domain;
- int ret = 1;
-
- mutex_lock(&iommu->lock);
- list_for_each_entry(domain, &iommu->domain_list, next) {
- if (!(domain->caps & IOMMU_CAP_CACHE_COHERENCY)) {
- ret = 0;
- break;
- }
- }
- mutex_unlock(&iommu->lock);
-
- return ret;
-}
-
static long vfio_iommu_type1_ioctl(void *iommu_data,
unsigned int cmd, unsigned long arg)
{
@@ -898,7 +898,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
case VFIO_DMA_CC_IOMMU:
if (!iommu)
return 0;
- return vfio_domains_have_iommu_cache(iommu);
+ return vfio_domains_have_iommu_cap(iommu,
+ IOMMU_CAP_CACHE_COHERENCY);
default:
return 0;
}
--
2.1.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag
[not found] <1413205748-6300-1-git-send-email-a.motakis@virtualopensystems.com>
` (3 preceding siblings ...)
2014-10-13 13:09 ` [PATCH 4/5] vfio: type1: replace vfio_domains_have_iommu_cache with generic function Antonios Motakis
@ 2014-10-13 13:09 ` Antonios Motakis
2014-10-20 21:13 ` Alex Williamson
4 siblings, 1 reply; 14+ messages in thread
From: Antonios Motakis @ 2014-10-13 13:09 UTC (permalink / raw)
To: kvmarm, iommu, alex.williamson
Cc: will.deacon, tech, christoffer.dall, eric.auger, kim.phillips,
marc.zyngier, Antonios Motakis, open list:VFIO DRIVER, open list
Some IOMMU drivers, such as the ARM SMMU driver, make available the
IOMMU_NOEXEC flag, to set the page tables for a device as XN (execute never).
This affects devices such as the ARM PL330 DMA Controller, which respects
this flag and will refuse to fetch DMA instructions from memory where the
XN flag has been set.
The flag can be used only if all IOMMU domains behind the container support
the IOMMU_NOEXEC flag. Also, if any mappings are created with the flag, any
new domains with devices will have to support it as well.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
drivers/vfio/vfio_iommu_type1.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 8b4202a..e225e8f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -569,6 +569,12 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
if (map->flags & VFIO_DMA_MAP_FLAG_READ)
prot |= IOMMU_READ;
+ if (map->flags & VFIO_DMA_MAP_FLAG_NOEXEC) {
+ if (!vfio_domains_have_iommu_cap(iommu, IOMMU_CAP_NOEXEC))
+ return -EINVAL;
+ prot |= IOMMU_NOEXEC;
+ }
+
if (!prot || !size || (size | iova | vaddr) & mask)
return -EINVAL;
@@ -662,6 +668,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
dma = rb_entry(n, struct vfio_dma, node);
iova = dma->iova;
+ /*
+ * if any of the mappings to be replayed has the NOEXEC flag
+ * set, then the new iommu domain must support it
+ */
+ if ((dma->prot | IOMMU_NOEXEC) &&
+ !(domain->caps & IOMMU_CAP_NOEXEC))
+ return -EINVAL;
+
while (iova < dma->iova + dma->size) {
phys_addr_t phys = iommu_iova_to_phys(d->domain, iova);
size_t size;
@@ -749,6 +763,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
+ if (iommu_capable(bus, IOMMU_CAP_NOEXEC))
+ domain->caps |= IOMMU_CAP_NOEXEC;
+
/*
* Try to match an existing compatible domain. We don't want to
* preclude an IOMMU driver supporting multiple bus_types and being
@@ -900,6 +917,11 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
return 0;
return vfio_domains_have_iommu_cap(iommu,
IOMMU_CAP_CACHE_COHERENCY);
+ case VFIO_DMA_NOEXEC_IOMMU:
+ if (!iommu)
+ return 0;
+ return vfio_domains_have_iommu_cap(iommu,
+ IOMMU_CAP_NOEXEC);
default:
return 0;
}
@@ -923,7 +945,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
} else if (cmd == VFIO_IOMMU_MAP_DMA) {
struct vfio_iommu_type1_dma_map map;
uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
- VFIO_DMA_MAP_FLAG_WRITE;
+ VFIO_DMA_MAP_FLAG_WRITE |
+ VFIO_DMA_MAP_FLAG_NOEXEC;
minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
--
2.1.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-13 13:09 ` [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag Antonios Motakis
@ 2014-10-20 21:13 ` Alex Williamson
2014-10-21 12:40 ` Antonios Motakis
0 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2014-10-20 21:13 UTC (permalink / raw)
To: Antonios Motakis
Cc: kvmarm, iommu, will.deacon, tech, christoffer.dall, eric.auger,
kim.phillips, marc.zyngier, open list:VFIO DRIVER, open list
On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
> Some IOMMU drivers, such as the ARM SMMU driver, make available the
> IOMMU_NOEXEC flag, to set the page tables for a device as XN (execute never).
> This affects devices such as the ARM PL330 DMA Controller, which respects
> this flag and will refuse to fetch DMA instructions from memory where the
> XN flag has been set.
>
> The flag can be used only if all IOMMU domains behind the container support
> the IOMMU_NOEXEC flag. Also, if any mappings are created with the flag, any
> new domains with devices will have to support it as well.
>
> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
> ---
> drivers/vfio/vfio_iommu_type1.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 8b4202a..e225e8f 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -569,6 +569,12 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
> if (map->flags & VFIO_DMA_MAP_FLAG_READ)
> prot |= IOMMU_READ;
>
> + if (map->flags & VFIO_DMA_MAP_FLAG_NOEXEC) {
> + if (!vfio_domains_have_iommu_cap(iommu, IOMMU_CAP_NOEXEC))
> + return -EINVAL;
> + prot |= IOMMU_NOEXEC;
> + }
> +
> if (!prot || !size || (size | iova | vaddr) & mask)
> return -EINVAL;
I think this test needs to move above adding the NOEXEC flag, otherwise
we now allow mappings without read or write, which is an ABI change.
>
> @@ -662,6 +668,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
> dma = rb_entry(n, struct vfio_dma, node);
> iova = dma->iova;
>
> + /*
> + * if any of the mappings to be replayed has the NOEXEC flag
> + * set, then the new iommu domain must support it
> + */
> + if ((dma->prot | IOMMU_NOEXEC) &&
I think you mean
& IOMMU_NOEXEC
> + !(domain->caps & IOMMU_CAP_NOEXEC))
> + return -EINVAL;
> +
In patch 2/5 you stated:
The IOMMU_NOEXEC flag needs to be available for all the IOMMUs
of the container used.
But here you'll create heterogeneous containers so long as there are no
NOEXEC mappings. Is that intentional or a side effect of the above
masking bug?
> while (iova < dma->iova + dma->size) {
> phys_addr_t phys = iommu_iova_to_phys(d->domain, iova);
> size_t size;
> @@ -749,6 +763,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
> domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
>
> + if (iommu_capable(bus, IOMMU_CAP_NOEXEC))
> + domain->caps |= IOMMU_CAP_NOEXEC;
> +
> /*
> * Try to match an existing compatible domain. We don't want to
> * preclude an IOMMU driver supporting multiple bus_types and being
> @@ -900,6 +917,11 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
> return 0;
> return vfio_domains_have_iommu_cap(iommu,
> IOMMU_CAP_CACHE_COHERENCY);
> + case VFIO_DMA_NOEXEC_IOMMU:
> + if (!iommu)
> + return 0;
> + return vfio_domains_have_iommu_cap(iommu,
> + IOMMU_CAP_NOEXEC);
> default:
> return 0;
> }
> @@ -923,7 +945,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
> } else if (cmd == VFIO_IOMMU_MAP_DMA) {
> struct vfio_iommu_type1_dma_map map;
> uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
> - VFIO_DMA_MAP_FLAG_WRITE;
> + VFIO_DMA_MAP_FLAG_WRITE |
> + VFIO_DMA_MAP_FLAG_NOEXEC;
>
> minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-20 21:13 ` Alex Williamson
@ 2014-10-21 12:40 ` Antonios Motakis
2014-10-21 14:37 ` Alex Williamson
0 siblings, 1 reply; 14+ messages in thread
From: Antonios Motakis @ 2014-10-21 12:40 UTC (permalink / raw)
To: Alex Williamson
Cc: kvm-arm, Linux IOMMU, Will Deacon,
VirtualOpenSystems Technical Team, Christoffer Dall, Eric Auger,
Kim Phillips, Marc Zyngier, open list:VFIO DRIVER, open list
On Mon, Oct 20, 2014 at 11:13 PM, Alex Williamson
<alex.williamson@redhat.com> wrote:
> On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
>> Some IOMMU drivers, such as the ARM SMMU driver, make available the
>> IOMMU_NOEXEC flag, to set the page tables for a device as XN (execute never).
>> This affects devices such as the ARM PL330 DMA Controller, which respects
>> this flag and will refuse to fetch DMA instructions from memory where the
>> XN flag has been set.
>>
>> The flag can be used only if all IOMMU domains behind the container support
>> the IOMMU_NOEXEC flag. Also, if any mappings are created with the flag, any
>> new domains with devices will have to support it as well.
>>
>> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
>> ---
>> drivers/vfio/vfio_iommu_type1.c | 25 ++++++++++++++++++++++++-
>> 1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
>> index 8b4202a..e225e8f 100644
>> --- a/drivers/vfio/vfio_iommu_type1.c
>> +++ b/drivers/vfio/vfio_iommu_type1.c
>> @@ -569,6 +569,12 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
>> if (map->flags & VFIO_DMA_MAP_FLAG_READ)
>> prot |= IOMMU_READ;
>>
>> + if (map->flags & VFIO_DMA_MAP_FLAG_NOEXEC) {
>> + if (!vfio_domains_have_iommu_cap(iommu, IOMMU_CAP_NOEXEC))
>> + return -EINVAL;
>> + prot |= IOMMU_NOEXEC;
>> + }
>> +
>> if (!prot || !size || (size | iova | vaddr) & mask)
>> return -EINVAL;
>
> I think this test needs to move above adding the NOEXEC flag, otherwise
> we now allow mappings without read or write, which is an ABI change.
>
Ack.
>>
>> @@ -662,6 +668,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
>> dma = rb_entry(n, struct vfio_dma, node);
>> iova = dma->iova;
>>
>> + /*
>> + * if any of the mappings to be replayed has the NOEXEC flag
>> + * set, then the new iommu domain must support it
>> + */
>> + if ((dma->prot | IOMMU_NOEXEC) &&
>
> I think you mean
>
> & IOMMU_NOEXEC
Ack.
>
>> + !(domain->caps & IOMMU_CAP_NOEXEC))
>> + return -EINVAL;
>> +
>
> In patch 2/5 you stated:
>
> The IOMMU_NOEXEC flag needs to be available for all the IOMMUs
> of the container used.
>
> But here you'll create heterogeneous containers so long as there are no
> NOEXEC mappings. Is that intentional or a side effect of the above
> masking bug?
>
Yeah, my intention was to not stop the user of having heterogeneous
containers, as long as he doesn't care about using the NOEXEC flag. As
soon as the user tries to apply this flag however, then it should be
supported by all the IOMMUs behind the container - otherwise it is not
enforceable.
Do you think we should change this behavior? I think most users will
not care about using this flag, and we should not stop them from
mixing containers.
>> while (iova < dma->iova + dma->size) {
>> phys_addr_t phys = iommu_iova_to_phys(d->domain, iova);
>> size_t size;
>> @@ -749,6 +763,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>> if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
>> domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
>>
>> + if (iommu_capable(bus, IOMMU_CAP_NOEXEC))
>> + domain->caps |= IOMMU_CAP_NOEXEC;
>> +
>> /*
>> * Try to match an existing compatible domain. We don't want to
>> * preclude an IOMMU driver supporting multiple bus_types and being
>> @@ -900,6 +917,11 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>> return 0;
>> return vfio_domains_have_iommu_cap(iommu,
>> IOMMU_CAP_CACHE_COHERENCY);
>> + case VFIO_DMA_NOEXEC_IOMMU:
>> + if (!iommu)
>> + return 0;
>> + return vfio_domains_have_iommu_cap(iommu,
>> + IOMMU_CAP_NOEXEC);
>> default:
>> return 0;
>> }
>> @@ -923,7 +945,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>> } else if (cmd == VFIO_IOMMU_MAP_DMA) {
>> struct vfio_iommu_type1_dma_map map;
>> uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
>> - VFIO_DMA_MAP_FLAG_WRITE;
>> + VFIO_DMA_MAP_FLAG_WRITE |
>> + VFIO_DMA_MAP_FLAG_NOEXEC;
>>
>> minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
>>
>
>
>
--
Antonios Motakis
Virtual Open Systems
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-21 12:40 ` Antonios Motakis
@ 2014-10-21 14:37 ` Alex Williamson
2014-10-21 14:41 ` Antonios Motakis
0 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2014-10-21 14:37 UTC (permalink / raw)
To: Antonios Motakis
Cc: kvm-arm, Linux IOMMU, Will Deacon,
VirtualOpenSystems Technical Team, Christoffer Dall, Eric Auger,
Kim Phillips, Marc Zyngier, open list:VFIO DRIVER, open list
On Tue, 2014-10-21 at 14:40 +0200, Antonios Motakis wrote:
> On Mon, Oct 20, 2014 at 11:13 PM, Alex Williamson
> <alex.williamson@redhat.com> wrote:
> > On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
> >> Some IOMMU drivers, such as the ARM SMMU driver, make available the
> >> IOMMU_NOEXEC flag, to set the page tables for a device as XN (execute never).
> >> This affects devices such as the ARM PL330 DMA Controller, which respects
> >> this flag and will refuse to fetch DMA instructions from memory where the
> >> XN flag has been set.
> >>
> >> The flag can be used only if all IOMMU domains behind the container support
> >> the IOMMU_NOEXEC flag. Also, if any mappings are created with the flag, any
> >> new domains with devices will have to support it as well.
> >>
> >> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
> >> ---
> >> drivers/vfio/vfio_iommu_type1.c | 25 ++++++++++++++++++++++++-
> >> 1 file changed, 24 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> >> index 8b4202a..e225e8f 100644
> >> --- a/drivers/vfio/vfio_iommu_type1.c
> >> +++ b/drivers/vfio/vfio_iommu_type1.c
> >> @@ -569,6 +569,12 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
> >> if (map->flags & VFIO_DMA_MAP_FLAG_READ)
> >> prot |= IOMMU_READ;
> >>
> >> + if (map->flags & VFIO_DMA_MAP_FLAG_NOEXEC) {
> >> + if (!vfio_domains_have_iommu_cap(iommu, IOMMU_CAP_NOEXEC))
> >> + return -EINVAL;
> >> + prot |= IOMMU_NOEXEC;
> >> + }
> >> +
> >> if (!prot || !size || (size | iova | vaddr) & mask)
> >> return -EINVAL;
> >
> > I think this test needs to move above adding the NOEXEC flag, otherwise
> > we now allow mappings without read or write, which is an ABI change.
> >
>
> Ack.
>
> >>
> >> @@ -662,6 +668,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
> >> dma = rb_entry(n, struct vfio_dma, node);
> >> iova = dma->iova;
> >>
> >> + /*
> >> + * if any of the mappings to be replayed has the NOEXEC flag
> >> + * set, then the new iommu domain must support it
> >> + */
> >> + if ((dma->prot | IOMMU_NOEXEC) &&
> >
> > I think you mean
> >
> > & IOMMU_NOEXEC
>
> Ack.
>
> >
> >> + !(domain->caps & IOMMU_CAP_NOEXEC))
> >> + return -EINVAL;
> >> +
> >
> > In patch 2/5 you stated:
> >
> > The IOMMU_NOEXEC flag needs to be available for all the IOMMUs
> > of the container used.
> >
> > But here you'll create heterogeneous containers so long as there are no
> > NOEXEC mappings. Is that intentional or a side effect of the above
> > masking bug?
> >
>
> Yeah, my intention was to not stop the user of having heterogeneous
> containers, as long as he doesn't care about using the NOEXEC flag. As
> soon as the user tries to apply this flag however, then it should be
> supported by all the IOMMUs behind the container - otherwise it is not
> enforceable.
>
> Do you think we should change this behavior? I think most users will
> not care about using this flag, and we should not stop them from
> mixing containers.
I think that's a reasonable way to go, but let's add a comment in uapi
vfio.h describing that expectation. Thanks,
Alex
> >> while (iova < dma->iova + dma->size) {
> >> phys_addr_t phys = iommu_iova_to_phys(d->domain, iova);
> >> size_t size;
> >> @@ -749,6 +763,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> >> if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
> >> domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
> >>
> >> + if (iommu_capable(bus, IOMMU_CAP_NOEXEC))
> >> + domain->caps |= IOMMU_CAP_NOEXEC;
> >> +
> >> /*
> >> * Try to match an existing compatible domain. We don't want to
> >> * preclude an IOMMU driver supporting multiple bus_types and being
> >> @@ -900,6 +917,11 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
> >> return 0;
> >> return vfio_domains_have_iommu_cap(iommu,
> >> IOMMU_CAP_CACHE_COHERENCY);
> >> + case VFIO_DMA_NOEXEC_IOMMU:
> >> + if (!iommu)
> >> + return 0;
> >> + return vfio_domains_have_iommu_cap(iommu,
> >> + IOMMU_CAP_NOEXEC);
> >> default:
> >> return 0;
> >> }
> >> @@ -923,7 +945,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
> >> } else if (cmd == VFIO_IOMMU_MAP_DMA) {
> >> struct vfio_iommu_type1_dma_map map;
> >> uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
> >> - VFIO_DMA_MAP_FLAG_WRITE;
> >> + VFIO_DMA_MAP_FLAG_WRITE |
> >> + VFIO_DMA_MAP_FLAG_NOEXEC;
> >>
> >> minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
> >>
> >
> >
> >
>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] vfio/iommu_type1: implement the VFIO_DMA_MAP_FLAG_NOEXEC flag
2014-10-21 14:37 ` Alex Williamson
@ 2014-10-21 14:41 ` Antonios Motakis
0 siblings, 0 replies; 14+ messages in thread
From: Antonios Motakis @ 2014-10-21 14:41 UTC (permalink / raw)
To: Alex Williamson
Cc: kvm-arm, Linux IOMMU, Will Deacon,
VirtualOpenSystems Technical Team, Christoffer Dall, Eric Auger,
Kim Phillips, Marc Zyngier, open list:VFIO DRIVER, open list
On Tue, Oct 21, 2014 at 4:37 PM, Alex Williamson
<alex.williamson@redhat.com> wrote:
> On Tue, 2014-10-21 at 14:40 +0200, Antonios Motakis wrote:
>> On Mon, Oct 20, 2014 at 11:13 PM, Alex Williamson
>> <alex.williamson@redhat.com> wrote:
>> > On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
>> >> Some IOMMU drivers, such as the ARM SMMU driver, make available the
>> >> IOMMU_NOEXEC flag, to set the page tables for a device as XN (execute never).
>> >> This affects devices such as the ARM PL330 DMA Controller, which respects
>> >> this flag and will refuse to fetch DMA instructions from memory where the
>> >> XN flag has been set.
>> >>
>> >> The flag can be used only if all IOMMU domains behind the container support
>> >> the IOMMU_NOEXEC flag. Also, if any mappings are created with the flag, any
>> >> new domains with devices will have to support it as well.
>> >>
>> >> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
>> >> ---
>> >> drivers/vfio/vfio_iommu_type1.c | 25 ++++++++++++++++++++++++-
>> >> 1 file changed, 24 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
>> >> index 8b4202a..e225e8f 100644
>> >> --- a/drivers/vfio/vfio_iommu_type1.c
>> >> +++ b/drivers/vfio/vfio_iommu_type1.c
>> >> @@ -569,6 +569,12 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
>> >> if (map->flags & VFIO_DMA_MAP_FLAG_READ)
>> >> prot |= IOMMU_READ;
>> >>
>> >> + if (map->flags & VFIO_DMA_MAP_FLAG_NOEXEC) {
>> >> + if (!vfio_domains_have_iommu_cap(iommu, IOMMU_CAP_NOEXEC))
>> >> + return -EINVAL;
>> >> + prot |= IOMMU_NOEXEC;
>> >> + }
>> >> +
>> >> if (!prot || !size || (size | iova | vaddr) & mask)
>> >> return -EINVAL;
>> >
>> > I think this test needs to move above adding the NOEXEC flag, otherwise
>> > we now allow mappings without read or write, which is an ABI change.
>> >
>>
>> Ack.
>>
>> >>
>> >> @@ -662,6 +668,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
>> >> dma = rb_entry(n, struct vfio_dma, node);
>> >> iova = dma->iova;
>> >>
>> >> + /*
>> >> + * if any of the mappings to be replayed has the NOEXEC flag
>> >> + * set, then the new iommu domain must support it
>> >> + */
>> >> + if ((dma->prot | IOMMU_NOEXEC) &&
>> >
>> > I think you mean
>> >
>> > & IOMMU_NOEXEC
>>
>> Ack.
>>
>> >
>> >> + !(domain->caps & IOMMU_CAP_NOEXEC))
>> >> + return -EINVAL;
>> >> +
>> >
>> > In patch 2/5 you stated:
>> >
>> > The IOMMU_NOEXEC flag needs to be available for all the IOMMUs
>> > of the container used.
>> >
>> > But here you'll create heterogeneous containers so long as there are no
>> > NOEXEC mappings. Is that intentional or a side effect of the above
>> > masking bug?
>> >
>>
>> Yeah, my intention was to not stop the user of having heterogeneous
>> containers, as long as he doesn't care about using the NOEXEC flag. As
>> soon as the user tries to apply this flag however, then it should be
>> supported by all the IOMMUs behind the container - otherwise it is not
>> enforceable.
>>
>> Do you think we should change this behavior? I think most users will
>> not care about using this flag, and we should not stop them from
>> mixing containers.
>
> I think that's a reasonable way to go, but let's add a comment in uapi
> vfio.h describing that expectation. Thanks,
Ok, will do.
>
> Alex
>
>> >> while (iova < dma->iova + dma->size) {
>> >> phys_addr_t phys = iommu_iova_to_phys(d->domain, iova);
>> >> size_t size;
>> >> @@ -749,6 +763,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>> >> if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
>> >> domain->caps |= IOMMU_CAP_CACHE_COHERENCY;
>> >>
>> >> + if (iommu_capable(bus, IOMMU_CAP_NOEXEC))
>> >> + domain->caps |= IOMMU_CAP_NOEXEC;
>> >> +
>> >> /*
>> >> * Try to match an existing compatible domain. We don't want to
>> >> * preclude an IOMMU driver supporting multiple bus_types and being
>> >> @@ -900,6 +917,11 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>> >> return 0;
>> >> return vfio_domains_have_iommu_cap(iommu,
>> >> IOMMU_CAP_CACHE_COHERENCY);
>> >> + case VFIO_DMA_NOEXEC_IOMMU:
>> >> + if (!iommu)
>> >> + return 0;
>> >> + return vfio_domains_have_iommu_cap(iommu,
>> >> + IOMMU_CAP_NOEXEC);
>> >> default:
>> >> return 0;
>> >> }
>> >> @@ -923,7 +945,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>> >> } else if (cmd == VFIO_IOMMU_MAP_DMA) {
>> >> struct vfio_iommu_type1_dma_map map;
>> >> uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
>> >> - VFIO_DMA_MAP_FLAG_WRITE;
>> >> + VFIO_DMA_MAP_FLAG_WRITE |
>> >> + VFIO_DMA_MAP_FLAG_NOEXEC;
>> >>
>> >> minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
>> >>
>> >
>> >
>> >
>>
>>
>>
>
>
>
--
Antonios Motakis
Virtual Open Systems
^ permalink raw reply [flat|nested] 14+ messages in thread