From: Marc-André Lureau <marcandre.lureau@redhat.com>
Change the "x-pixman" property default value and use the fallback path
when PIXMAN support is disabled.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/display/ati.c | 16 +++++++++++++++-
hw/display/ati_2d.c | 11 +++++++----
hw/display/meson.build | 2 +-
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 9a87a5504a..51a3b156ac 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -32,6 +32,13 @@
#define ATI_DEBUG_HW_CURSOR 0
+#ifdef CONFIG_PIXMAN
+#define DEFAULT_X_PIXMAN 3
+#else
+#define DEFAULT_X_PIXMAN 0
+#endif
+
+
static const struct {
const char *name;
uint16_t dev_id;
@@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
ATIVGAState *s = ATI_VGA(dev);
VGACommonState *vga = &s->vga;
+#ifndef CONFIG_PIXMAN
+ if (s->use_pixman != 0) {
+ warn_report("x-pixman != 0, not effective without PIXMAN");
+ }
+#endif
+
if (s->model) {
int i;
for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
@@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = {
DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
PCI_DEVICE_ID_ATI_RAGE128_PF),
DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
- DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
+ /* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */
+ DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 0e6b8e4367..e58acd0802 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
case ROP3_SRCCOPY:
{
- bool fallback = false;
+ bool fallback = true;
unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
@@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s)
src_stride /= sizeof(uint32_t);
dst_stride /= sizeof(uint32_t);
+#ifdef CONFIG_PIXMAN
DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
@@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s)
s->regs.dst_width, s->regs.dst_height);
}
g_free(tmp);
- } else {
- fallback = true;
}
+#endif
if (fallback) {
unsigned int y, i, j, bypp = bpp / 8;
unsigned int src_pitch = src_stride * sizeof(uint32_t);
@@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s)
}
dst_stride /= sizeof(uint32_t);
+#ifdef CONFIG_PIXMAN
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
dst_bits, dst_stride, bpp, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height, filler);
if (!(s->use_pixman & BIT(0)) ||
!pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
- s->regs.dst_width, s->regs.dst_height, filler)) {
+ s->regs.dst_width, s->regs.dst_height, filler))
+#endif
+ {
/* fallback when pixman failed or we don't want to call it */
unsigned int x, y, i, bypp = bpp / 8;
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
diff --git a/hw/display/meson.build b/hw/display/meson.build
index 9c06aaee20..344dfe3d8c 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c'))
system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
-system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c'))
+system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
--
2.41.0
On Tue, 7 Nov 2023, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Change the "x-pixman" property default value and use the fallback path
> when PIXMAN support is disabled.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hw/display/ati.c | 16 +++++++++++++++-
> hw/display/ati_2d.c | 11 +++++++----
> hw/display/meson.build | 2 +-
> 3 files changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/hw/display/ati.c b/hw/display/ati.c
> index 9a87a5504a..51a3b156ac 100644
> --- a/hw/display/ati.c
> +++ b/hw/display/ati.c
> @@ -32,6 +32,13 @@
>
> #define ATI_DEBUG_HW_CURSOR 0
>
> +#ifdef CONFIG_PIXMAN
> +#define DEFAULT_X_PIXMAN 3
> +#else
> +#define DEFAULT_X_PIXMAN 0
> +#endif
> +
> +
Excess new line.
> static const struct {
> const char *name;
> uint16_t dev_id;
> @@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
> ATIVGAState *s = ATI_VGA(dev);
> VGACommonState *vga = &s->vga;
>
> +#ifndef CONFIG_PIXMAN
> + if (s->use_pixman != 0) {
> + warn_report("x-pixman != 0, not effective without PIXMAN");
> + }
> +#endif
> +
> if (s->model) {
> int i;
> for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
> @@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = {
> DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
> PCI_DEVICE_ID_ATI_RAGE128_PF),
> DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
> - DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
> + /* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */
Comment not needed but if you still want it, should be "this is a debug..."
> + DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN),
> DEFINE_PROP_END_OF_LIST()
> };
>
> diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
> index 0e6b8e4367..e58acd0802 100644
> --- a/hw/display/ati_2d.c
> +++ b/hw/display/ati_2d.c
> @@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
> switch (s->regs.dp_mix & GMC_ROP3_MASK) {
> case ROP3_SRCCOPY:
> {
> - bool fallback = false;
> + bool fallback = true;
> unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
> s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
> unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
> @@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s)
>
> src_stride /= sizeof(uint32_t);
> dst_stride /= sizeof(uint32_t);
> +#ifdef CONFIG_PIXMAN
> DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
> src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
> src_x, src_y, dst_x, dst_y,
Keep debug log even without pixman so move ifdef after it (also below) as
this provides info on the operation even if done by fallback.
> @@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s)
> s->regs.dst_width, s->regs.dst_height);
> }
> g_free(tmp);
> - } else {
> - fallback = true;
> }
If you cahnge default value to true this is not needed any more but for
consistency with sm501 you could keep default and put this outside of
#idfef instead so it's the same as sm501 or do the same there.
> +#endif
> if (fallback) {
> unsigned int y, i, j, bypp = bpp / 8;
> unsigned int src_pitch = src_stride * sizeof(uint32_t);
> @@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s)
> }
>
> dst_stride /= sizeof(uint32_t);
> +#ifdef CONFIG_PIXMAN
> DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
> dst_bits, dst_stride, bpp, dst_x, dst_y,
> s->regs.dst_width, s->regs.dst_height, filler);
Move ifdef here.
With these
Acked-by: BALATON Zoltan <balaton@eik.bme.hu>
Thanks for doing this in last minute.
Regards,
BALATON Zoltan
> if (!(s->use_pixman & BIT(0)) ||
> !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
> - s->regs.dst_width, s->regs.dst_height, filler)) {
> + s->regs.dst_width, s->regs.dst_height, filler))
> +#endif
> + {
> /* fallback when pixman failed or we don't want to call it */
> unsigned int x, y, i, bypp = bpp / 8;
> unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
> diff --git a/hw/display/meson.build b/hw/display/meson.build
> index 9c06aaee20..344dfe3d8c 100644
> --- a/hw/display/meson.build
> +++ b/hw/display/meson.build
> @@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c'))
>
> system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
>
> -system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c'))
> +system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
>
>
> if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
>
Hi
On Tue, Nov 7, 2023 at 12:46 PM BALATON Zoltan <balaton@eik.bme.hu> wrote:
>
> On Tue, 7 Nov 2023, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Change the "x-pixman" property default value and use the fallback path
> > when PIXMAN support is disabled.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > hw/display/ati.c | 16 +++++++++++++++-
> > hw/display/ati_2d.c | 11 +++++++----
> > hw/display/meson.build | 2 +-
> > 3 files changed, 23 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/display/ati.c b/hw/display/ati.c
> > index 9a87a5504a..51a3b156ac 100644
> > --- a/hw/display/ati.c
> > +++ b/hw/display/ati.c
> > @@ -32,6 +32,13 @@
> >
> > #define ATI_DEBUG_HW_CURSOR 0
> >
> > +#ifdef CONFIG_PIXMAN
> > +#define DEFAULT_X_PIXMAN 3
> > +#else
> > +#define DEFAULT_X_PIXMAN 0
> > +#endif
> > +
> > +
>
> Excess new line.
ok
>
> > static const struct {
> > const char *name;
> > uint16_t dev_id;
> > @@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
> > ATIVGAState *s = ATI_VGA(dev);
> > VGACommonState *vga = &s->vga;
> >
> > +#ifndef CONFIG_PIXMAN
> > + if (s->use_pixman != 0) {
> > + warn_report("x-pixman != 0, not effective without PIXMAN");
> > + }
> > +#endif
> > +
> > if (s->model) {
> > int i;
> > for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
> > @@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = {
> > DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
> > PCI_DEVICE_ID_ATI_RAGE128_PF),
> > DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
> > - DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
> > + /* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */
>
> Comment not needed but if you still want it, should be "this is a debug..."
indeed
>
> > + DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN),
> > DEFINE_PROP_END_OF_LIST()
> > };
> >
> > diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
> > index 0e6b8e4367..e58acd0802 100644
> > --- a/hw/display/ati_2d.c
> > +++ b/hw/display/ati_2d.c
> > @@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
> > switch (s->regs.dp_mix & GMC_ROP3_MASK) {
> > case ROP3_SRCCOPY:
> > {
> > - bool fallback = false;
> > + bool fallback = true;
> > unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
> > s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
> > unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
> > @@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s)
> >
> > src_stride /= sizeof(uint32_t);
> > dst_stride /= sizeof(uint32_t);
> > +#ifdef CONFIG_PIXMAN
> > DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
> > src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
> > src_x, src_y, dst_x, dst_y,
>
> Keep debug log even without pixman so move ifdef after it (also below) as
> this provides info on the operation even if done by fallback.
ok
>
> > @@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s)
> > s->regs.dst_width, s->regs.dst_height);
> > }
> > g_free(tmp);
> > - } else {
> > - fallback = true;
> > }
>
> If you cahnge default value to true this is not needed any more but for
> consistency with sm501 you could keep default and put this outside of
> #idfef instead so it's the same as sm501 or do the same there.
ok, and fixing the fallback=true case in my sm501 patch while at it.
>
> > +#endif
> > if (fallback) {
> > unsigned int y, i, j, bypp = bpp / 8;
> > unsigned int src_pitch = src_stride * sizeof(uint32_t);
> > @@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s)
> > }
> >
> > dst_stride /= sizeof(uint32_t);
> > +#ifdef CONFIG_PIXMAN
> > DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
> > dst_bits, dst_stride, bpp, dst_x, dst_y,
> > s->regs.dst_width, s->regs.dst_height, filler);
>
> Move ifdef here.
>
> With these
>
> Acked-by: BALATON Zoltan <balaton@eik.bme.hu>
>
> Thanks for doing this in last minute.
thanks for the quick review!
>
> Regards,
> BALATON Zoltan
>
> > if (!(s->use_pixman & BIT(0)) ||
> > !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
> > - s->regs.dst_width, s->regs.dst_height, filler)) {
> > + s->regs.dst_width, s->regs.dst_height, filler))
> > +#endif
> > + {
> > /* fallback when pixman failed or we don't want to call it */
> > unsigned int x, y, i, bypp = bpp / 8;
> > unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
> > diff --git a/hw/display/meson.build b/hw/display/meson.build
> > index 9c06aaee20..344dfe3d8c 100644
> > --- a/hw/display/meson.build
> > +++ b/hw/display/meson.build
> > @@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c'))
> >
> > system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
> >
> > -system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c'))
> > +system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
> >
> >
> > if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
> >
HI Zoltan
On Tue, Nov 7, 2023 at 11:21 AM <marcandre.lureau@redhat.com> wrote:
>
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Change the "x-pixman" property default value and use the fallback path
> when PIXMAN support is disabled.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
please review today :) thanks
> ---
> hw/display/ati.c | 16 +++++++++++++++-
> hw/display/ati_2d.c | 11 +++++++----
> hw/display/meson.build | 2 +-
> 3 files changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/hw/display/ati.c b/hw/display/ati.c
> index 9a87a5504a..51a3b156ac 100644
> --- a/hw/display/ati.c
> +++ b/hw/display/ati.c
> @@ -32,6 +32,13 @@
>
> #define ATI_DEBUG_HW_CURSOR 0
>
> +#ifdef CONFIG_PIXMAN
> +#define DEFAULT_X_PIXMAN 3
> +#else
> +#define DEFAULT_X_PIXMAN 0
> +#endif
> +
> +
> static const struct {
> const char *name;
> uint16_t dev_id;
> @@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
> ATIVGAState *s = ATI_VGA(dev);
> VGACommonState *vga = &s->vga;
>
> +#ifndef CONFIG_PIXMAN
> + if (s->use_pixman != 0) {
> + warn_report("x-pixman != 0, not effective without PIXMAN");
> + }
> +#endif
> +
> if (s->model) {
> int i;
> for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
> @@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = {
> DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
> PCI_DEVICE_ID_ATI_RAGE128_PF),
> DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
> - DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
> + /* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */
> + DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN),
> DEFINE_PROP_END_OF_LIST()
> };
>
> diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
> index 0e6b8e4367..e58acd0802 100644
> --- a/hw/display/ati_2d.c
> +++ b/hw/display/ati_2d.c
> @@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
> switch (s->regs.dp_mix & GMC_ROP3_MASK) {
> case ROP3_SRCCOPY:
> {
> - bool fallback = false;
> + bool fallback = true;
> unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
> s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
> unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
> @@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s)
>
> src_stride /= sizeof(uint32_t);
> dst_stride /= sizeof(uint32_t);
> +#ifdef CONFIG_PIXMAN
> DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
> src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
> src_x, src_y, dst_x, dst_y,
> @@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s)
> s->regs.dst_width, s->regs.dst_height);
> }
> g_free(tmp);
> - } else {
> - fallback = true;
> }
> +#endif
> if (fallback) {
> unsigned int y, i, j, bypp = bpp / 8;
> unsigned int src_pitch = src_stride * sizeof(uint32_t);
> @@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s)
> }
>
> dst_stride /= sizeof(uint32_t);
> +#ifdef CONFIG_PIXMAN
> DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
> dst_bits, dst_stride, bpp, dst_x, dst_y,
> s->regs.dst_width, s->regs.dst_height, filler);
> if (!(s->use_pixman & BIT(0)) ||
> !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
> - s->regs.dst_width, s->regs.dst_height, filler)) {
> + s->regs.dst_width, s->regs.dst_height, filler))
> +#endif
> + {
> /* fallback when pixman failed or we don't want to call it */
> unsigned int x, y, i, bypp = bpp / 8;
> unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
> diff --git a/hw/display/meson.build b/hw/display/meson.build
> index 9c06aaee20..344dfe3d8c 100644
> --- a/hw/display/meson.build
> +++ b/hw/display/meson.build
> @@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c'))
>
> system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
>
> -system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c'))
> +system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
>
>
> if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
> --
> 2.41.0
>
© 2016 - 2026 Red Hat, Inc.