[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 1/5] qdev: Introduce DEFINE_PROP_RESERVED_REGION
From: |
Auger Eric |
Subject: |
Re: [PATCH v4 1/5] qdev: Introduce DEFINE_PROP_RESERVED_REGION |
Date: |
Wed, 24 Jun 2020 10:38:57 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 |
Hi Markus,
On 6/24/20 10:10 AM, Markus Armbruster wrote:
> Auger Eric <eric.auger@redhat.com> writes:
>
>> Hi Markus,
>>
>> On 6/23/20 5:13 PM, Markus Armbruster wrote:
>>> Eric Auger <eric.auger@redhat.com> writes:
>>>
>>>> Introduce a new property defining a reserved region:
>>>> <low address>:<high address>:<type>.
>>>>
>>>> This will be used to encode reserved IOVA regions.
>>>>
>>>> For instance, in virtio-iommu use case, reserved IOVA regions
>>>> will be passed by the machine code to the virtio-iommu-pci
>>>> device (an array of those). The type of the reserved region
>>>> will match the virtio_iommu_probe_resv_mem subtype value:
>>>> - VIRTIO_IOMMU_RESV_MEM_T_RESERVED (0)
>>>> - VIRTIO_IOMMU_RESV_MEM_T_MSI (1)
>>>>
>>>> on PC/Q35 machine, this will be used to inform the
>>>> virtio-iommu-pci device it should bypass the MSI region.
>>>> The reserved region will be: 0xfee00000:0xfeefffff:1.
>>>>
>>>> On ARM, we can declare the ITS MSI doorbell as an MSI
>>>> region to prevent MSIs from being mapped on guest side.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>>>>
>>>> ---
>>>>
>>>> v3 -> v4:
>>>> - use ':' instead of commas as separators.
>>>> - rearrange error messages
>>>> - check snprintf returned value
>>>> - dared to keep Markus' R-b despite those changes
>>>> ---
>>>> include/exec/memory.h | 6 +++
>>>> include/hw/qdev-properties.h | 3 ++
>>>> include/qemu/typedefs.h | 1 +
>>>> hw/core/qdev-properties.c | 89 ++++++++++++++++++++++++++++++++++++
>>>> 4 files changed, 99 insertions(+)
>>>>
>>>> diff --git a/include/exec/memory.h b/include/exec/memory.h
>>>> index 7207025bd4..d7a53b96cc 100644
>>>> --- a/include/exec/memory.h
>>>> +++ b/include/exec/memory.h
>>>> @@ -51,6 +51,12 @@ extern bool global_dirty_log;
>>>>
>>>> typedef struct MemoryRegionOps MemoryRegionOps;
>>>>
>>>> +struct ReservedRegion {
>>>> + hwaddr low;
>>>> + hwaddr high;
>>>> + unsigned int type;
>>>
>>> Suggest to s/unsigned int/unsigned/.
>>>
>>>> +};
>>>> +
>>>> typedef struct IOMMUTLBEntry IOMMUTLBEntry;
>>>>
>>>> /* See address_space_translate: bit 0 is read, bit 1 is write. */
>>>> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
>>>> index 5252bb6b1a..95d0e7201d 100644
>>>> --- a/include/hw/qdev-properties.h
>>>> +++ b/include/hw/qdev-properties.h
>>>> @@ -19,6 +19,7 @@ extern const PropertyInfo qdev_prop_string;
>>>> extern const PropertyInfo qdev_prop_chr;
>>>> extern const PropertyInfo qdev_prop_tpm;
>>>> extern const PropertyInfo qdev_prop_macaddr;
>>>> +extern const PropertyInfo qdev_prop_reserved_region;
>>>> extern const PropertyInfo qdev_prop_on_off_auto;
>>>> extern const PropertyInfo qdev_prop_multifd_compression;
>>>> extern const PropertyInfo qdev_prop_losttickpolicy;
>>>> @@ -184,6 +185,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
>>>> DEFINE_PROP(_n, _s, _f, qdev_prop_drive_iothread, BlockBackend *)
>>>> #define DEFINE_PROP_MACADDR(_n, _s, _f) \
>>>> DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
>>>> +#define DEFINE_PROP_RESERVED_REGION(_n, _s, _f) \
>>>> + DEFINE_PROP(_n, _s, _f, qdev_prop_reserved_region, ReservedRegion)
>>>> #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
>>>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
>>>> #define DEFINE_PROP_MULTIFD_COMPRESSION(_n, _s, _f, _d) \
>>>> diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
>>>> index ce4a78b687..15f5047bf1 100644
>>>> --- a/include/qemu/typedefs.h
>>>> +++ b/include/qemu/typedefs.h
>>>> @@ -58,6 +58,7 @@ typedef struct ISABus ISABus;
>>>> typedef struct ISADevice ISADevice;
>>>> typedef struct IsaDma IsaDma;
>>>> typedef struct MACAddr MACAddr;
>>>> +typedef struct ReservedRegion ReservedRegion;
>>>> typedef struct MachineClass MachineClass;
>>>> typedef struct MachineState MachineState;
>>>> typedef struct MemoryListener MemoryListener;
>>>> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
>>>> index ead35d7ffd..193d0d95f9 100644
>>>> --- a/hw/core/qdev-properties.c
>>>> +++ b/hw/core/qdev-properties.c
>>>> @@ -15,6 +15,7 @@
>>>> #include "chardev/char.h"
>>>> #include "qemu/uuid.h"
>>>> #include "qemu/units.h"
>>>> +#include "qemu/cutils.h"
>>>>
>>>> void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
>>>> Error **errp)
>>>> @@ -578,6 +579,94 @@ const PropertyInfo qdev_prop_macaddr = {
>>>> .set = set_mac,
>>>> };
>>>>
>>>> +/* --- Reserved Region --- */
>>>> +
>>>> +/*
>>>> + * accepted syntax version:
>>>
>>> "version" feels redundant. Suggest to capitalize "Accepted".
>>>
>>>> + * <low address>:<high address>:<type>
>>>> + * where low/high addresses are uint64_t in hexadecimal
>>>> + * and type is an unsigned integer in decimal
>>>> + */
>>>> +static void get_reserved_region(Object *obj, Visitor *v, const char *name,
>>>> + void *opaque, Error **errp)
>>>> +{
>>>> + DeviceState *dev = DEVICE(obj);
>>>> + Property *prop = opaque;
>>>> + ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
>>>> + char buffer[64];
>>>> + char *p = buffer;
>>>> + int rc;
>>>> +
>>>> + rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
>>>> + rr->low, rr->high, rr->type);
>>>> + assert(rc < sizeof(buffer));
>>>> +
>>>> + visit_type_str(v, name, &p, errp);
>>>> +}
>>>> +
>>>> +static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>>>> + void *opaque, Error **errp)
>>>> +{
>>>> + DeviceState *dev = DEVICE(obj);
>>>> + Property *prop = opaque;
>>>> + ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
>>>> + Error *local_err = NULL;
>>>> + const char *endptr;
>>>> + char *str;
>>>> + int ret;
>>>> +
>>>> + if (dev->realized) {
>>>> + qdev_prop_set_after_realize(dev, name, errp);
>>>> + return;
>>>> + }
>>>> +
>>>> + visit_type_str(v, name, &str, &local_err);
>>>> + if (local_err) {
>>>> + error_propagate(errp, local_err);
>>>> + return;
>>>> + }
>>>> +
>>>> + ret = qemu_strtou64(str, &endptr, 16, &rr->low);
>>>> + if (ret) {
>>>> + error_setg(errp, "start address of '%s'"
>>>> + " must be a hexadecimal integer", name);
>>>> + goto out;
>>>> + }
>>>> + if (*endptr != ':') {
>>>> + goto separator_error;
>>>> + }
>>>> +
>>>> + ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high);
>>>> + if (ret) {
>>>> + error_setg(errp, "end address of '%s'"
>>>> + " must be a hexadecimal integer", name);
>>>> + goto out;
>>>> + }
>>>> + if (*endptr != ':') {
>>>> + goto separator_error;
>>>> + }
>>>> +
>>>> + ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type);
>>>> + if (ret) {
>>>> + error_setg(errp, "type of '%s'"
>>>> + " must be an unsigned integer in decimal", name);
>>>
>>> Suggest "must be a non-negative decimal integer".
>>>
>>> Whatever uses the property needs a range check. I can't see that the
>>> patches that follow. What am I missing?
>> Do you mean, you would expect the virtio-iommu-pci device to abort in
>> case a wrong VIRTIO reserved region type has been registered?
>
> Knowing nothing about reserved region types, I (naively?) assume that a
> finite set of types are encoded as small integers. Any other integers
> are then meaningless, and should be rejected.
you're right.
>
>> Effectively I could do that.
>>
>> For the time being, unexpected types are considered as RESERVED type.
>> Also reserved regions are set by the machinesa nd we don't expect users
>> to set them directly so I thought it was sufficient.
>
> One, rejecting invalid values is useful even when they're set
> programmatically, because it can catch programming errors.
>
> Two, expecting users to only do what you expect is walking on rather
> thin ice ;)
Agreed, I will add an assert()
Thanks!
Eric
>
[PATCH v4 2/5] virtio-iommu: Implement RESV_MEM probe request, Eric Auger, 2020/06/23
[PATCH v4 3/5] virtio-iommu: Handle reserved regions in the translation process, Eric Auger, 2020/06/23
[PATCH v4 4/5] virtio-iommu-pci: Add array of Interval properties, Eric Auger, 2020/06/23
[PATCH v4 5/5] hw/arm/virt: Let the virtio-iommu bypass MSIs, Eric Auger, 2020/06/23