Skip to content

Commit ae24fb4

Browse files
jpbruckermstsirkin
authored andcommitted
iommu/virtio: Update to most recent specification
Following specification review a few things were changed in v8 of the virtio-iommu series [1], but have been omitted when merging the base driver. Add them now: * Remove the EXEC flag. * Add feature bit for the MMIO flag. * Change domain_bits to domain_range. * Add NOMEM status flag. [1] https://lore.kernel.org/linux-iommu/[email protected]/ Fixes: edcd69a ("iommu: Add virtio-iommu driver") Reported-by: Eric Auger <[email protected]> Signed-off-by: Jean-Philippe Brucker <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Reviewed-by: Eric Auger <[email protected]> Tested-by: Eric Auger <[email protected]> Acked-by: Joerg Roedel <[email protected]>
1 parent cfe6180 commit ae24fb4

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

drivers/iommu/virtio-iommu.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Virtio driver for the paravirtualized IOMMU
44
*
5-
* Copyright (C) 2018 Arm Limited
5+
* Copyright (C) 2019 Arm Limited
66
*/
77

88
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -47,7 +47,10 @@ struct viommu_dev {
4747
/* Device configuration */
4848
struct iommu_domain_geometry geometry;
4949
u64 pgsize_bitmap;
50-
u8 domain_bits;
50+
u32 first_domain;
51+
u32 last_domain;
52+
/* Supported MAP flags */
53+
u32 map_flags;
5154
u32 probe_size;
5255
};
5356

@@ -62,6 +65,7 @@ struct viommu_domain {
6265
struct viommu_dev *viommu;
6366
struct mutex mutex; /* protects viommu pointer */
6467
unsigned int id;
68+
u32 map_flags;
6569

6670
spinlock_t mappings_lock;
6771
struct rb_root_cached mappings;
@@ -113,6 +117,8 @@ static int viommu_get_req_errno(void *buf, size_t len)
113117
return -ENOENT;
114118
case VIRTIO_IOMMU_S_FAULT:
115119
return -EFAULT;
120+
case VIRTIO_IOMMU_S_NOMEM:
121+
return -ENOMEM;
116122
case VIRTIO_IOMMU_S_IOERR:
117123
case VIRTIO_IOMMU_S_DEVERR:
118124
default:
@@ -607,15 +613,15 @@ static int viommu_domain_finalise(struct viommu_dev *viommu,
607613
{
608614
int ret;
609615
struct viommu_domain *vdomain = to_viommu_domain(domain);
610-
unsigned int max_domain = viommu->domain_bits > 31 ? ~0 :
611-
(1U << viommu->domain_bits) - 1;
612616

613617
vdomain->viommu = viommu;
618+
vdomain->map_flags = viommu->map_flags;
614619

615620
domain->pgsize_bitmap = viommu->pgsize_bitmap;
616621
domain->geometry = viommu->geometry;
617622

618-
ret = ida_alloc_max(&viommu->domain_ids, max_domain, GFP_KERNEL);
623+
ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
624+
viommu->last_domain, GFP_KERNEL);
619625
if (ret >= 0)
620626
vdomain->id = (unsigned int)ret;
621627

@@ -710,14 +716,17 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
710716
phys_addr_t paddr, size_t size, int prot)
711717
{
712718
int ret;
713-
int flags;
719+
u32 flags;
714720
struct virtio_iommu_req_map map;
715721
struct viommu_domain *vdomain = to_viommu_domain(domain);
716722

717723
flags = (prot & IOMMU_READ ? VIRTIO_IOMMU_MAP_F_READ : 0) |
718724
(prot & IOMMU_WRITE ? VIRTIO_IOMMU_MAP_F_WRITE : 0) |
719725
(prot & IOMMU_MMIO ? VIRTIO_IOMMU_MAP_F_MMIO : 0);
720726

727+
if (flags & ~vdomain->map_flags)
728+
return -EINVAL;
729+
721730
ret = viommu_add_mapping(vdomain, iova, paddr, size, flags);
722731
if (ret)
723732
return ret;
@@ -1027,7 +1036,8 @@ static int viommu_probe(struct virtio_device *vdev)
10271036
goto err_free_vqs;
10281037
}
10291038

1030-
viommu->domain_bits = 32;
1039+
viommu->map_flags = VIRTIO_IOMMU_MAP_F_READ | VIRTIO_IOMMU_MAP_F_WRITE;
1040+
viommu->last_domain = ~0U;
10311041

10321042
/* Optional features */
10331043
virtio_cread_feature(vdev, VIRTIO_IOMMU_F_INPUT_RANGE,
@@ -1038,9 +1048,13 @@ static int viommu_probe(struct virtio_device *vdev)
10381048
struct virtio_iommu_config, input_range.end,
10391049
&input_end);
10401050

1041-
virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_BITS,
1042-
struct virtio_iommu_config, domain_bits,
1043-
&viommu->domain_bits);
1051+
virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_RANGE,
1052+
struct virtio_iommu_config, domain_range.start,
1053+
&viommu->first_domain);
1054+
1055+
virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_RANGE,
1056+
struct virtio_iommu_config, domain_range.end,
1057+
&viommu->last_domain);
10441058

10451059
virtio_cread_feature(vdev, VIRTIO_IOMMU_F_PROBE,
10461060
struct virtio_iommu_config, probe_size,
@@ -1052,6 +1066,9 @@ static int viommu_probe(struct virtio_device *vdev)
10521066
.force_aperture = true,
10531067
};
10541068

1069+
if (virtio_has_feature(vdev, VIRTIO_IOMMU_F_MMIO))
1070+
viommu->map_flags |= VIRTIO_IOMMU_MAP_F_MMIO;
1071+
10551072
viommu_ops.pgsize_bitmap = viommu->pgsize_bitmap;
10561073

10571074
virtio_device_ready(vdev);
@@ -1130,9 +1147,10 @@ static void viommu_config_changed(struct virtio_device *vdev)
11301147

11311148
static unsigned int features[] = {
11321149
VIRTIO_IOMMU_F_MAP_UNMAP,
1133-
VIRTIO_IOMMU_F_DOMAIN_BITS,
11341150
VIRTIO_IOMMU_F_INPUT_RANGE,
1151+
VIRTIO_IOMMU_F_DOMAIN_RANGE,
11351152
VIRTIO_IOMMU_F_PROBE,
1153+
VIRTIO_IOMMU_F_MMIO,
11361154
};
11371155

11381156
static struct virtio_device_id id_table[] = {

include/uapi/linux/virtio_iommu.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* SPDX-License-Identifier: BSD-3-Clause */
22
/*
3-
* Virtio-iommu definition v0.9
3+
* Virtio-iommu definition v0.12
44
*
5-
* Copyright (C) 2018 Arm Ltd.
5+
* Copyright (C) 2019 Arm Ltd.
66
*/
77
#ifndef _UAPI_LINUX_VIRTIO_IOMMU_H
88
#define _UAPI_LINUX_VIRTIO_IOMMU_H
@@ -11,26 +11,31 @@
1111

1212
/* Feature bits */
1313
#define VIRTIO_IOMMU_F_INPUT_RANGE 0
14-
#define VIRTIO_IOMMU_F_DOMAIN_BITS 1
14+
#define VIRTIO_IOMMU_F_DOMAIN_RANGE 1
1515
#define VIRTIO_IOMMU_F_MAP_UNMAP 2
1616
#define VIRTIO_IOMMU_F_BYPASS 3
1717
#define VIRTIO_IOMMU_F_PROBE 4
18+
#define VIRTIO_IOMMU_F_MMIO 5
1819

19-
struct virtio_iommu_range {
20-
__u64 start;
21-
__u64 end;
20+
struct virtio_iommu_range_64 {
21+
__le64 start;
22+
__le64 end;
23+
};
24+
25+
struct virtio_iommu_range_32 {
26+
__le32 start;
27+
__le32 end;
2228
};
2329

2430
struct virtio_iommu_config {
2531
/* Supported page sizes */
26-
__u64 page_size_mask;
32+
__le64 page_size_mask;
2733
/* Supported IOVA range */
28-
struct virtio_iommu_range input_range;
34+
struct virtio_iommu_range_64 input_range;
2935
/* Max domain ID size */
30-
__u8 domain_bits;
31-
__u8 padding[3];
36+
struct virtio_iommu_range_32 domain_range;
3237
/* Probe buffer size */
33-
__u32 probe_size;
38+
__le32 probe_size;
3439
};
3540

3641
/* Request types */
@@ -49,6 +54,7 @@ struct virtio_iommu_config {
4954
#define VIRTIO_IOMMU_S_RANGE 0x05
5055
#define VIRTIO_IOMMU_S_NOENT 0x06
5156
#define VIRTIO_IOMMU_S_FAULT 0x07
57+
#define VIRTIO_IOMMU_S_NOMEM 0x08
5258

5359
struct virtio_iommu_req_head {
5460
__u8 type;
@@ -78,12 +84,10 @@ struct virtio_iommu_req_detach {
7884

7985
#define VIRTIO_IOMMU_MAP_F_READ (1 << 0)
8086
#define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1)
81-
#define VIRTIO_IOMMU_MAP_F_EXEC (1 << 2)
82-
#define VIRTIO_IOMMU_MAP_F_MMIO (1 << 3)
87+
#define VIRTIO_IOMMU_MAP_F_MMIO (1 << 2)
8388

8489
#define VIRTIO_IOMMU_MAP_F_MASK (VIRTIO_IOMMU_MAP_F_READ | \
8590
VIRTIO_IOMMU_MAP_F_WRITE | \
86-
VIRTIO_IOMMU_MAP_F_EXEC | \
8791
VIRTIO_IOMMU_MAP_F_MMIO)
8892

8993
struct virtio_iommu_req_map {

0 commit comments

Comments
 (0)