Patchwork [2/2] Xen: Add xen-apic support and hook it up.

login
register
mail settings
Submitter Wei Liu
Date April 5, 2012, 9:35 a.m.
Message ID <1333618505.2513.8.camel@leeds.uk.xensource.com>
Download mbox | patch
Permalink /patch/150903/
State New
Headers show

Comments

Wei Liu - April 5, 2012, 9:35 a.m.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 Makefile.target |    2 +-
 hw/pc.c         |    8 +++++
 hw/xen_apic.c   |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 1 deletions(-)
 create mode 100644 hw/xen_apic.c
Jan Kiszka - April 11, 2012, 4:01 p.m.
On 2012-04-11 18:02, Stefano Stabellini wrote:
> Jan, Anthony, any opinions on this patch?
> If it is OK for you, I am going to include it in the next Xen pull request.
> 

Looks good to me.

Jan

> 
> On Thu, 5 Apr 2012, Wei Liu (Intern) wrote:
>>
>> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  Makefile.target |    2 +-
>>  hw/pc.c         |    8 +++++
>>  hw/xen_apic.c   |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 99 insertions(+), 1 deletions(-)
>>  create mode 100644 hw/xen_apic.c
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index cff15f0..6210bae 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -235,7 +235,7 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>>  obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
>>  obj-$(CONFIG_NO_XEN) += xen-stub.o
>>  
>> -obj-i386-$(CONFIG_XEN) += xen_platform.o
>> +obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o
>>  
>>  # Inter-VM PCI shared memory
>>  CONFIG_IVSHMEM =
>> diff --git a/hw/pc.c b/hw/pc.c
>> index 83a1b5b..5585cac 100644
>> --- a/hw/pc.c
>> +++ b/hw/pc.c
>> @@ -42,6 +42,7 @@
>>  #include "sysbus.h"
>>  #include "sysemu.h"
>>  #include "kvm.h"
>> +#include "xen.h"
>>  #include "blockdev.h"
>>  #include "ui/qemu-spice.h"
>>  #include "memory.h"
>> @@ -891,9 +892,12 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
>>  
>>      if (kvm_irqchip_in_kernel()) {
>>          dev = qdev_create(NULL, "kvm-apic");
>> +    } else if (xen_enabled()) {
>> +        dev = qdev_create(NULL, "xen-apic");
>>      } else {
>>          dev = qdev_create(NULL, "apic");
>>      }
>> +
>>      qdev_prop_set_uint8(dev, "id", apic_id);
>>      qdev_prop_set_ptr(dev, "cpu_env", env);
>>      qdev_init_nofail(dev);
>> @@ -912,6 +916,10 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
>>          msi_supported = true;
>>      }
>>  
>> +    if (xen_enabled()) {
>> +        msi_supported = true;
>> +    }
>> +
>>      return dev;
>>  }
>>  
>> diff --git a/hw/xen_apic.c b/hw/xen_apic.c
>> new file mode 100644
>> index 0000000..b1060b7
>> --- /dev/null
>> +++ b/hw/xen_apic.c
>> @@ -0,0 +1,90 @@
>> +/*
>> + * Xen basic APIC support
>> + *
>> + * Copyright (c) 2012 Citrix
>> + *
>> + * Authors:
>> + *  Wei Liu <wei.liu2@citrix.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL version 2.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +#include "hw/apic_internal.h"
>> +#include "hw/msi.h"
>> +#include "xen.h"
>> +
>> +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
>> +                                  unsigned size)
>> +{
>> +    return -1U;
>> +}
>> +
>> +static void xen_apic_mem_write(void *opaque, target_phys_addr_t addr,
>> +                               uint64_t data, unsigned size)
>> +{
>> +    if (size != sizeof(uint32_t)) {
>> +        fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size);
>> +        return;
>> +    }
>> +
>> +    xen_hvm_inject_msi(addr, data);
>> +}
>> +
>> +static const MemoryRegionOps xen_apic_io_ops = {
>> +    .read = xen_apic_mem_read,
>> +    .write = xen_apic_mem_write,
>> +    .endianness = DEVICE_NATIVE_ENDIAN,
>> +};
>> +
>> +static void xen_apic_init(APICCommonState *s)
>> +{
>> +    memory_region_init_io(&s->io_memory, &xen_apic_io_ops, s, "xen-apic-msi",
>> +                          MSI_SPACE_SIZE);
>> +}
>> +
>> +static void xen_apic_set_base(APICCommonState *s, uint64_t val)
>> +{
>> +}
>> +
>> +static void xen_apic_set_tpr(APICCommonState *s, uint8_t val)
>> +{
>> +}
>> +
>> +static uint8_t xen_apic_get_tpr(APICCommonState *s)
>> +{
>> +    return 0;
>> +}
>> +
>> +static void xen_apic_vapic_base_update(APICCommonState *s)
>> +{
>> +}
>> +
>> +static void xen_apic_external_nmi(APICCommonState *s)
>> +{
>> +}
>> +
>> +static void xen_apic_class_init(ObjectClass *klass, void *data)
>> +{
>> +    APICCommonClass *k = APIC_COMMON_CLASS(klass);
>> +
>> +    k->init = xen_apic_init;
>> +    k->set_base = xen_apic_set_base;
>> +    k->set_tpr = xen_apic_set_tpr;
>> +    k->get_tpr = xen_apic_get_tpr;
>> +    k->vapic_base_update = xen_apic_vapic_base_update;
>> +    k->external_nmi = xen_apic_external_nmi;
>> +}
>> +
>> +static TypeInfo xen_apic_info = {
>> +    .name = "xen-apic",
>> +    .parent = TYPE_APIC_COMMON,
>> +    .instance_size = sizeof(APICCommonState),
>> +    .class_init = xen_apic_class_init,
>> +};
>> +
>> +static void xen_apic_register_types(void)
>> +{
>> +    type_register_static(&xen_apic_info);
>> +}
>> +
>> +type_init(xen_apic_register_types)
>> -- 
>> 1.7.2.5
>>
>>
>>
>>
>>
Stefano Stabellini - April 11, 2012, 4:02 p.m.
Jan, Anthony, any opinions on this patch?
If it is OK for you, I am going to include it in the next Xen pull request.


On Thu, 5 Apr 2012, Wei Liu (Intern) wrote:
> 
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
>  Makefile.target |    2 +-
>  hw/pc.c         |    8 +++++
>  hw/xen_apic.c   |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+), 1 deletions(-)
>  create mode 100644 hw/xen_apic.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index cff15f0..6210bae 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -235,7 +235,7 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>  obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
>  obj-$(CONFIG_NO_XEN) += xen-stub.o
>  
> -obj-i386-$(CONFIG_XEN) += xen_platform.o
> +obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o
>  
>  # Inter-VM PCI shared memory
>  CONFIG_IVSHMEM =
> diff --git a/hw/pc.c b/hw/pc.c
> index 83a1b5b..5585cac 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -42,6 +42,7 @@
>  #include "sysbus.h"
>  #include "sysemu.h"
>  #include "kvm.h"
> +#include "xen.h"
>  #include "blockdev.h"
>  #include "ui/qemu-spice.h"
>  #include "memory.h"
> @@ -891,9 +892,12 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
>  
>      if (kvm_irqchip_in_kernel()) {
>          dev = qdev_create(NULL, "kvm-apic");
> +    } else if (xen_enabled()) {
> +        dev = qdev_create(NULL, "xen-apic");
>      } else {
>          dev = qdev_create(NULL, "apic");
>      }
> +
>      qdev_prop_set_uint8(dev, "id", apic_id);
>      qdev_prop_set_ptr(dev, "cpu_env", env);
>      qdev_init_nofail(dev);
> @@ -912,6 +916,10 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
>          msi_supported = true;
>      }
>  
> +    if (xen_enabled()) {
> +        msi_supported = true;
> +    }
> +
>      return dev;
>  }
>  
> diff --git a/hw/xen_apic.c b/hw/xen_apic.c
> new file mode 100644
> index 0000000..b1060b7
> --- /dev/null
> +++ b/hw/xen_apic.c
> @@ -0,0 +1,90 @@
> +/*
> + * Xen basic APIC support
> + *
> + * Copyright (c) 2012 Citrix
> + *
> + * Authors:
> + *  Wei Liu <wei.liu2@citrix.com>
> + *
> + * This work is licensed under the terms of the GNU GPL version 2.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "hw/apic_internal.h"
> +#include "hw/msi.h"
> +#include "xen.h"
> +
> +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
> +                                  unsigned size)
> +{
> +    return -1U;
> +}
> +
> +static void xen_apic_mem_write(void *opaque, target_phys_addr_t addr,
> +                               uint64_t data, unsigned size)
> +{
> +    if (size != sizeof(uint32_t)) {
> +        fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size);
> +        return;
> +    }
> +
> +    xen_hvm_inject_msi(addr, data);
> +}
> +
> +static const MemoryRegionOps xen_apic_io_ops = {
> +    .read = xen_apic_mem_read,
> +    .write = xen_apic_mem_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void xen_apic_init(APICCommonState *s)
> +{
> +    memory_region_init_io(&s->io_memory, &xen_apic_io_ops, s, "xen-apic-msi",
> +                          MSI_SPACE_SIZE);
> +}
> +
> +static void xen_apic_set_base(APICCommonState *s, uint64_t val)
> +{
> +}
> +
> +static void xen_apic_set_tpr(APICCommonState *s, uint8_t val)
> +{
> +}
> +
> +static uint8_t xen_apic_get_tpr(APICCommonState *s)
> +{
> +    return 0;
> +}
> +
> +static void xen_apic_vapic_base_update(APICCommonState *s)
> +{
> +}
> +
> +static void xen_apic_external_nmi(APICCommonState *s)
> +{
> +}
> +
> +static void xen_apic_class_init(ObjectClass *klass, void *data)
> +{
> +    APICCommonClass *k = APIC_COMMON_CLASS(klass);
> +
> +    k->init = xen_apic_init;
> +    k->set_base = xen_apic_set_base;
> +    k->set_tpr = xen_apic_set_tpr;
> +    k->get_tpr = xen_apic_get_tpr;
> +    k->vapic_base_update = xen_apic_vapic_base_update;
> +    k->external_nmi = xen_apic_external_nmi;
> +}
> +
> +static TypeInfo xen_apic_info = {
> +    .name = "xen-apic",
> +    .parent = TYPE_APIC_COMMON,
> +    .instance_size = sizeof(APICCommonState),
> +    .class_init = xen_apic_class_init,
> +};
> +
> +static void xen_apic_register_types(void)
> +{
> +    type_register_static(&xen_apic_info);
> +}
> +
> +type_init(xen_apic_register_types)
> -- 
> 1.7.2.5
> 
> 
> 
> 
>
Peter Maydell - April 11, 2012, 4:07 p.m.
On 5 April 2012 10:35, Wei Liu <wei.liu2@citrix.com> wrote:
>
> --- /dev/null
> +++ b/hw/xen_apic.c
> @@ -0,0 +1,90 @@
> +/*
> + * Xen basic APIC support
> + *
> + * Copyright (c) 2012 Citrix
> + *
> + * Authors:
> + *  Wei Liu <wei.liu2@citrix.com>
> + *
> + * This work is licensed under the terms of the GNU GPL version 2.
> + * See the COPYING file in the top-level directory.
> + */

Really 2-only, not 2-or-later ?

> +#include "hw/apic_internal.h"
> +#include "hw/msi.h"
> +#include "xen.h"
> +
> +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
> +                                  unsigned size)
> +{
> +    return -1U;
> +}

This seems a rather confusing way to write 'return 0xffffffff;'

-- PMM
Jan Kiszka - April 11, 2012, 4:13 p.m.
On 2012-04-11 18:07, Peter Maydell wrote:
>> +#include "hw/apic_internal.h"
>> +#include "hw/msi.h"
>> +#include "xen.h"
>> +
>> +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
>> +                                  unsigned size)
>> +{
>> +    return -1U;
>> +}
> 
> This seems a rather confusing way to write 'return 0xffffffff;'

You mean 0xffffffffffffffff? :)

Jan
Stefano Stabellini - April 11, 2012, 4:17 p.m.
On Wed, 11 Apr 2012, Peter Maydell wrote:
> On 5 April 2012 10:35, Wei Liu <wei.liu2@citrix.com> wrote:
> >
> > --- /dev/null
> > +++ b/hw/xen_apic.c
> > @@ -0,0 +1,90 @@
> > +/*
> > + * Xen basic APIC support
> > + *
> > + * Copyright (c) 2012 Citrix
> > + *
> > + * Authors:
> > + *  Wei Liu <wei.liu2@citrix.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL version 2.
> > + * See the COPYING file in the top-level directory.
> > + */
> 
> Really 2-only, not 2-or-later ?

I am not a great fun of the 2-or-later clause and it doesn't look like a
requirement from the QEMU project POV. However if it is, I'll change it
to 2-or-later.


> > +#include "hw/apic_internal.h"
> > +#include "hw/msi.h"
> > +#include "xen.h"
> > +
> > +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
> > +                                  unsigned size)
> > +{
> > +    return -1U;
> > +}
> 
> This seems a rather confusing way to write 'return 0xffffffff;'
 
Yep, I'll change it.
Stefano Stabellini - April 11, 2012, 4:19 p.m.
On Wed, 11 Apr 2012, Stefano Stabellini wrote:
> On Wed, 11 Apr 2012, Peter Maydell wrote:
> > On 5 April 2012 10:35, Wei Liu <wei.liu2@citrix.com> wrote:
> > >
> > > --- /dev/null
> > > +++ b/hw/xen_apic.c
> > > @@ -0,0 +1,90 @@
> > > +/*
> > > + * Xen basic APIC support
> > > + *
> > > + * Copyright (c) 2012 Citrix
> > > + *
> > > + * Authors:
> > > + *  Wei Liu <wei.liu2@citrix.com>
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL version 2.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > 
> > Really 2-only, not 2-or-later ?
> 
> I am not a great fun of the 2-or-later clause and it doesn't look like a
> requirement from the QEMU project POV. However if it is, I'll change it
> to 2-or-later.
> 
> 
> > > +#include "hw/apic_internal.h"
> > > +#include "hw/msi.h"
> > > +#include "xen.h"
> > > +
> > > +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
> > > +                                  unsigned size)
> > > +{
> > > +    return -1U;
> > > +}
> > 
> > This seems a rather confusing way to write 'return 0xffffffff;'
>  
> Yep, I'll change it.

Actually it is a uint64 so it is a lot of f's
Peter Maydell - April 11, 2012, 4:23 p.m.
On 11 April 2012 17:13, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2012-04-11 18:07, Peter Maydell wrote:
>>> +#include "hw/apic_internal.h"
>>> +#include "hw/msi.h"
>>> +#include "xen.h"
>>> +
>>> +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
>>> +                                  unsigned size)
>>> +{
>>> +    return -1U;
>>> +}
>>
>> This seems a rather confusing way to write 'return 0xffffffff;'
>
> You mean 0xffffffffffffffff? :)

No, that's why it's confusing :-)

1U is the integer constant 1 with a type of 'unsigned int'
(cf C99 section 6.4.4.1). It then has the unary negation
operator applied to it, giving (for the usual 32 bit integer
case) 0xffffffff. This is then cast from 'unsigned int'
to 'uint64_t' giving 0xffffffff as a 64 bit unsigned value.

(I had to write a test program to (a) confirm what it was
going to return and (b) that it would be the same thing on
both 32 and 64 bit systems...)

I have no opinion on what the return value actually ought
to be.

-- PMM
Eric Blake - April 11, 2012, 5:02 p.m.
On 04/11/2012 10:17 AM, Stefano Stabellini wrote:
> On Wed, 11 Apr 2012, Peter Maydell wrote:
>> On 5 April 2012 10:35, Wei Liu <wei.liu2@citrix.com> wrote:
>>>
>>> --- /dev/null
>>> +++ b/hw/xen_apic.c
>>> @@ -0,0 +1,90 @@
>>> +/*
>>> + * Xen basic APIC support
>>> + *
>>> + * Copyright (c) 2012 Citrix
>>> + *
>>> + * Authors:
>>> + *  Wei Liu <wei.liu2@citrix.com>
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL version 2.
>>> + * See the COPYING file in the top-level directory.
>>> + */
>>
>> Really 2-only, not 2-or-later ?
> 
> I am not a great fun of the 2-or-later clause and it doesn't look like a
> requirement from the QEMU project POV. However if it is, I'll change it
> to 2-or-later.

Conversely, I am not a great fan of the 2-only clause, as it prevents
reuse of qemu code in other projects.  There's a reason that qemu is now
favoring 2-or-later for new submissions.

http://wiki.qemu.org/Relicensing
Paolo Bonzini - April 11, 2012, 9:37 p.m.
Il 11/04/2012 18:17, Stefano Stabellini ha scritto:
>> > Really 2-only, not 2-or-later ?
> I am not a great fun of the 2-or-later clause and it doesn't look like a
> requirement from the QEMU project POV. However if it is, I'll change it
> to 2-or-later.

OT fun fact: did you know that MPL comes with an or-later clause that
(unlike the GPL) you cannot reject?

So much for "weak" copyleft.

Paolo
Wei Liu - April 12, 2012, 3:23 a.m.
On Thu, Apr 12, 2012 at 1:02 AM, Eric Blake <eblake@redhat.com> wrote:
> On 04/11/2012 10:17 AM, Stefano Stabellini wrote:
>> On Wed, 11 Apr 2012, Peter Maydell wrote:
>>> On 5 April 2012 10:35, Wei Liu <wei.liu2@citrix.com> wrote:
>>>>
>>>> --- /dev/null
>>>> +++ b/hw/xen_apic.c
>>>> @@ -0,0 +1,90 @@
>>>> +/*
>>>> + * Xen basic APIC support
>>>> + *
>>>> + * Copyright (c) 2012 Citrix
>>>> + *
>>>> + * Authors:
>>>> + *  Wei Liu <wei.liu2@citrix.com>
>>>> + *
>>>> + * This work is licensed under the terms of the GNU GPL version 2.
>>>> + * See the COPYING file in the top-level directory.
>>>> + */
>>>
>>> Really 2-only, not 2-or-later ?
>>
>> I am not a great fun of the 2-or-later clause and it doesn't look like a
>> requirement from the QEMU project POV. However if it is, I'll change it
>> to 2-or-later.
>
> Conversely, I am not a great fan of the 2-only clause, as it prevents
> reuse of qemu code in other projects.  There's a reason that qemu is now
> favoring 2-or-later for new submissions.
>
> http://wiki.qemu.org/Relicensing
>

I don't mind changing the licensing to 2-or-later for greater benefit.

Stefano, please do whatever you need to.


Wei.

> --
> Eric Blake   eblake@redhat.com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>

Patch

diff --git a/Makefile.target b/Makefile.target
index cff15f0..6210bae 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -235,7 +235,7 @@  QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
 obj-$(CONFIG_NO_XEN) += xen-stub.o
 
-obj-i386-$(CONFIG_XEN) += xen_platform.o
+obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 
 # Inter-VM PCI shared memory
 CONFIG_IVSHMEM =
diff --git a/hw/pc.c b/hw/pc.c
index 83a1b5b..5585cac 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -42,6 +42,7 @@ 
 #include "sysbus.h"
 #include "sysemu.h"
 #include "kvm.h"
+#include "xen.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
 #include "memory.h"
@@ -891,9 +892,12 @@  static DeviceState *apic_init(void *env, uint8_t apic_id)
 
     if (kvm_irqchip_in_kernel()) {
         dev = qdev_create(NULL, "kvm-apic");
+    } else if (xen_enabled()) {
+        dev = qdev_create(NULL, "xen-apic");
     } else {
         dev = qdev_create(NULL, "apic");
     }
+
     qdev_prop_set_uint8(dev, "id", apic_id);
     qdev_prop_set_ptr(dev, "cpu_env", env);
     qdev_init_nofail(dev);
@@ -912,6 +916,10 @@  static DeviceState *apic_init(void *env, uint8_t apic_id)
         msi_supported = true;
     }
 
+    if (xen_enabled()) {
+        msi_supported = true;
+    }
+
     return dev;
 }
 
diff --git a/hw/xen_apic.c b/hw/xen_apic.c
new file mode 100644
index 0000000..b1060b7
--- /dev/null
+++ b/hw/xen_apic.c
@@ -0,0 +1,90 @@ 
+/*
+ * Xen basic APIC support
+ *
+ * Copyright (c) 2012 Citrix
+ *
+ * Authors:
+ *  Wei Liu <wei.liu2@citrix.com>
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+#include "hw/apic_internal.h"
+#include "hw/msi.h"
+#include "xen.h"
+
+static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
+{
+    return -1U;
+}
+
+static void xen_apic_mem_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    if (size != sizeof(uint32_t)) {
+        fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size);
+        return;
+    }
+
+    xen_hvm_inject_msi(addr, data);
+}
+
+static const MemoryRegionOps xen_apic_io_ops = {
+    .read = xen_apic_mem_read,
+    .write = xen_apic_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void xen_apic_init(APICCommonState *s)
+{
+    memory_region_init_io(&s->io_memory, &xen_apic_io_ops, s, "xen-apic-msi",
+                          MSI_SPACE_SIZE);
+}
+
+static void xen_apic_set_base(APICCommonState *s, uint64_t val)
+{
+}
+
+static void xen_apic_set_tpr(APICCommonState *s, uint8_t val)
+{
+}
+
+static uint8_t xen_apic_get_tpr(APICCommonState *s)
+{
+    return 0;
+}
+
+static void xen_apic_vapic_base_update(APICCommonState *s)
+{
+}
+
+static void xen_apic_external_nmi(APICCommonState *s)
+{
+}
+
+static void xen_apic_class_init(ObjectClass *klass, void *data)
+{
+    APICCommonClass *k = APIC_COMMON_CLASS(klass);
+
+    k->init = xen_apic_init;
+    k->set_base = xen_apic_set_base;
+    k->set_tpr = xen_apic_set_tpr;
+    k->get_tpr = xen_apic_get_tpr;
+    k->vapic_base_update = xen_apic_vapic_base_update;
+    k->external_nmi = xen_apic_external_nmi;
+}
+
+static TypeInfo xen_apic_info = {
+    .name = "xen-apic",
+    .parent = TYPE_APIC_COMMON,
+    .instance_size = sizeof(APICCommonState),
+    .class_init = xen_apic_class_init,
+};
+
+static void xen_apic_register_types(void)
+{
+    type_register_static(&xen_apic_info);
+}
+
+type_init(xen_apic_register_types)