aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-04-30 09:16:15 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-04-30 09:16:15 +0100
commit013351bd7ab3e35717e0133b5f44f82efd6a5d28 (patch)
tree07939fd55c2d3554fa6d89d443d01a1a4427b6fa
parent4fabe234e8d2895bd2f49d43263f3dafb4658695 (diff)
downloadxen-013351bd7ab3e35717e0133b5f44f82efd6a5d28.tar.gz
xen-013351bd7ab3e35717e0133b5f44f82efd6a5d28.tar.bz2
xen-013351bd7ab3e35717e0133b5f44f82efd6a5d28.zip
Define new event-channel and physdev hypercalls with a more extensible
interface (the legacy hypercalls would break if subcommands with large argument structures were added, as it would grow the size of the union of all argument structures). Also, based on a patch from Kevin Tian, add a new physdev op to signal EOI for a particular irq. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c35
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c9
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c26
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c7
-rw-r--r--linux-2.6-xen-sparse/arch/ia64/Kconfig2
-rw-r--r--linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c31
-rw-r--r--linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c25
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c35
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c9
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c26
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c7
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/Kconfig2
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/blkback/interface.c13
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/blktap/interface.c13
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/core/evtchn.c109
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c47
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/netback/interface.c13
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c2
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c15
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c46
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c12
-rw-r--r--linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h22
-rw-r--r--linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h2
-rw-r--r--linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h7
-rw-r--r--linux-2.6-xen-sparse/include/asm-ia64/hypercall.h22
-rw-r--r--linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h2
-rw-r--r--linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h22
-rw-r--r--linux-2.6-xen-sparse/include/xen/evtchn.h6
-rw-r--r--tools/libxc/xc_evtchn.c37
-rw-r--r--xen/arch/ia64/vmx/vmx_hypercall.c4
-rw-r--r--xen/arch/ia64/vmx/vmx_ivt.S2
-rw-r--r--xen/arch/ia64/xen/hypercall.c119
-rw-r--r--xen/arch/ia64/xen/irq.c34
-rw-r--r--xen/arch/x86/Makefile1
-rw-r--r--xen/arch/x86/compat.c32
-rw-r--r--xen/arch/x86/irq.c97
-rw-r--r--xen/arch/x86/physdev.c118
-rw-r--r--xen/arch/x86/x86_32/entry.S12
-rw-r--r--xen/arch/x86/x86_64/entry.S12
-rw-r--r--xen/common/event_channel.c123
-rw-r--r--xen/include/acm/acm_hooks.h24
-rw-r--r--xen/include/asm-ia64/hypercall.h4
-rw-r--r--xen/include/asm-x86/hypercall.h10
-rw-r--r--xen/include/public/event_channel.h11
-rw-r--r--xen/include/public/physdev.h120
-rw-r--r--xen/include/public/xen-compat.h10
-rw-r--r--xen/include/public/xen.h8
-rw-r--r--xen/include/xen/hypercall.h3
-rw-r--r--xen/include/xen/irq.h7
49 files changed, 837 insertions, 518 deletions
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
index cf0e62c5ff..e7e1aa834a 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
@@ -57,27 +57,25 @@ unsigned long io_apic_irqs;
static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;
- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}
static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = value;
- HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}
#define io_apic_read(a,r) xen_io_apic_read(a,r)
@@ -1205,22 +1203,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; *
int assign_irq_vector(int irq)
{
- physdev_op_t op;
+ struct physdev_irq irq_op;
BUG_ON(irq >= NR_IRQ_VECTORS);
if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
return IO_APIC_VECTOR(irq);
- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;
- vector_irq[op.u.irq_op.vector] = irq;
+ vector_irq[irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+ IO_APIC_VECTOR(irq) = irq_op.vector;
- return op.u.irq_op.vector;
+ return irq_op.vector;
}
#ifndef CONFIG_XEN
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c
index fe395b146c..ee66fc288b 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c
@@ -60,7 +60,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
struct thread_struct * t = &current->thread;
unsigned long *bitmap;
- physdev_op_t op;
+ struct physdev_set_iobitmap set_iobitmap;
if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
@@ -80,10 +80,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
memset(bitmap, 0xff, IO_BITMAP_BYTES);
t->io_bitmap_ptr = bitmap;
- op.cmd = PHYSDEVOP_SET_IOBITMAP;
- op.u.set_iobitmap.bitmap = (char *)bitmap;
- op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS;
- HYPERVISOR_physdev_op(&op);
+ set_iobitmap.bitmap = (char *)bitmap;
+ set_iobitmap.nr_ports = IO_BITMAP_BITS;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
}
set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
index 02f2835f56..162ea42dd9 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
@@ -297,9 +297,8 @@ void exit_thread(void)
/* The process may have allocated an io port bitmap... nuke it. */
if (unlikely(NULL != t->io_bitmap_ptr)) {
- physdev_op_t op = { 0 };
- op.cmd = PHYSDEVOP_SET_IOBITMAP;
- HYPERVISOR_physdev_op(&op);
+ struct physdev_set_iobitmap set_iobitmap = { 0 };
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
kfree(t->io_bitmap_ptr);
t->io_bitmap_ptr = NULL;
}
@@ -521,7 +520,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
- physdev_op_t iopl_op, iobmp_op;
+ struct physdev_set_iopl iopl_op;
+ struct physdev_set_iobitmap iobmp_op;
multicall_entry_t _mcl[8], *mcl = _mcl;
/* XEN NOTE: FS/GS saved in switch_mm(), not here. */
@@ -568,23 +568,19 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
#undef C
if (unlikely(prev->iopl != next->iopl)) {
- iopl_op.cmd = PHYSDEVOP_SET_IOPL;
- iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 :
- (next->iopl >> 12) & 3;
+ iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iopl_op;
+ mcl->args[0] = PHYSDEVOP_set_iopl;
+ mcl->args[1] = (unsigned long)&iopl_op;
mcl++;
}
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
- iobmp_op.cmd =
- PHYSDEVOP_SET_IOBITMAP;
- iobmp_op.u.set_iobitmap.bitmap =
- (char *)next->io_bitmap_ptr;
- iobmp_op.u.set_iobitmap.nr_ports =
- next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+ iobmp_op.bitmap = (char *)next->io_bitmap_ptr;
+ iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iobmp_op;
+ mcl->args[0] = PHYSDEVOP_set_iobitmap;
+ mcl->args[1] = (unsigned long)&iobmp_op;
mcl++;
}
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
index 0921330bfe..6fbde82f48 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
@@ -1630,7 +1630,7 @@ static void set_mca_bus(int x) { }
void __init setup_arch(char **cmdline_p)
{
int i, j, k, fpp;
- physdev_op_t op;
+ struct physdev_set_iopl set_iopl;
unsigned long max_low_pfn;
/* Force a quick death if the kernel panics (not domain 0). */
@@ -1815,9 +1815,8 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled)
efi_map_memmap();
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = 1;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = 1;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
#ifdef CONFIG_X86_IO_APIC
check_acpi_pci(); /* Checks more than just ACPI actually */
diff --git a/linux-2.6-xen-sparse/arch/ia64/Kconfig b/linux-2.6-xen-sparse/arch/ia64/Kconfig
index 6bb58cb15f..13df89f457 100644
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig
@@ -106,7 +106,7 @@ config XEN_SYSFS
config XEN_INTERFACE_VERSION
hex
depends on XEN
- default 0x00030201
+ default 0x00030202
config SCHED_NO_NO_OMIT_FRAME_POINTER
bool
diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
index 8fba804bbe..2f955cb5ab 100644
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
@@ -146,29 +146,27 @@ static LIST_HEAD(free_rte_list);
#include <asm/hypervisor.h>
static inline unsigned int xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;
- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = (unsigned long)iosapic -
+ apic_op.apic_physbase = (unsigned long)iosapic -
__IA64_UNCACHED_OFFSET;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}
static inline void xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = (unsigned long)iosapic -
+ apic_op.apic_physbase = (unsigned long)iosapic -
__IA64_UNCACHED_OFFSET;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = val;
- HYPERVISOR_physdev_op(&op);
+ apic_op.reg = reg;
+ apic_op.value = val;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}
static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
@@ -191,14 +189,13 @@ static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 va
int xen_assign_irq_vector(int irq)
{
- physdev_op_t op;
+ struct physdev_irq irq_op;
- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;
- return op.u.irq_op.vector;
+ return irq_op.vector;
}
#endif /* XEN */
diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
index fa753e512b..1e7df722d0 100644
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
@@ -61,9 +61,8 @@ void unmask_evtchn(int port)
#if 0 // FIXME: diverged from x86 evtchn.c
/* Slow path (hypercall) if this is a non-local port. */
if (unlikely(cpu != cpu_from_evtchn(port))) {
- evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
- .u.unmask.port = port };
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_unmask op = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &op);
return;
}
#endif
@@ -95,16 +94,16 @@ int bind_virq_to_irqhandler(
const char *devname,
void *dev_id)
{
- evtchn_op_t op;
+ struct evtchn_bind_virq bind_virq;
int evtchn;
spin_lock(&irq_mapping_update_lock);
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;
if (!unbound_irq(evtchn)) {
evtchn = -EINVAL;
@@ -158,7 +157,7 @@ int bind_ipi_to_irqhandler(
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
- evtchn_op_t op;
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);
spin_lock(&irq_mapping_update_lock);
@@ -166,9 +165,9 @@ void unbind_from_irqhandler(unsigned int irq, void *dev_id)
if (unbound_irq(irq))
goto out;
- op.cmd = EVTCHNOP_close;
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();
switch (type_from_irq(irq)) {
case IRQT_VIRQ:
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
index d71120093e..1fb4c8f112 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
@@ -104,27 +104,25 @@ unsigned long io_apic_irqs;
static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;
- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}
static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = value;
- HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}
#define io_apic_read(a,r) xen_io_apic_read(a,r)
@@ -869,22 +867,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
int assign_irq_vector(int irq)
{
- physdev_op_t op;
+ struct physdev_irq irq_op;
BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
return IO_APIC_VECTOR(irq);
- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;
- vector_irq[op.u.irq_op.vector] = irq;
+ vector_irq[irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+ IO_APIC_VECTOR(irq) = irq_op.vector;
- return op.u.irq_op.vector;
+ return irq_op.vector;
}
extern void (*interrupt[NR_IRQS])(void);
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
index 1b628dff54..19bca3e8c4 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
@@ -28,8 +28,8 @@
asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
{
- unsigned int old_iopl = current->thread.iopl;
- physdev_op_t op;
+ unsigned int old_iopl = current->thread.iopl;
+ struct physdev_set_iopl set_iopl;
if (new_iopl > 3)
return -EINVAL;
@@ -42,9 +42,8 @@ asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
current->thread.iopl = new_iopl;
/* Force the change at ring 0. */
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
return 0;
}
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
index 7127fb57f3..c761d703ed 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
@@ -293,9 +293,7 @@ void exit_thread(void)
struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
#endif
#ifdef CONFIG_XEN
- static physdev_op_t iobmp_op = {
- .cmd = PHYSDEVOP_SET_IOBITMAP
- };
+ struct physdev_set_iobitmap iobmp_op = { 0 };
#endif
kfree(t->io_bitmap_ptr);
@@ -308,7 +306,7 @@ void exit_thread(void)
put_cpu();
#endif
#ifdef CONFIG_XEN
- HYPERVISOR_physdev_op(&iobmp_op);
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
#endif
t->io_bitmap_max = 0;
}
@@ -478,7 +476,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
- physdev_op_t iopl_op, iobmp_op;
+ struct physdev_set_iopl iopl_op;
+ struct physdev_set_iobitmap iobmp_op;
multicall_entry_t _mcl[8], *mcl = _mcl;
/*
@@ -518,22 +517,19 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
#undef C
if (unlikely(prev->iopl != next->iopl)) {
- iopl_op.cmd = PHYSDEVOP_SET_IOPL;
- iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 : next->iopl;
+ iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iopl_op;
+ mcl->args[0] = PHYSDEVOP_set_iopl;
+ mcl->args[1] = (unsigned long)&iopl_op;
mcl++;
}
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
- iobmp_op.cmd =
- PHYSDEVOP_SET_IOBITMAP;
- iobmp_op.u.set_iobitmap.bitmap =
- (char *)next->io_bitmap_ptr;
- iobmp_op.u.set_iobitmap.nr_ports =
- next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+ iobmp_op.bitmap = (char *)next->io_bitmap_ptr;
+ iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iobmp_op;
+ mcl->args[0] = PHYSDEVOP_set_iobitmap;
+ mcl->args[1] = (unsigned long)&iobmp_op;
mcl++;
}
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
index 30f8b40513..df9c1ddbf6 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
@@ -959,11 +959,10 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_XEN
{
- physdev_op_t op;
+ struct physdev_set_iopl set_iopl;
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = 1;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = 1;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
if (xen_start_info->flags & SIF_INITDOMAIN) {
if (!(xen_start_info->flags & SIF_PRIVILEGED))
diff --git a/linux-2.6-xen-sparse/drivers/xen/Kconfig b/linux-2.6-xen-sparse/drivers/xen/Kconfig
index 054e1397de..21487f54d4 100644
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig
@@ -13,7 +13,7 @@ config XEN
if XEN
config XEN_INTERFACE_VERSION
hex
- default 0x00030201
+ default 0x00030202
menu "XEN"
diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
index ac2b961490..15ff3d1b5a 100644
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
@@ -101,10 +101,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
{
blkif_sring_t *sring;
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = blkif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;
/* Already connected through? */
if (blkif->irq)
@@ -119,14 +116,18 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
return err;
}
- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = blkif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
return err;
}
- blkif->evtchn = op.u.bind_interdomain.local_port;
+ blkif->evtchn = bind_interdomain.local_port;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
index f341f9ac33..60ef8d305c 100644
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
@@ -70,10 +70,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
{
blkif_sring_t *sring;
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = blkif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;
if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -84,14 +81,18 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
return err;
}
- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = blkif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
return err;
}
- blkif->evtchn = op.u.bind_interdomain.local_port;
+ blkif->evtchn = bind_interdomain.local_port;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
diff --git a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
index 92888ac62a..d51a986108 100644
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
@@ -103,7 +103,7 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
static int irq_bindcount[NR_IRQS];
/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
+static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];
#ifdef CONFIG_SMP
@@ -258,16 +258,18 @@ static int bind_evtchn_to_irq(unsigned int evtchn)
static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
+ struct evtchn_bind_virq bind_virq;
int evtchn, irq;
spin_lock(&irq_mapping_update_lock);
if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;
irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
@@ -287,15 +289,17 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
+ struct evtchn_bind_ipi bind_ipi;
int evtchn, irq;
spin_lock(&irq_mapping_update_lock);
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
- op.u.bind_ipi.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_ipi.port;
+ bind_ipi.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+ &bind_ipi) != 0)
+ BUG();
+ evtchn = bind_ipi.port;
irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
@@ -315,14 +319,15 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
static void unbind_from_irq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);
spin_lock(&irq_mapping_update_lock);
if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();
switch (type_from_irq(irq)) {
case IRQT_VIRQ:
@@ -428,7 +433,7 @@ static void do_nothing_function(void *ign)
/* Rebind an evtchn so that it gets delivered to a specific cpu */
static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
+ struct evtchn_bind_vcpu bind_vcpu;
int evtchn;
spin_lock(&irq_mapping_update_lock);
@@ -440,15 +445,15 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
}
/* Send future instances of this interrupt to other vcpu. */
- op.u.bind_vcpu.port = evtchn;
- op.u.bind_vcpu.vcpu = tcpu;
+ bind_vcpu.port = evtchn;
+ bind_vcpu.vcpu = tcpu;
/*
* If this fails, it usually just indicates that we're dealing with a
* virq or IPI channel, which don't actually need to be rebound. Ignore
* it, but don't do the xenlinux-level rebind in that case.
*/
- if (HYPERVISOR_event_channel_op(&op) >= 0)
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
bind_evtchn_to_cpu(evtchn, tcpu);
spin_unlock(&irq_mapping_update_lock);
@@ -544,22 +549,19 @@ static struct hw_interrupt_type dynirq_type = {
static inline void pirq_unmask_notify(int pirq)
{
- physdev_op_t op;
- if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
- op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
- (void)HYPERVISOR_physdev_op(&op);
- }
+ struct physdev_eoi eoi = { .irq = pirq };
+ if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
}
static inline void pirq_query_unmask(int pirq)
{
- physdev_op_t op;
- op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
- op.u.irq_status_query.irq = pirq;
- (void)HYPERVISOR_physdev_op(&op);
- clear_bit(pirq, &pirq_needs_unmask_notify[0]);
- if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
- set_bit(pirq, &pirq_needs_unmask_notify[0]);
+ struct physdev_irq_status_query irq_status;
+ irq_status.irq = pirq;
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
+ clear_bit(pirq, &pirq_needs_eoi[0]);
+ if (irq_status.flags & XENIRQSTAT_needs_eoi)
+ set_bit(pirq, &pirq_needs_eoi[0]);
}
/*
@@ -570,22 +572,22 @@ static inline void pirq_query_unmask(int pirq)
static unsigned int startup_pirq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
+ struct evtchn_bind_pirq bind_pirq;
int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
goto out;
- op.u.bind_pirq.pirq = irq;
+ bind_pirq.pirq = irq;
/* NB. We are happy to share unless we are probing. */
- op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
- if (HYPERVISOR_event_channel_op(&op) != 0) {
+ bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
if (!probing_irq(irq))
printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
irq);
return 0;
}
- evtchn = op.u.bind_pirq.port;
+ evtchn = bind_pirq.port;
pirq_query_unmask(irq_to_pirq(irq));
@@ -602,7 +604,7 @@ static unsigned int startup_pirq(unsigned int irq)
static void shutdown_pirq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);
if (!VALID_EVTCHN(evtchn))
@@ -610,8 +612,9 @@ static void shutdown_pirq(unsigned int irq)
mask_evtchn(evtchn);
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();
bind_evtchn_to_cpu(evtchn, 0);
evtchn_to_irq[evtchn] = -1;
@@ -703,9 +706,8 @@ void unmask_evtchn(int port)
/* Slow path (hypercall) if this is a non-local port. */
if (unlikely(cpu != cpu_from_evtchn(port))) {
- evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
- .u.unmask.port = port };
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_unmask unmask = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
return;
}
@@ -728,8 +730,9 @@ EXPORT_SYMBOL_GPL(unmask_evtchn);
void irq_resume(void)
{
- evtchn_op_t op;
- int cpu, pirq, virq, ipi, irq, evtchn;
+ struct evtchn_bind_virq bind_virq;
+ struct evtchn_bind_ipi bind_ipi;
+ int cpu, pirq, virq, ipi, irq, evtchn;
init_evtchn_cpu_bindings();
@@ -763,12 +766,12 @@ void irq_resume(void)
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
/* Get a new binding from Xen. */
- memset(&op, 0, sizeof(op));
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = 0;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = 0;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
@@ -786,11 +789,11 @@ void irq_resume(void)
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
/* Get a new binding from Xen. */
- memset(&op, 0, sizeof(op));
- op.cmd = EVTCHNOP_bind_ipi;
- op.u.bind_ipi.vcpu = 0;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_ipi.port;
+ bind_ipi.vcpu = 0;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+ &bind_ipi) != 0)
+ BUG();
+ evtchn = bind_ipi.port;
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
diff --git a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
index 2975fe070e..8b9cdbbb31 100644
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
@@ -206,68 +206,71 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
int rc;
struct per_user_data *u = file->private_data;
void __user *uarg = (void __user *) arg;
- evtchn_op_t op = { 0 };
switch (cmd) {
case IOCTL_EVTCHN_BIND_VIRQ: {
struct ioctl_evtchn_bind_virq bind;
+ struct evtchn_bind_virq bind_virq;
rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = bind.virq;
- op.u.bind_virq.vcpu = 0;
- rc = HYPERVISOR_event_channel_op(&op);
+ bind_virq.virq = bind.virq;
+ bind_virq.vcpu = 0;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq);
if (rc != 0)
break;
- rc = op.u.bind_virq.port;
+ rc = bind_virq.port;
evtchn_bind_to_user(u, rc);
break;
}
case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
struct ioctl_evtchn_bind_interdomain bind;
+ struct evtchn_bind_interdomain bind_interdomain;
rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;
- op.cmd = EVTCHNOP_bind_interdomain;
- op.u.bind_interdomain.remote_dom = bind.remote_domain;
- op.u.bind_interdomain.remote_port = bind.remote_port;
- rc = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = bind.remote_domain;
+ bind_interdomain.remote_port = bind.remote_port;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (rc != 0)
break;
- rc = op.u.bind_interdomain.local_port;
+ rc = bind_interdomain.local_port;
evtchn_bind_to_user(u, rc);
break;
}
case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
struct ioctl_evtchn_bind_unbound_port bind;
+ struct evtchn_alloc_unbound alloc_unbound;
rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;
- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = bind.remote_domain;
- rc = HYPERVISOR_event_channel_op(&op);
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = bind.remote_domain;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (rc != 0)
break;
- rc = op.u.alloc_unbound.port;
+ rc = alloc_unbound.port;
evtchn_bind_to_user(u, rc);
break;
}
case IOCTL_EVTCHN_UNBIND: {
struct ioctl_evtchn_unbind unbind;
+ struct evtchn_close close;
int ret;
rc = -EFAULT;
@@ -291,9 +294,8 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
spin_unlock_irq(&port_user_lock);
- op.cmd = EVTCHNOP_close;
- op.u.close.port = unbind.port;
- ret = HYPERVISOR_event_channel_op(&op);
+ close.port = unbind.port;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
BUG_ON(ret);
rc = 0;
@@ -379,7 +381,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
{
int i;
struct per_user_data *u = filp->private_data;
- evtchn_op_t op = { 0 };
+ struct evtchn_close close;
spin_lock_irq(&port_user_lock);
@@ -393,9 +395,8 @@ static int evtchn_release(struct inode *inode, struct file *filp)
port_user[i] = NULL;
mask_evtchn(i);
- op.cmd = EVTCHNOP_close;
- op.u.close.port = i;
- ret = HYPERVISOR_event_channel_op(&op);
+ close.port = i;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
BUG_ON(ret);
}
diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
index f4407bccdc..10095a6abf 100644
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
@@ -213,10 +213,7 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
int err = -ENOMEM;
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = netif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;
/* Already connected through? */
if (netif->irq)
@@ -233,11 +230,15 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
if (err)
goto err_map;
- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = netif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err)
goto err_hypervisor;
- netif->evtchn = op.u.bind_interdomain.local_port;
+ netif->evtchn = bind_interdomain.local_port;
netif->irq = bind_evtchn_to_irqhandler(
netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
index 5b51e3271d..a5b9c73813 100644
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
@@ -35,7 +35,7 @@
static struct proc_dir_entry *privcmd_intf;
static struct proc_dir_entry *capabilities_intf;
-#define NR_HYPERCALLS 32
+#define NR_HYPERCALLS 64
static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
static int privcmd_ioctl(struct inode *inode, struct file *file,
diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
index 7a7ca4c7ed..347ed1ab02 100644
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
@@ -112,11 +112,7 @@ static void unmap_frontend_page(tpmif_t *tpmif)
int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
{
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = tpmif->domid,
- .u.bind_interdomain.remote_port = evtchn,
- };
+ struct evtchn_bind_interdomain bind_interdomain;
if (tpmif->irq) {
return 0;
@@ -131,14 +127,19 @@ int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
return err;
}
- err = HYPERVISOR_event_channel_op(&op);
+
+ bind_interdomain.remote_dom = tpmif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(tpmif);
free_vm_area(tpmif->tx_area);
return err;
}
- tpmif->evtchn = op.u.bind_interdomain.local_port;
+ tpmif->evtchn = bind_interdomain.local_port;
tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
index d4059b18c2..5985ebefed 100644
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
@@ -214,16 +214,19 @@ EXPORT_SYMBOL_GPL(xenbus_grant_ring);
int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_alloc_unbound,
- .u.alloc_unbound.dom = DOMID_SELF,
- .u.alloc_unbound.remote_dom = dev->otherend_id
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_alloc_unbound alloc_unbound;
+ int err;
+
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = dev->otherend_id;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (err)
xenbus_dev_fatal(dev, err, "allocating event channel");
else
- *port = op.u.alloc_unbound.port;
+ *port = alloc_unbound.port;
+
return err;
}
EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
@@ -231,18 +234,21 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = dev->otherend_id,
- .u.bind_interdomain.remote_port = remote_port,
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_bind_interdomain bind_interdomain;
+ int err;
+
+ bind_interdomain.remote_dom = dev->otherend_id;
+ bind_interdomain.remote_port = remote_port,
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err)
xenbus_dev_fatal(dev, err,
"binding to event channel %d from domain %d",
remote_port, dev->otherend_id);
else
- *port = op.u.bind_interdomain.local_port;
+ *port = bind_interdomain.local_port;
+
return err;
}
EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
@@ -250,13 +256,15 @@ EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
int xenbus_free_evtchn(struct xenbus_device *dev, int port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_close,
- .u.close.port = port,
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_close close;
+ int err;
+
+ close.port = port;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
if (err)
xenbus_dev_error(dev, err, "freeing event channel %d", port);
+
return err;
}
diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
index 09bedf7b66..e0c05915a5 100644
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
@@ -981,7 +981,7 @@ static int __init xenbus_probe_init(void)
dom0 = (xen_start_info->store_evtchn == 0);
if (dom0) {
- evtchn_op_t op = { 0 };
+ struct evtchn_alloc_unbound alloc_unbound;
/* Allocate page. */
page = get_zeroed_page(GFP_KERNEL);
@@ -993,15 +993,15 @@ static int __init xenbus_probe_init(void)
PAGE_SHIFT);
/* Next allocate a local port which xenstored can bind to */
- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = 0;
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = 0;
- err = HYPERVISOR_event_channel_op(&op);
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (err == -ENOSYS)
goto err;
BUG_ON(err);
- xen_start_info->store_evtchn = op.u.alloc_unbound.port;
+ xen_start_info->store_evtchn = alloc_unbound.port;
/* And finally publish the above info in /proc/xen */
xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
index 491362c976..a5ffa3a53b 100644
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
@@ -245,9 +245,16 @@ HYPERVISOR_update_va_mapping(
static inline int
HYPERVISOR_event_channel_op(
- void *op)
+ int cmd, void *arg)
{
- return _hypercall1(int, event_channel_op, op);
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}
static inline int
@@ -266,9 +273,16 @@ HYPERVISOR_console_io(
static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
+ int cmd, void *arg)
{
- return _hypercall1(int, physdev_op, physdev_op);
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}
static inline int
diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
index 8e135b4054..e4ec1309d3 100644
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <xen/interface/nmi.h>
#include <asm/ptrace.h>
diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
index 6c02802144..fabab38fa2 100644
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
@@ -534,12 +534,11 @@ static inline void __load_esp0(struct tss_struct *tss, struct thread_struct *thr
*/
static inline void set_iopl_mask(unsigned mask)
{
- physdev_op_t op;
+ struct physdev_set_iopl set_iopl;
/* Force the change at ring 0. */
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
}
/* Forward declaration, a strange C thing */
diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
index b0cced7678..432026eea4 100644
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
@@ -202,9 +202,16 @@ HYPERVISOR_memory_op(
static inline int
HYPERVISOR_event_channel_op(
- void *op)
+ int cmd, void *arg)
{
- return _hypercall1(int, event_channel_op, op);
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}
static inline int
@@ -223,9 +230,16 @@ HYPERVISOR_console_io(
static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
+ int cmd, void *arg)
{
- return _hypercall1(int, physdev_op, physdev_op);
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}
static inline int
diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
index e92cc4fbdb..ba17a56210 100644
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <asm/hypercall.h>
#include <asm/ptrace.h>
diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
index f75ae5819d..be9933975e 100644
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
@@ -243,9 +243,16 @@ HYPERVISOR_update_va_mapping(
static inline int
HYPERVISOR_event_channel_op(
- void *op)
+ int cmd, void *arg)
{
- return _hypercall1(int, event_channel_op, op);
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}
static inline int
@@ -264,9 +271,16 @@ HYPERVISOR_console_io(
static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
+ int cmd, void *arg)
{
- return _hypercall1(int, physdev_op, physdev_op);
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}
static inline int
diff --git a/linux-2.6-xen-sparse/include/xen/evtchn.h b/linux-2.6-xen-sparse/include/xen/evtchn.h
index 100eb1cdaa..4770663603 100644
--- a/linux-2.6-xen-sparse/include/xen/evtchn.h
+++ b/linux-2.6-xen-sparse/include/xen/evtchn.h
@@ -101,10 +101,8 @@ static inline void clear_evtchn(int port)
static inline void notify_remote_via_evtchn(int port)
{
- evtchn_op_t op;
- op.cmd = EVTCHNOP_send,
- op.u.send.port = port;
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_send send = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
}
/*
diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c
index 27d464bb2f..e43d210faf 100644
--- a/tools/libxc/xc_evtchn.c
+++ b/tools/libxc/xc_evtchn.c
@@ -9,24 +9,25 @@
#include "xc_private.h"
-static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
+static int do_evtchn_op(int xc_handle, int cmd, void *arg, size_t arg_size)
{
int ret = -1;
DECLARE_HYPERCALL;
hypercall.op = __HYPERVISOR_event_channel_op;
- hypercall.arg[0] = (unsigned long)op;
+ hypercall.arg[0] = cmd;
+ hypercall.arg[1] = (unsigned long)arg;
- if ( mlock(op, sizeof(*op)) != 0 )
+ if ( mlock(arg, arg_size) != 0 )
{
- PERROR("do_evtchn_op: op mlock failed");
+ PERROR("do_evtchn_op: arg mlock failed");
goto out;
}
if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
- safe_munlock(op, sizeof(*op));
+ safe_munlock(arg, arg_size);
out:
return ret;
}
@@ -37,13 +38,14 @@ int xc_evtchn_alloc_unbound(int xc_handle,
uint32_t remote_dom)
{
int rc;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_alloc_unbound,
- .u.alloc_unbound.dom = (domid_t)dom,
- .u.alloc_unbound.remote_dom = (domid_t)remote_dom };
+ struct evtchn_alloc_unbound arg = {
+ .dom = (domid_t)dom,
+ .remote_dom = (domid_t)remote_dom
+ };
- if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
- rc = op.u.alloc_unbound.port;
+ rc = do_evtchn_op(xc_handle, EVTCHNOP_alloc_unbound, &arg, sizeof(arg));
+ if ( rc == 0 )
+ rc = arg.port;
return rc;
}
@@ -54,14 +56,7 @@ int xc_evtchn_status(int xc_handle,
evtchn_port_t port,
xc_evtchn_status_t *status)
{
- int rc;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_status,
- .u.status.dom = (domid_t)dom,
- .u.status.port = port };
-
- if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
- memcpy(status, &op.u.status, sizeof(*status));
-
- return rc;
+ status->dom = (domid_t)dom;
+ status->port = port;
+ return do_evtchn_op(xc_handle, EVTCHNOP_status, status, sizeof(*status));
}
diff --git a/xen/arch/ia64/vmx/vmx_hypercall.c b/xen/arch/ia64/vmx/vmx_hypercall.c
index d07b7334e6..403605bf41 100644
--- a/xen/arch/ia64/vmx/vmx_hypercall.c
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c
@@ -106,12 +106,12 @@ void hyper_dom0_op(void)
vmx_vcpu_increment_iip(vcpu);
}
-void hyper_event_channel_op(void)
+void hyper_event_channel_op_compat(void)
{
VCPU *vcpu=current;
u64 r32,ret;
vcpu_get_gr_nat(vcpu,16,&r32);
- ret=do_event_channel_op(guest_handle_from_ptr(r32, evtchn_op_t));
+ ret=do_event_channel_op_compat(guest_handle_from_ptr(r32, evtchn_op_t));
vcpu_set_gr(vcpu, 8, ret, 0);
vmx_vcpu_increment_iip(vcpu);
}
diff --git a/xen/arch/ia64/vmx/vmx_ivt.S b/xen/arch/ia64/vmx/vmx_ivt.S
index 81b3e64636..c9288b1794 100644
--- a/xen/arch/ia64/vmx/vmx_ivt.S
+++ b/xen/arch/ia64/vmx/vmx_ivt.S
@@ -1154,7 +1154,7 @@ hyper_call_table:
data8 hyper_not_support //hyper_multicall
data8 hyper_not_support //hyper_update_va_mapping
data8 hyper_not_support //hyper_set_timer_op /* 15 */
- data8 hyper_event_channel_op
+ data8 hyper_event_channel_op_compat
data8 hyper_xen_version
data8 hyper_not_support //hyper_console_io
data8 hyper_not_support //hyper_physdev_op
diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c
index 72e6ecf7a3..ca1a103c3b 100644
--- a/xen/arch/ia64/xen/hypercall.c
+++ b/xen/arch/ia64/xen/hypercall.c
@@ -27,6 +27,7 @@
#include <xen/domain.h>
extern unsigned long translate_domain_mpaddr(unsigned long);
+static long do_physdev_op_compat(int cmd, XEN_GUEST_HANDLE(void) arg);
static long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop);
/* FIXME: where these declarations should be there ? */
extern int dump_privop_counts_to_user(char *, int);
@@ -53,10 +54,10 @@ hypercall_t ia64_hypercall_table[] =
(hypercall_t)do_multicall,
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping */
(hypercall_t)do_ni_hypercall, /* do_set_timer_op */ /* 15 */
- (hypercall_t)do_event_channel_op,
+ (hypercall_t)do_event_channel_op_compat,
(hypercall_t)do_xen_version,
(hypercall_t)do_console_io,
- (hypercall_t)do_physdev_op,
+ (hypercall_t)do_physdev_op_compat,
(hypercall_t)do_grant_table_op, /* 20 */
(hypercall_t)do_ni_hypercall, /* do_vm_assist */
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping_otherdomain */
@@ -68,7 +69,9 @@ hypercall_t ia64_hypercall_table[] =
(hypercall_t)do_ni_hypercall, /* do_nmi_op */
(hypercall_t)do_sched_op,
(hypercall_t)do_ni_hypercall, /* */ /* 30 */
- (hypercall_t)do_ni_hypercall /* */
+ (hypercall_t)do_ni_hypercall, /* */
+ (hypercall_t)do_event_channel_op,
+ (hypercall_t)do_physdev_op
};
uint32_t nr_hypercalls =
@@ -330,71 +333,117 @@ extern int
iosapic_guest_write(
unsigned long physbase, unsigned int reg, u32 pval);
-static long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop)
+static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
- struct physdev_op op;
+ int irq;
long ret;
- int irq;
-
- if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
- return -EFAULT;
- switch ( op.cmd )
+ switch ( cmd )
{
- case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+ case PHYSDEVOP_eoi: {
+ struct physdev_eoi eoi;
+ ret = -EFAULT;
+ if ( copy_from_guest(&eoi, arg, 1) != 0 )
+ break;
+ ret = pirq_guest_eoi(current->domain, eoi.irq);
+ break;
+ }
+
+ /* Legacy since 0x00030202. */
+ case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
ret = pirq_guest_unmask(current->domain);
break;
+ }
- case PHYSDEVOP_IRQ_STATUS_QUERY:
- irq = op.u.irq_status_query.irq;
+ case PHYSDEVOP_irq_status_query: {
+ struct physdev_irq_status_query irq_status_query;
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+ break;
+ irq = irq_status_query.irq;
ret = -EINVAL;
if ( (irq < 0) || (irq >= NR_IRQS) )
break;
- op.u.irq_status_query.flags = 0;
+ irq_status_query.flags = 0;
/* Edge-triggered interrupts don't need an explicit unmask downcall. */
if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") )
- op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
- ret = 0;
+ irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+ ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
break;
+ }
- case PHYSDEVOP_APIC_READ:
+ case PHYSDEVOP_apic_read: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = iosapic_guest_read(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- &op.u.apic_op.value);
+ ret = iosapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+ if ( copy_to_guest(arg, &apic, 1) != 0 )
+ ret = -EFAULT;
break;
+ }
- case PHYSDEVOP_APIC_WRITE:
+ case PHYSDEVOP_apic_write: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = iosapic_guest_write(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- op.u.apic_op.value);
+ ret = iosapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
break;
+ }
- case PHYSDEVOP_ASSIGN_VECTOR:
+ case PHYSDEVOP_alloc_irq_vector: {
+ struct physdev_irq irq_op;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+ break;
+
+ ret = -EPERM;
if ( !IS_PRIV(current->domain) )
- return -EPERM;
+ break;
- if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
- return -EINVAL;
+ ret = -EINVAL;
+ if ( (irq = irq_op.irq) >= NR_IRQS )
+ break;
- op.u.irq_op.vector = assign_irq_vector(irq);
- ret = 0;
+ irq_op.vector = assign_irq_vector(irq);
+ ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
break;
+ }
default:
ret = -EINVAL;
break;
}
- if ( copy_to_guest(uop, &op, 1) )
- ret = -EFAULT;
-
return ret;
}
+
+/* Legacy hypercall (as of 0x00030202). */
+static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
+{
+ struct physdev_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+ struct evtchn_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c
index 5fbffdf82b..c8f8ec5b9e 100644
--- a/xen/arch/ia64/xen/irq.c
+++ b/xen/arch/ia64/xen/irq.c
@@ -411,22 +411,40 @@ void __do_IRQ_guest(int irq)
}
}
+int pirq_guest_eoi(struct domain *d, int irq)
+{
+ irq_desc_t *desc;
+
+ if ( (irq < 0) || (irq >= NR_IRQS) )
+ return -EINVAL;
+
+ desc = &irq_desc[irq];
+ spin_lock_irq(&desc->lock);
+ if ( test_and_clear_bit(irq, &d->pirq_mask) &&
+ (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+ desc->handler->end(irq);
+ spin_unlock_irq(&desc->lock);
+
+ return 0;
+
+}
+
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
- int pirq;
+ int irq;
shared_info_t *s = d->shared_info;
- for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
- pirq < NR_PIRQS;
- pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
+ for ( irq = find_first_bit(d->pirq_mask, NR_PIRQS);
+ irq < NR_PIRQS;
+ irq = find_next_bit(d->pirq_mask, NR_PIRQS, irq+1) )
{
- desc = &irq_desc[pirq];
+ desc = &irq_desc[irq];
spin_lock_irq(&desc->lock);
- if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
- test_and_clear_bit(pirq, &d->pirq_mask) &&
+ if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) &&
+ test_and_clear_bit(irq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
- desc->handler->end(pirq);
+ desc->handler->end(irq);
spin_unlock_irq(&desc->lock);
}
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index e4d6452141..fad402d314 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -10,6 +10,7 @@ subdir-$(x86_64) += x86_64
obj-y += apic.o
obj-y += audit.o
obj-y += bitops.o
+obj-y += compat.o
obj-y += delay.o
obj-y += dmi_scan.o
obj-y += dom0_ops.o
diff --git a/xen/arch/x86/compat.c b/xen/arch/x86/compat.c
new file mode 100644
index 0000000000..431c4560fd
--- /dev/null
+++ b/xen/arch/x86/compat.c
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * compat.c
+ *
+ * Implementations of legacy hypercalls. These call through to the new
+ * hypercall after doing necessary argument munging.
+ */
+
+#include <xen/config.h>
+#include <xen/guest_access.h>
+#include <xen/hypercall.h>
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
+{
+ struct physdev_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u });
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+ struct evtchn_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u });
+}
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 41bfb98e7e..c144b9f415 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -293,52 +293,75 @@ static void flush_all_pending_eoi(void *unused)
flush_ready_eoi(NULL);
}
-int pirq_guest_unmask(struct domain *d)
+static void __pirq_guest_eoi(struct domain *d, int irq)
{
irq_desc_t *desc;
irq_guest_action_t *action;
- cpumask_t cpu_eoi_map = CPU_MASK_NONE;
- unsigned int pirq, cpu = smp_processor_id();
- shared_info_t *s = d->shared_info;
+ cpumask_t cpu_eoi_map;
+
+ desc = &irq_desc[irq_to_vector(irq)];
+ action = (irq_guest_action_t *)desc->action;
+
+ spin_lock_irq(&desc->lock);
+
+ ASSERT(!test_bit(irq, d->pirq_mask) ||
+ (action->ack_type != ACKTYPE_NONE));
- for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
- pirq < NR_PIRQS;
- pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
+ if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) ||
+ unlikely(--action->in_flight != 0) )
{
- desc = &irq_desc[irq_to_vector(pirq)];
- action = (irq_guest_action_t *)desc->action;
+ spin_unlock_irq(&desc->lock);
+ return;
+ }
- spin_lock_irq(&desc->lock);
+ if ( action->ack_type == ACKTYPE_UNMASK )
+ {
+ ASSERT(cpus_empty(action->cpu_eoi_map));
+ desc->handler->end(irq_to_vector(irq));
+ return;
+ }
- if ( !test_bit(d->pirq_to_evtchn[pirq], s->evtchn_mask) &&
- test_and_clear_bit(pirq, d->pirq_mask) )
- {
- ASSERT(action->ack_type != ACKTYPE_NONE);
- if ( --action->in_flight == 0 )
- {
- if ( action->ack_type == ACKTYPE_UNMASK )
- desc->handler->end(irq_to_vector(pirq));
- cpu_eoi_map = action->cpu_eoi_map;
- }
- }
+ ASSERT(action->ack_type == ACKTYPE_EOI);
+
+ cpu_eoi_map = action->cpu_eoi_map;
- if ( cpu_test_and_clear(cpu, cpu_eoi_map) )
- {
- __set_eoi_ready(desc);
- spin_unlock(&desc->lock);
- flush_ready_eoi(NULL);
- local_irq_enable();
- }
- else
- {
- spin_unlock_irq(&desc->lock);
- }
+ if ( cpu_test_and_clear(smp_processor_id(), cpu_eoi_map) )
+ {
+ __set_eoi_ready(desc);
+ spin_unlock(&desc->lock);
+ flush_ready_eoi(NULL);
+ local_irq_enable();
+ }
+ else
+ {
+ spin_unlock_irq(&desc->lock);
+ }
- if ( !cpus_empty(cpu_eoi_map) )
- {
- on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
- cpu_eoi_map = CPU_MASK_NONE;
- }
+ if ( !cpus_empty(cpu_eoi_map) )
+ on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
+}
+
+int pirq_guest_eoi(struct domain *d, int irq)
+{
+ if ( (irq < 0) || (irq >= NR_IRQS) )
+ return -EINVAL;
+
+ __pirq_guest_eoi(d, irq);
+
+ return 0;
+}
+
+int pirq_guest_unmask(struct domain *d)
+{
+ unsigned int irq;
+ shared_info_t *s = d->shared_info;
+
+ for ( irq = find_first_bit(d->pirq_mask, NR_PIRQS);
+ irq < NR_PIRQS;
+ irq = find_next_bit(d->pirq_mask, NR_PIRQS, irq+1) )
+ {
+ if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) )
+ __pirq_guest_eoi(d, irq);
}
return 0;
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 50155e1003..48d259c85d 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -22,91 +22,123 @@ extern int
pirq_acktype(
int irq);
-/*
- * Demuxing hypercall.
- */
-long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop)
+long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
- struct physdev_op op;
+ int irq;
long ret;
- int irq;
-
- if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
- return -EFAULT;
- switch ( op.cmd )
+ switch ( cmd )
{
- case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+ case PHYSDEVOP_eoi: {
+ struct physdev_eoi eoi;
+ ret = -EFAULT;
+ if ( copy_from_guest(&eoi, arg, 1) != 0 )
+ break;
+ ret = pirq_guest_eoi(current->domain, eoi.irq);
+ break;
+ }
+
+ /* Legacy since 0x00030202. */
+ case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
ret = pirq_guest_unmask(current->domain);
break;
+ }
- case PHYSDEVOP_IRQ_STATUS_QUERY:
- irq = op.u.irq_status_query.irq;
+ case PHYSDEVOP_irq_status_query: {
+ struct physdev_irq_status_query irq_status_query;
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+ break;
+ irq = irq_status_query.irq;
ret = -EINVAL;
if ( (irq < 0) || (irq >= NR_IRQS) )
break;
- op.u.irq_status_query.flags = 0;
+ irq_status_query.flags = 0;
if ( pirq_acktype(irq) != 0 )
- op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
- ret = 0;
+ irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+ ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
break;
+ }
- case PHYSDEVOP_APIC_READ:
+ case PHYSDEVOP_apic_read: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = ioapic_guest_read(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- &op.u.apic_op.value);
+ ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+ if ( copy_to_guest(arg, &apic, 1) != 0 )
+ ret = -EFAULT;
break;
+ }
- case PHYSDEVOP_APIC_WRITE:
+ case PHYSDEVOP_apic_write: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = ioapic_guest_write(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- op.u.apic_op.value);
+ ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
break;
+ }
- case PHYSDEVOP_ASSIGN_VECTOR:
+ case PHYSDEVOP_alloc_irq_vector: {
+ struct physdev_irq irq_op;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+ break;
+
+ ret = -EPERM;
if ( !IS_PRIV(current->domain) )
- return -EPERM;
+ break;
- if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
- return -EINVAL;
+ ret = -EINVAL;
+ if ( (irq = irq_op.irq) >= NR_IRQS )
+ break;
- op.u.irq_op.vector = assign_irq_vector(irq);
- ret = 0;
+ irq_op.vector = assign_irq_vector(irq);
+ ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
break;
+ }
- case PHYSDEVOP_SET_IOPL:
+ case PHYSDEVOP_set_iopl: {
+ struct physdev_set_iopl set_iopl;
+ ret = -EFAULT;
+ if ( copy_from_guest(&set_iopl, arg, 1) != 0 )
+ break;
ret = -EINVAL;
- if ( op.u.set_iopl.iopl > 3 )
+ if ( set_iopl.iopl > 3 )
break;
ret = 0;
- current->arch.iopl = op.u.set_iopl.iopl;
+ current->arch.iopl = set_iopl.iopl;
break;
+ }
- case PHYSDEVOP_SET_IOBITMAP:
+ case PHYSDEVOP_set_iobitmap: {
+ struct physdev_set_iobitmap set_iobitmap;
+ ret = -EFAULT;
+ if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 )
+ break;
ret = -EINVAL;
- if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
- (op.u.set_iobitmap.nr_ports > 65536) )
+ if ( !access_ok(set_iobitmap.bitmap, IOBMP_BYTES) ||
+ (set_iobitmap.nr_ports > 65536) )
break;
ret = 0;
- current->arch.iobmp = op.u.set_iobitmap.bitmap;
- current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
+ current->arch.iobmp = set_iobitmap.bitmap;
+ current->arch.iobmp_limit = set_iobitmap.nr_ports;
break;
+ }
+
default:
ret = -EINVAL;
break;
}
- if ( copy_to_guest(uop, &op, 1) )
- ret = -EFAULT;
-
return ret;
}
diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S
index 1c1cf83901..1a4ac5367e 100644
--- a/xen/arch/x86/x86_32/entry.S
+++ b/xen/arch/x86/x86_32/entry.S
@@ -630,10 +630,10 @@ ENTRY(hypercall_table)
.long do_multicall
.long do_update_va_mapping
.long do_set_timer_op /* 15 */
- .long do_event_channel_op
+ .long do_event_channel_op_compat
.long do_xen_version
.long do_console_io
- .long do_physdev_op
+ .long do_physdev_op_compat
.long do_grant_table_op /* 20 */
.long do_vm_assist
.long do_update_va_mapping_otherdomain
@@ -646,6 +646,8 @@ ENTRY(hypercall_table)
.long do_arch_sched_op
.long do_callback_op /* 30 */
.long do_xenoprof_op
+ .long do_event_channel_op
+ .long do_physdev_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -667,10 +669,10 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_multicall */
.byte 4 /* do_update_va_mapping */
.byte 2 /* do_set_timer_op */ /* 15 */
- .byte 1 /* do_event_channel_op */
+ .byte 1 /* do_event_channel_op_compat */
.byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
- .byte 1 /* do_physdev_op */
+ .byte 1 /* do_physdev_op_compat */
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 5 /* do_update_va_mapping_otherdomain */
@@ -683,6 +685,8 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_arch_sched_op */
.byte 2 /* do_callback_op */ /* 30 */
.byte 2 /* do_xenoprof_op */
+ .byte 2 /* do_event_channel_op */
+ .byte 2 /* do_physdev_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 9c27e2a595..110c34a417 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -538,10 +538,10 @@ ENTRY(hypercall_table)
.quad do_multicall
.quad do_update_va_mapping
.quad do_set_timer_op /* 15 */
- .quad do_event_channel_op
+ .quad do_event_channel_op_compat
.quad do_xen_version
.quad do_console_io
- .quad do_physdev_op
+ .quad do_physdev_op_compat
.quad do_grant_table_op /* 20 */
.quad do_vm_assist
.quad do_update_va_mapping_otherdomain
@@ -554,6 +554,8 @@ ENTRY(hypercall_table)
.quad do_arch_sched_op
.quad do_callback_op /* 30 */
.quad do_xenoprof_op
+ .quad do_event_channel_op
+ .quad do_physdev_op
.rept NR_hypercalls-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
@@ -575,10 +577,10 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_multicall */
.byte 3 /* do_update_va_mapping */
.byte 1 /* do_set_timer_op */ /* 15 */
- .byte 1 /* do_event_channel_op */
+ .byte 1 /* do_event_channel_op_compat */
.byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
- .byte 1 /* do_physdev_op */
+ .byte 1 /* do_physdev_op_compat */
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 4 /* do_update_va_mapping_otherdomain */
@@ -591,6 +593,8 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_arch_sched_op */
.byte 2 /* do_callback_op */ /* 30 */
.byte 2 /* do_xenoprof_op */
+ .byte 2 /* do_event_channel_op */
+ .byte 2 /* do_physdev_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 1bfd792b3b..c02ef9ac08 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -97,7 +97,10 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
struct domain *d;
int port;
domid_t dom = alloc->dom;
- long rc = 0;
+ long rc;
+
+ if ( (rc = acm_pre_eventchannel_unbound(dom, alloc->remote_dom)) != 0 )
+ return rc;
if ( dom == DOMID_SELF )
dom = current->domain->domain_id;
@@ -134,7 +137,10 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
struct domain *ld = current->domain, *rd;
int lport, rport = bind->remote_port;
domid_t rdom = bind->remote_dom;
- long rc = 0;
+ long rc;
+
+ if ( (rc = acm_pre_eventchannel_interdomain(rdom)) != 0 )
+ return rc;
if ( rdom == DOMID_SELF )
rdom = current->domain->domain_id;
@@ -201,13 +207,14 @@ static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
int port, virq = bind->virq, vcpu = bind->vcpu;
long rc = 0;
- if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
+ if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
return -EINVAL;
if ( virq_is_global(virq) && (vcpu != 0) )
return -EINVAL;
- if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
+ if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+ ((v = d->vcpu[vcpu]) == NULL) )
return -ENOENT;
spin_lock(&d->evtchn_lock);
@@ -239,7 +246,8 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
int port, vcpu = bind->vcpu;
long rc = 0;
- if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
+ if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+ (d->vcpu[vcpu] == NULL) )
return -ENOENT;
spin_lock(&d->evtchn_lock);
@@ -267,7 +275,7 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
int port, pirq = bind->pirq;
long rc;
- if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
+ if ( (pirq < 0) || (pirq >= ARRAY_SIZE(d->pirq_to_evtchn)) )
return -EINVAL;
if ( !irq_access_permitted(d, pirq) )
@@ -683,70 +691,103 @@ static long evtchn_unmask(evtchn_unmask_t *unmask)
}
-long do_event_channel_op(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
long rc;
- struct evtchn_op op;
-
- if ( copy_from_guest(&op, uop, 1) != 0 )
- return -EFAULT;
- if (acm_pre_event_channel(&op))
- return -EACCES;
-
- switch ( op.cmd )
+ switch ( cmd )
{
- case EVTCHNOP_alloc_unbound:
- rc = evtchn_alloc_unbound(&op.u.alloc_unbound);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_alloc_unbound: {
+ struct evtchn_alloc_unbound alloc_unbound;
+ if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_alloc_unbound(&alloc_unbound);
+ if ( (rc == 0) && (copy_to_guest(arg, &alloc_unbound, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
+ }
- case EVTCHNOP_bind_interdomain:
- rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_bind_interdomain: {
+ struct evtchn_bind_interdomain bind_interdomain;
+ if ( copy_from_guest(&bind_interdomain, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_interdomain(&bind_interdomain);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_interdomain, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
+ }
- case EVTCHNOP_bind_virq:
- rc = evtchn_bind_virq(&op.u.bind_virq);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_bind_virq: {
+ struct evtchn_bind_virq bind_virq;
+ if ( copy_from_guest(&bind_virq, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_virq(&bind_virq);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_virq, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
+ }
- case EVTCHNOP_bind_ipi:
- rc = evtchn_bind_ipi(&op.u.bind_ipi);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_bind_ipi: {
+ struct evtchn_bind_ipi bind_ipi;
+ if ( copy_from_guest(&bind_ipi, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_ipi(&bind_ipi);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_ipi, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
+ }
- case EVTCHNOP_bind_pirq:
- rc = evtchn_bind_pirq(&op.u.bind_pirq);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_bind_pirq: {
+ struct evtchn_bind_pirq bind_pirq;
+ if ( copy_from_guest(&bind_pirq, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_pirq(&bind_pirq);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_pirq, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
+ }
- case EVTCHNOP_close:
- rc = evtchn_close(&op.u.close);
+ case EVTCHNOP_close: {
+ struct evtchn_close close;
+ if ( copy_from_guest(&close, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_close(&close);
break;
+ }
- case EVTCHNOP_send:
- rc = evtchn_send(op.u.send.port);
+ case EVTCHNOP_send: {
+ struct evtchn_send send;
+ if ( copy_from_guest(&send, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_send(send.port);
break;
+ }
- case EVTCHNOP_status:
- rc = evtchn_status(&op.u.status);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ case EVTCHNOP_status: {
+ struct evtchn_status status;
+ if ( copy_from_guest(&status, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_status(&status);
+ if ( (rc == 0) && (copy_to_guest(arg, &status, 1) != 0) )
rc = -EFAULT;
break;
+ }
- case EVTCHNOP_bind_vcpu:
- rc = evtchn_bind_vcpu(op.u.bind_vcpu.port, op.u.bind_vcpu.vcpu);
+ case EVTCHNOP_bind_vcpu: {
+ struct evtchn_bind_vcpu bind_vcpu;
+ if ( copy_from_guest(&bind_vcpu, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_vcpu(bind_vcpu.port, bind_vcpu.vcpu);
break;
+ }
- case EVTCHNOP_unmask:
- rc = evtchn_unmask(&op.u.unmask);
+ case EVTCHNOP_unmask: {
+ struct evtchn_unmask unmask;
+ if ( copy_from_guest(&unmask, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_unmask(&unmask);
break;
+ }
default:
rc = -ENOSYS;
diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h
index a48755e9f1..c89eca7c73 100644
--- a/xen/include/acm/acm_hooks.h
+++ b/xen/include/acm/acm_hooks.h
@@ -135,7 +135,9 @@ static inline void acm_post_dom0_op(struct dom0_op *op, void *ssid)
{ return; }
static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid)
{ return; }
-static inline int acm_pre_event_channel(struct evtchn_op *op)
+static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
+{ return 0; }
+static inline int acm_pre_eventchannel_interdomain(domid_t id)
{ return 0; }
static inline int acm_pre_grant_map_ref(domid_t id)
{ return 0; }
@@ -289,26 +291,6 @@ static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid)
}
}
-static inline int acm_pre_event_channel(struct evtchn_op *op)
-{
- int ret = -EACCES;
-
- switch(op->cmd) {
- case EVTCHNOP_alloc_unbound:
- ret = acm_pre_eventchannel_unbound(
- op->u.alloc_unbound.dom,
- op->u.alloc_unbound.remote_dom);
- break;
- case EVTCHNOP_bind_interdomain:
- ret = acm_pre_eventchannel_interdomain(
- op->u.bind_interdomain.remote_dom);
- break;
- default:
- ret = 0; /* ok */
- }
- return ret;
-}
-
static inline int acm_pre_grant_map_ref(domid_t id)
{
if ( (acm_primary_ops->pre_grant_map_ref != NULL) &&
diff --git a/xen/include/asm-ia64/hypercall.h b/xen/include/asm-ia64/hypercall.h
index ad34db37d8..6e4a0320fd 100644
--- a/xen/include/asm-ia64/hypercall.h
+++ b/xen/include/asm-ia64/hypercall.h
@@ -9,6 +9,10 @@
#include <asm/types.h>
#include <asm/vcpu.h>
+extern long
+do_event_channel_op_compat(
+ XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
extern int
vmx_do_mmu_update(
mmu_update_t *ureqs,
diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h
index e324e693d6..69d7ba793d 100644
--- a/xen/include/asm-x86/hypercall.h
+++ b/xen/include/asm-x86/hypercall.h
@@ -8,6 +8,14 @@
#include <public/physdev.h>
extern long
+do_event_channel_op_compat(
+ XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
+extern long
+do_physdev_op_compat(
+ XEN_GUEST_HANDLE(physdev_op_t) uop);
+
+extern long
do_set_trap_table(
XEN_GUEST_HANDLE(trap_info_t) traps);
@@ -54,7 +62,7 @@ do_update_va_mapping(
extern long
do_physdev_op(
- XEN_GUEST_HANDLE(physdev_op_t) uop);
+ int cmd, XEN_GUEST_HANDLE(void) arg);
extern int
do_update_va_mapping_otherdomain(
diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h
index d79a4bc861..24de420154 100644
--- a/xen/include/public/event_channel.h
+++ b/xen/include/public/event_channel.h
@@ -9,6 +9,13 @@
#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
#define __XEN_PUBLIC_EVENT_CHANNEL_H__
+/*
+ * Prototype for this hypercall is:
+ * int event_channel_op(int cmd, void *args)
+ * @cmd == EVTCHNOP_??? (event-channel operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
typedef uint32_t evtchn_port_t;
DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
@@ -181,6 +188,10 @@ typedef struct evtchn_unmask {
evtchn_port_t port;
} evtchn_unmask_t;
+/*
+ * Argument to event_channel_op_compat() hypercall. Superceded by new
+ * event_channel_op() hypercall since 0x00030202.
+ */
typedef struct evtchn_op {
uint32_t cmd; /* EVTCHNOP_* */
union {
diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h
index e12fafe918..ccb6f87a0b 100644
--- a/xen/include/public/physdev.h
+++ b/xen/include/public/physdev.h
@@ -2,62 +2,128 @@
#ifndef __XEN_PUBLIC_PHYSDEV_H__
#define __XEN_PUBLIC_PHYSDEV_H__
-/* Commands to HYPERVISOR_physdev_op() */
-#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
-#define PHYSDEVOP_IRQ_STATUS_QUERY 5
-#define PHYSDEVOP_SET_IOPL 6
-#define PHYSDEVOP_SET_IOBITMAP 7
-#define PHYSDEVOP_APIC_READ 8
-#define PHYSDEVOP_APIC_WRITE 9
-#define PHYSDEVOP_ASSIGN_VECTOR 10
+/*
+ * Prototype for this hypercall is:
+ * int physdev_op(int cmd, void *args)
+ * @cmd == PHYSDEVOP_??? (physdev operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+/*
+ * Notify end-of-interrupt (EOI) for the specified IRQ.
+ * @arg == pointer to physdev_eoi structure.
+ */
+#define PHYSDEVOP_eoi 12
+typedef struct physdev_eoi {
+ /* IN */
+ uint32_t irq;
+} physdev_eoi_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
-typedef struct physdevop_irq_status_query {
+/*
+ * Query the status of an IRQ line.
+ * @arg == pointer to physdev_irq_status_query structure.
+ */
+#define PHYSDEVOP_irq_status_query 5
+typedef struct physdev_irq_status_query {
/* IN */
uint32_t irq;
/* OUT */
-/* Need to call PHYSDEVOP_IRQ_UNMASK_NOTIFY when the IRQ has been serviced? */
-#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY (1<<0)
- uint32_t flags;
-} physdevop_irq_status_query_t;
+ uint32_t flags; /* XENIRQSTAT_* */
+} physdev_irq_status_query_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
-typedef struct physdevop_set_iopl {
+/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
+#define _XENIRQSTAT_needs_eoi (0)
+#define XENIRQSTAT_needs_eoi (1<<_XENIRQSTAT_needs_eoi)
+
+/*
+ * Set the current VCPU's I/O privilege level.
+ * @arg == pointer to physdev_set_iopl structure.
+ */
+#define PHYSDEVOP_set_iopl 6
+typedef struct physdev_set_iopl {
/* IN */
uint32_t iopl;
-} physdevop_set_iopl_t;
+} physdev_set_iopl_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
-typedef struct physdevop_set_iobitmap {
+/*
+ * Set the current VCPU's I/O-port permissions bitmap.
+ * @arg == pointer to physdev_set_iobitmap structure.
+ */
+#define PHYSDEVOP_set_iobitmap 7
+typedef struct physdev_set_iobitmap {
/* IN */
uint8_t *bitmap;
uint32_t nr_ports;
-} physdevop_set_iobitmap_t;
+} physdev_set_iobitmap_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
-typedef struct physdevop_apic {
+/*
+ * Read or write an IO-APIC register.
+ * @arg == pointer to physdev_apic structure.
+ */
+#define PHYSDEVOP_apic_read 8
+#define PHYSDEVOP_apic_write 9
+typedef struct physdev_apic {
/* IN */
unsigned long apic_physbase;
uint32_t reg;
/* IN or OUT */
uint32_t value;
-} physdevop_apic_t;
+} physdev_apic_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
-typedef struct physdevop_irq {
+/*
+ * Allocate or free a physical upcall vector for the specified IRQ line.
+ * @arg == pointer to physdev_irq structure.
+ */
+#define PHYSDEVOP_alloc_irq_vector 10
+#define PHYSDEVOP_free_irq_vector 11
+typedef struct physdev_irq {
/* IN */
uint32_t irq;
- /* OUT */
+ /* IN or OUT */
uint32_t vector;
-} physdevop_irq_t;
+} physdev_irq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
+/*
+ * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
+ * hypercall since 0x00030202.
+ */
typedef struct physdev_op {
uint32_t cmd;
union {
- physdevop_irq_status_query_t irq_status_query;
- physdevop_set_iopl_t set_iopl;
- physdevop_set_iobitmap_t set_iobitmap;
- physdevop_apic_t apic_op;
- physdevop_irq_t irq_op;
+ physdev_irq_status_query_t irq_status_query;
+ physdev_set_iopl_t set_iopl;
+ physdev_set_iobitmap_t set_iobitmap;
+ physdev_apic_t apic_op;
+ physdev_irq_t irq_op;
} u;
} physdev_op_t;
DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
+/*
+ * Notify that some PIRQ-bound event channels have been unmasked.
+ * ** This command is obsolete since interface version 0x00030202 and is **
+ * ** unsupported by newer versions of Xen. **
+ */
+#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
+
+/*
+ * These all-capitals physdev operation names are superceded by the new names
+ * (defined above) since interface version 0x00030202.
+ */
+#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
+#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
+#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
+#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
+#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
+#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
+#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
+
#endif /* __XEN_PUBLIC_PHYSDEV_H__ */
/*
diff --git a/xen/include/public/xen-compat.h b/xen/include/public/xen-compat.h
index ffea28d520..65cd7443fd 100644
--- a/xen/include/public/xen-compat.h
+++ b/xen/include/public/xen-compat.h
@@ -9,7 +9,7 @@
#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
#define __XEN_PUBLIC_XEN_COMPAT_H__
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030201
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030202
#if defined(__XEN__) || defined(__XEN_TOOLS__)
/* Xen is built with matching headers and implements the latest interface. */
@@ -36,4 +36,12 @@
typedef type * __guest_handle_ ## name
#endif
+/* New event-channel and physdev hypercalls introduced in 0x00030202. */
+#if __XEN_INTERFACE_VERSION__ < 0x00030202
+#undef __HYPERVISOR_event_channel_op
+#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
+#undef __HYPERVISOR_physdev_op
+#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
+#endif
+
#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index a481df3440..75fbcba20c 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -37,7 +37,7 @@
#define __HYPERVISOR_stack_switch 3
#define __HYPERVISOR_set_callbacks 4
#define __HYPERVISOR_fpu_taskswitch 5
-#define __HYPERVISOR_sched_op_compat 6 /* compat as of 0x00030101 */
+#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */
#define __HYPERVISOR_dom0_op 7
#define __HYPERVISOR_set_debugreg 8
#define __HYPERVISOR_get_debugreg 9
@@ -46,10 +46,10 @@
#define __HYPERVISOR_multicall 13
#define __HYPERVISOR_update_va_mapping 14
#define __HYPERVISOR_set_timer_op 15
-#define __HYPERVISOR_event_channel_op 16
+#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
#define __HYPERVISOR_xen_version 17
#define __HYPERVISOR_console_io 18
-#define __HYPERVISOR_physdev_op 19
+#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */
#define __HYPERVISOR_grant_table_op 20
#define __HYPERVISOR_vm_assist 21
#define __HYPERVISOR_update_va_mapping_otherdomain 22
@@ -62,6 +62,8 @@
#define __HYPERVISOR_sched_op 29
#define __HYPERVISOR_callback_op 30
#define __HYPERVISOR_xenoprof_op 31
+#define __HYPERVISOR_event_channel_op 32
+#define __HYPERVISOR_physdev_op 33
/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index b894dd1beb..fcdfba46a6 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -9,6 +9,7 @@
#include <xen/types.h>
#include <xen/time.h>
#include <public/xen.h>
+#include <public/dom0_ops.h>
#include <public/acm_ops.h>
#include <public/event_channel.h>
#include <asm/hypercall.h>
@@ -47,7 +48,7 @@ do_set_timer_op(
extern long
do_event_channel_op(
- XEN_GUEST_HANDLE(evtchn_op_t) uop);
+ int cmd, XEN_GUEST_HANDLE(void) arg);
extern long
do_xen_version(
diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
index 7b1f826198..b3f8f9d548 100644
--- a/xen/include/xen/irq.h
+++ b/xen/include/xen/irq.h
@@ -68,8 +68,9 @@ extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);
struct domain;
struct vcpu;
-extern int pirq_guest_unmask(struct domain *p);
-extern int pirq_guest_bind(struct vcpu *p, int irq, int will_share);
-extern int pirq_guest_unbind(struct domain *p, int irq);
+extern int pirq_guest_eoi(struct domain *d, int irq);
+extern int pirq_guest_unmask(struct domain *d);
+extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share);
+extern int pirq_guest_unbind(struct domain *d, int irq);
#endif /* __XEN_IRQ_H__ */