[Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Create a new file to hold the emulation code for the ITS widget. For now we emulate the memory mapped ITS registers and provide a stub to introduce the ITS command handling framework (but without actually emulating any commands at this time). Signed-off-by: Andre Przywara --- xen/arch/arm/Makefile | 1 + xen/arch/arm/vgic-its.c | 378 ++ xen/arch/arm/vgic-v3.c| 9 - xen/include/asm-arm/gic_v3_defs.h | 19 ++ 4 files changed, 398 insertions(+), 9 deletions(-) create mode 100644 xen/arch/arm/vgic-its.c diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index c2c4daa..cb0201f 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -44,6 +44,7 @@ obj-y += traps.o obj-y += vgic.o obj-y += vgic-v2.o obj-$(CONFIG_ARM_64) += vgic-v3.o +obj-$(CONFIG_HAS_ITS) += vgic-its.o obj-y += vm_event.o obj-y += vtimer.o obj-y += vpsci.o diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c new file mode 100644 index 000..875b992 --- /dev/null +++ b/xen/arch/arm/vgic-its.c @@ -0,0 +1,378 @@ +/* + * xen/arch/arm/vgic-its.c + * + * ARM Interrupt Translation Service (ITS) emulation + * + * Andre Przywara + * Copyright (c) 2016 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Data structure to describe a virtual ITS */ +struct virt_its { +struct domain *d; +struct host_its *hw_its; +spinlock_t vcmd_lock; /* protects the virtual command buffer */ +uint64_t cbaser; +uint64_t *cmdbuf; +int cwriter; +int creadr; +spinlock_t its_lock;/* protects the collection and device tables */ +uint64_t baser0, baser1; +uint16_t *coll_table; +int max_collections; +uint64_t *dev_table; +int max_devices; +bool enabled; +}; + +/* An Interrupt Translation Table Entry: this is indexed by a + * DeviceID/EventID pair and is located in guest memory. + */ +struct vits_itte +{ +uint64_t hlpi:24; +uint64_t vlpi:24; +uint64_t collection:16; +}; + +/** + * Functions that handle ITS commands * + **/ + +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, + int word, int shift, int size) +{ +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); +} + +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) + +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) + +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, +uint32_t writer) +{ +uint64_t *cmdptr; + +if ( !its->cmdbuf ) +return -1; + +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) +return -1; + +spin_lock(&its->vcmd_lock); + +while ( its->creadr != writer ) +{ +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); +switch (its_cmd_get_command(cmdptr)) +{ +case GITS_CMD_SYNC: +/* We handle ITS commands synchronously, so we ignore SYNC. */ + break; +default: +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", + its_cmd_get_command(cmdptr)); +break; +} + +its->creadr += ITS_CMD_SIZE; +if ( its->creadr == ITS_CMD_BUFFER_SIZE(its->cbaser) ) +its->creadr = 0; +} +its->cwriter = writer; + +spin_unlock(&its->vcmd_lock); + +return 0; +} + +/* + * ITS registers read access * + */ + +/* The physical address is encoded slightly differently depending on + * the used page size: the highest four bits are stored in the lowest + * four bits of the field for 64K pages. + */ +static paddr_t get
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara wrote: > Create a new file to hold the emulation code for the ITS widget. > For now we emulate the memory mapped ITS registers and provide a stub > to introduce the ITS command handling framework (but without actually > emulating any commands at this time). > > Signed-off-by: Andre Przywara > --- > xen/arch/arm/Makefile | 1 + > xen/arch/arm/vgic-its.c | 378 > ++ > xen/arch/arm/vgic-v3.c| 9 - > xen/include/asm-arm/gic_v3_defs.h | 19 ++ > 4 files changed, 398 insertions(+), 9 deletions(-) > create mode 100644 xen/arch/arm/vgic-its.c > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index c2c4daa..cb0201f 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -44,6 +44,7 @@ obj-y += traps.o > obj-y += vgic.o > obj-y += vgic-v2.o > obj-$(CONFIG_ARM_64) += vgic-v3.o > +obj-$(CONFIG_HAS_ITS) += vgic-its.o > obj-y += vm_event.o > obj-y += vtimer.o > obj-y += vpsci.o > diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c > new file mode 100644 > index 000..875b992 > --- /dev/null > +++ b/xen/arch/arm/vgic-its.c > @@ -0,0 +1,378 @@ > +/* > + * xen/arch/arm/vgic-its.c > + * > + * ARM Interrupt Translation Service (ITS) emulation > + * > + * Andre Przywara > + * Copyright (c) 2016 ARM Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* Data structure to describe a virtual ITS */ > +struct virt_its { > +struct domain *d; > +struct host_its *hw_its; > +spinlock_t vcmd_lock; /* protects the virtual command buffer */ > +uint64_t cbaser; > +uint64_t *cmdbuf; > +int cwriter; > +int creadr; > +spinlock_t its_lock;/* protects the collection and device tables > */ > +uint64_t baser0, baser1; > +uint16_t *coll_table; > +int max_collections; > +uint64_t *dev_table; > +int max_devices; > +bool enabled; > +}; > + > +/* An Interrupt Translation Table Entry: this is indexed by a > + * DeviceID/EventID pair and is located in guest memory. > + */ > +struct vits_itte > +{ > +uint64_t hlpi:24; > +uint64_t vlpi:24; > +uint64_t collection:16; > +}; > + > +/** > + * Functions that handle ITS commands * > + **/ > + > +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, > + int word, int shift, int size) > +{ > +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); > +} > + > +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) > +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) > +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) > +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) > +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) > +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) > +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) > +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) > + > +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) > + > +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, > +uint32_t writer) > +{ > +uint64_t *cmdptr; > + > +if ( !its->cmdbuf ) > +return -1; > + > +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +return -1; > + > +spin_lock(&its->vcmd_lock); > + > +while ( its->creadr != writer ) > +{ > +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); > +switch (its_cmd_get_command(cmdptr)) > +{ > +case GITS_CMD_SYNC: > +/* We handle ITS commands synchronously, so we ignore SYNC. */ > + break; > +default: > +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", > + its_cmd_get_command(cmdptr)); > +break; > +} > + > +its->creadr += ITS_CMD_SIZE; > +if ( its->creadr == ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +its->creadr = 0; > +} > +its->cwriter = writer; > + > +
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Hi, On 09/10/16 15:20, Vijay Kilari wrote: > On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara > wrote: >> Create a new file to hold the emulation code for the ITS widget. >> For now we emulate the memory mapped ITS registers and provide a stub >> to introduce the ITS command handling framework (but without actually >> emulating any commands at this time). >> >> Signed-off-by: Andre Przywara >> --- >> xen/arch/arm/Makefile | 1 + >> xen/arch/arm/vgic-its.c | 378 >> ++ >> xen/arch/arm/vgic-v3.c| 9 - >> xen/include/asm-arm/gic_v3_defs.h | 19 ++ >> 4 files changed, 398 insertions(+), 9 deletions(-) >> create mode 100644 xen/arch/arm/vgic-its.c >> >> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile >> index c2c4daa..cb0201f 100644 >> --- a/xen/arch/arm/Makefile >> +++ b/xen/arch/arm/Makefile >> @@ -44,6 +44,7 @@ obj-y += traps.o >> obj-y += vgic.o >> obj-y += vgic-v2.o >> obj-$(CONFIG_ARM_64) += vgic-v3.o >> +obj-$(CONFIG_HAS_ITS) += vgic-its.o >> obj-y += vm_event.o >> obj-y += vtimer.o >> obj-y += vpsci.o >> diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c >> new file mode 100644 >> index 000..875b992 >> --- /dev/null >> +++ b/xen/arch/arm/vgic-its.c >> @@ -0,0 +1,378 @@ >> +/* >> + * xen/arch/arm/vgic-its.c >> + * >> + * ARM Interrupt Translation Service (ITS) emulation >> + * >> + * Andre Przywara >> + * Copyright (c) 2016 ARM Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* Data structure to describe a virtual ITS */ >> +struct virt_its { >> +struct domain *d; >> +struct host_its *hw_its; >> +spinlock_t vcmd_lock; /* protects the virtual command buffer */ >> +uint64_t cbaser; >> +uint64_t *cmdbuf; >> +int cwriter; >> +int creadr; >> +spinlock_t its_lock;/* protects the collection and device >> tables */ >> +uint64_t baser0, baser1; >> +uint16_t *coll_table; >> +int max_collections; >> +uint64_t *dev_table; >> +int max_devices; >> +bool enabled; >> +}; >> + >> +/* An Interrupt Translation Table Entry: this is indexed by a >> + * DeviceID/EventID pair and is located in guest memory. >> + */ >> +struct vits_itte >> +{ >> +uint64_t hlpi:24; >> +uint64_t vlpi:24; >> +uint64_t collection:16; >> +}; >> + >> +/** >> + * Functions that handle ITS commands * >> + **/ >> + >> +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, >> + int word, int shift, int size) >> +{ >> +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); >> +} >> + >> +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) >> +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) >> +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) >> +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) >> +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) >> +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) >> +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) >> +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) >> + >> +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) >> + >> +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, >> +uint32_t writer) >> +{ >> +uint64_t *cmdptr; >> + >> +if ( !its->cmdbuf ) >> +return -1; >> + >> +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) >> +return -1; >> + >> +spin_lock(&its->vcmd_lock); >> + >> +while ( its->creadr != writer ) >> +{ >> +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); >> +switch (its_cmd_get_command(cmdptr)) >> +{ >> +case GITS_CMD_SYNC: >> +/* We handle ITS commands synchronously, so we ignore SYNC. */ >> + break; >> +default: >> +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", >> + its_cmd_get_command(cmdptr)); >> +break; >> +
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara wrote: > Create a new file to hold the emulation code for the ITS widget. > For now we emulate the memory mapped ITS registers and provide a stub > to introduce the ITS command handling framework (but without actually > emulating any commands at this time). > > Signed-off-by: Andre Przywara > --- > xen/arch/arm/Makefile | 1 + > xen/arch/arm/vgic-its.c | 378 > ++ > xen/arch/arm/vgic-v3.c| 9 - > xen/include/asm-arm/gic_v3_defs.h | 19 ++ > 4 files changed, 398 insertions(+), 9 deletions(-) > create mode 100644 xen/arch/arm/vgic-its.c > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index c2c4daa..cb0201f 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -44,6 +44,7 @@ obj-y += traps.o > obj-y += vgic.o > obj-y += vgic-v2.o > obj-$(CONFIG_ARM_64) += vgic-v3.o > +obj-$(CONFIG_HAS_ITS) += vgic-its.o > obj-y += vm_event.o > obj-y += vtimer.o > obj-y += vpsci.o > diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c > new file mode 100644 > index 000..875b992 > --- /dev/null > +++ b/xen/arch/arm/vgic-its.c > @@ -0,0 +1,378 @@ > +/* > + * xen/arch/arm/vgic-its.c > + * > + * ARM Interrupt Translation Service (ITS) emulation > + * > + * Andre Przywara > + * Copyright (c) 2016 ARM Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* Data structure to describe a virtual ITS */ > +struct virt_its { > +struct domain *d; > +struct host_its *hw_its; > +spinlock_t vcmd_lock; /* protects the virtual command buffer */ > +uint64_t cbaser; > +uint64_t *cmdbuf; > +int cwriter; > +int creadr; > +spinlock_t its_lock;/* protects the collection and device tables > */ > +uint64_t baser0, baser1; > +uint16_t *coll_table; > +int max_collections; > +uint64_t *dev_table; > +int max_devices; > +bool enabled; > +}; > + > +/* An Interrupt Translation Table Entry: this is indexed by a > + * DeviceID/EventID pair and is located in guest memory. > + */ > +struct vits_itte > +{ > +uint64_t hlpi:24; > +uint64_t vlpi:24; > +uint64_t collection:16; > +}; > + > +/** > + * Functions that handle ITS commands * > + **/ > + > +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, > + int word, int shift, int size) > +{ > +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); > +} > + > +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) > +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) > +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) > +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) > +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) > +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) > +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) > +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) > + > +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) > + > +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, > +uint32_t writer) > +{ > +uint64_t *cmdptr; > + > +if ( !its->cmdbuf ) > +return -1; > + > +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +return -1; > + > +spin_lock(&its->vcmd_lock); > + > +while ( its->creadr != writer ) > +{ > +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); > +switch (its_cmd_get_command(cmdptr)) > +{ > +case GITS_CMD_SYNC: > +/* We handle ITS commands synchronously, so we ignore SYNC. */ > + break; > +default: > +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", > + its_cmd_get_command(cmdptr)); > +break; > +} > + > +its->creadr += ITS_CMD_SIZE; > +if ( its->creadr == ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +its->creadr = 0; > +} > +its->cwriter = writer; > + > +
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Hi Andre, On 28/09/16 19:24, Andre Przywara wrote: Create a new file to hold the emulation code for the ITS widget. For now we emulate the memory mapped ITS registers and provide a stub to introduce the ITS command handling framework (but without actually emulating any commands at this time). The ITS is a complex piece so I think it would be good to describe more in the commit message how this will work. Also a documentation in the tree would be very good to help understanding the code. Signed-off-by: Andre Przywara --- xen/arch/arm/Makefile | 1 + xen/arch/arm/vgic-its.c | 378 ++ xen/arch/arm/vgic-v3.c| 9 - xen/include/asm-arm/gic_v3_defs.h | 19 ++ 4 files changed, 398 insertions(+), 9 deletions(-) create mode 100644 xen/arch/arm/vgic-its.c diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index c2c4daa..cb0201f 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -44,6 +44,7 @@ obj-y += traps.o obj-y += vgic.o obj-y += vgic-v2.o obj-$(CONFIG_ARM_64) += vgic-v3.o +obj-$(CONFIG_HAS_ITS) += vgic-its.o obj-y += vm_event.o obj-y += vtimer.o obj-y += vpsci.o diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c new file mode 100644 index 000..875b992 --- /dev/null +++ b/xen/arch/arm/vgic-its.c @@ -0,0 +1,378 @@ +/* + * xen/arch/arm/vgic-its.c + * + * ARM Interrupt Translation Service (ITS) emulation + * + * Andre Przywara + * Copyright (c) 2016 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Data structure to describe a virtual ITS */ +struct virt_its { +struct domain *d; +struct host_its *hw_its; +spinlock_t vcmd_lock; /* protects the virtual command buffer */ +uint64_t cbaser; +uint64_t *cmdbuf; +int cwriter; +int creadr; CWRITER and CREADR are registers so they need to be described in term of number of bits. Also, while the top word of CREADR/CWRITER is RES0. I would much prefer to see uint64_t rather than uint32_t as this is the real size of the register. +spinlock_t its_lock;/* protects the collection and device tables */ +uint64_t baser0, baser1; Please describe what contains baser0 and baser1. If I understand correctly the code, baser0 will be store Device information whilst baser1 the collection. +uint16_t *coll_table; What is the layout of the device table? +int max_collections; unsigned int +uint64_t *dev_table; What is the layout of the device table? +int max_devices; unsigned int. +bool enabled; +}; + +/* An Interrupt Translation Table Entry: this is indexed by a Coding style: /* * Foo + * DeviceID/EventID pair and is located in guest memory. + */ +struct vits_itte +{ +uint64_t hlpi:24; +uint64_t vlpi:24; +uint64_t collection:16; +}; + +/** + * Functions that handle ITS commands * + **/ + +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, Please make this function inline. + int word, int shift, int size) unsigned for all those parameters. +{ +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); It is probably better to use BIT_ULL (see my explanation on previous patches). +} + +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) + +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) + +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, +uint32_t writer) uint64_t here. +{ +uint64_t *cmdptr; + +if ( !its->cmdbuf ) +return -1; + +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) +return -1; You return an error value but the cal
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Hi, On 24/10/16 16:31, Vijay Kilari wrote: > On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara > wrote: >> Create a new file to hold the emulation code for the ITS widget. >> For now we emulate the memory mapped ITS registers and provide a stub >> to introduce the ITS command handling framework (but without actually >> emulating any commands at this time). >> >> Signed-off-by: Andre Przywara >> --- >> xen/arch/arm/Makefile | 1 + >> xen/arch/arm/vgic-its.c | 378 >> ++ >> xen/arch/arm/vgic-v3.c| 9 - >> xen/include/asm-arm/gic_v3_defs.h | 19 ++ >> 4 files changed, 398 insertions(+), 9 deletions(-) >> create mode 100644 xen/arch/arm/vgic-its.c >> >> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile >> index c2c4daa..cb0201f 100644 >> --- a/xen/arch/arm/Makefile >> +++ b/xen/arch/arm/Makefile >> @@ -44,6 +44,7 @@ obj-y += traps.o >> obj-y += vgic.o >> obj-y += vgic-v2.o >> obj-$(CONFIG_ARM_64) += vgic-v3.o >> +obj-$(CONFIG_HAS_ITS) += vgic-its.o >> obj-y += vm_event.o >> obj-y += vtimer.o >> obj-y += vpsci.o >> diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c >> new file mode 100644 >> index 000..875b992 >> --- /dev/null >> +++ b/xen/arch/arm/vgic-its.c >> @@ -0,0 +1,378 @@ >> +/* >> + * xen/arch/arm/vgic-its.c >> + * >> + * ARM Interrupt Translation Service (ITS) emulation >> + * >> + * Andre Przywara >> + * Copyright (c) 2016 ARM Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* Data structure to describe a virtual ITS */ >> +struct virt_its { >> +struct domain *d; >> +struct host_its *hw_its; >> +spinlock_t vcmd_lock; /* protects the virtual command buffer */ >> +uint64_t cbaser; >> +uint64_t *cmdbuf; >> +int cwriter; >> +int creadr; >> +spinlock_t its_lock;/* protects the collection and device >> tables */ >> +uint64_t baser0, baser1; >> +uint16_t *coll_table; >> +int max_collections; >> +uint64_t *dev_table; >> +int max_devices; >> +bool enabled; >> +}; >> + >> +/* An Interrupt Translation Table Entry: this is indexed by a >> + * DeviceID/EventID pair and is located in guest memory. >> + */ >> +struct vits_itte >> +{ >> +uint64_t hlpi:24; >> +uint64_t vlpi:24; >> +uint64_t collection:16; >> +}; >> + >> +/** >> + * Functions that handle ITS commands * >> + **/ >> + >> +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, >> + int word, int shift, int size) >> +{ >> +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); >> +} >> + >> +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) >> +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) >> +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) >> +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) >> +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) >> +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) >> +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) >> +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) >> + >> +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) >> + >> +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, >> +uint32_t writer) >> +{ >> +uint64_t *cmdptr; >> + >> +if ( !its->cmdbuf ) >> +return -1; >> + >> +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) >> +return -1; >> + >> +spin_lock(&its->vcmd_lock); >> + >> +while ( its->creadr != writer ) >> +{ >> +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); >> +switch (its_cmd_get_command(cmdptr)) >> +{ >> +case GITS_CMD_SYNC: >> +/* We handle ITS commands synchronously, so we ignore SYNC. */ >> + break; >> +default: >> +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", >> + its_cmd_get_command(cmdptr)); >> +break; >> +
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Hello Andre, On 03/11/16 19:26, Andre Przywara wrote: On 24/10/16 16:31, Vijay Kilari wrote: On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara wrote: +switch ( info->gpa & 0x ) +{ +case VREG32(GITS_CTLR): +if ( info->dabt.size != DABT_WORD ) goto bad_width; +*r = vgic_reg32_extract(its->enabled | BIT(31), info); + break; +case VREG32(GITS_IIDR): +if ( info->dabt.size != DABT_WORD ) goto bad_width; +*r = vgic_reg32_extract(GITS_IIDR_VALUE, info); +break; +case VREG64(GITS_TYPER): +if ( info->dabt.size < DABT_WORD ) goto bad_width; +*r = vgic_reg64_extract(0x1eff1, info); GITS_TYPER.HCC is not set. Should be max vcpus of the domain HCC is clear on purpose. We want the guest to provide memory for everything that it allocates, to avoid it to hog Xen with allocations. Whilst I agree that we want to limit the memory allocated by Xen itself, each collection entry is just 16-bit. So unless we want to support a very big number of collection, I don't see any reason to request the guest to provision memory. This makes the code more complex and you also have to validate the collection every time. I remembered minimum number of collection an implementation has to support is "max_vcpus + 1" but I can't find again the statement in the spec. Regards, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
On Wed, 28 Sep 2016, Andre Przywara wrote: > Create a new file to hold the emulation code for the ITS widget. > For now we emulate the memory mapped ITS registers and provide a stub > to introduce the ITS command handling framework (but without actually > emulating any commands at this time). > > Signed-off-by: Andre Przywara > --- > xen/arch/arm/Makefile | 1 + > xen/arch/arm/vgic-its.c | 378 > ++ > xen/arch/arm/vgic-v3.c| 9 - > xen/include/asm-arm/gic_v3_defs.h | 19 ++ > 4 files changed, 398 insertions(+), 9 deletions(-) > create mode 100644 xen/arch/arm/vgic-its.c > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index c2c4daa..cb0201f 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -44,6 +44,7 @@ obj-y += traps.o > obj-y += vgic.o > obj-y += vgic-v2.o > obj-$(CONFIG_ARM_64) += vgic-v3.o > +obj-$(CONFIG_HAS_ITS) += vgic-its.o > obj-y += vm_event.o > obj-y += vtimer.o > obj-y += vpsci.o > diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c > new file mode 100644 > index 000..875b992 > --- /dev/null > +++ b/xen/arch/arm/vgic-its.c > @@ -0,0 +1,378 @@ > +/* > + * xen/arch/arm/vgic-its.c > + * > + * ARM Interrupt Translation Service (ITS) emulation > + * > + * Andre Przywara > + * Copyright (c) 2016 ARM Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* Data structure to describe a virtual ITS */ > +struct virt_its { > +struct domain *d; > +struct host_its *hw_its; > +spinlock_t vcmd_lock; /* protects the virtual command buffer */ > +uint64_t cbaser; > +uint64_t *cmdbuf; > +int cwriter; > +int creadr; > +spinlock_t its_lock;/* protects the collection and device tables > */ > +uint64_t baser0, baser1; > +uint16_t *coll_table; > +int max_collections; > +uint64_t *dev_table; > +int max_devices; > +bool enabled; > +}; > + > +/* An Interrupt Translation Table Entry: this is indexed by a > + * DeviceID/EventID pair and is located in guest memory. > + */ > +struct vits_itte > +{ > +uint64_t hlpi:24; > +uint64_t vlpi:24; > +uint64_t collection:16; > +}; > + > +/** > + * Functions that handle ITS commands * > + **/ > + > +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, > + int word, int shift, int size) > +{ > +return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); > +} > + > +#define its_cmd_get_command(cmd)its_cmd_mask_field(cmd, 0, 0, 8) > +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) > +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) > +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) > +#define its_cmd_get_physical_id(cmd)its_cmd_mask_field(cmd, 1, 32, 32) > +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) > +#define its_cmd_get_target_addr(cmd)its_cmd_mask_field(cmd, 2, 16, 32) > +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) > + > +#define ITS_CMD_BUFFER_SIZE(baser) baser) & 0xff) + 1) << 12) > + > +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, > +uint32_t writer) > +{ > +uint64_t *cmdptr; > + > +if ( !its->cmdbuf ) > +return -1; > + > +if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +return -1; > + > +spin_lock(&its->vcmd_lock); > + > +while ( its->creadr != writer ) > +{ > +cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); > + > +switch (its_cmd_get_command(cmdptr)) > +{ > +case GITS_CMD_SYNC: > +/* We handle ITS commands synchronously, so we ignore SYNC. */ > + break; indentation > +default: > +gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", > + its_cmd_get_command(cmdptr)); > +break; > +} > + > +its->creadr += ITS_CMD_SIZE; > +if ( its->creadr == ITS_CMD_BUFFER_SIZE(its->cbaser) ) > +its->creadr = 0; > +} > +its->cwriter = writer; > +