* [PATCH V2] Implement 3-level event channel in Xen
@ 2013-02-04 17:23 Wei Liu
2013-02-04 17:23 ` [PATCH V2 01/15] Dynamically allocate d->evtchn Wei Liu
` (14 more replies)
0 siblings, 15 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: ian.campbell, jbeulich, david.vrabel
Changes from V1:
* move all evtchn related macros / struct definitions to event.h
* only allow 3-level evtchn for Dom0 and driver domains
* add evtchn_l3 flag in libxl
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH V2 01/15] Dynamically allocate d->evtchn
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 02/15] Move event channel macros / struct definition to proper place Wei Liu
` (13 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
As we move to N level evtchn we need bigger d->evtchn, as a result
this will bloat struct domain. So move this array out of struct domain
and allocate a dedicated page for it.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/common/event_channel.c | 17 +++++++++++++++--
xen/include/xen/sched.h | 2 +-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 9231eb0..3293f91 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -1172,15 +1172,26 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
int evtchn_init(struct domain *d)
{
+ BUILD_BUG_ON(sizeof(struct evtchn *) * NR_EVTCHN_BUCKETS > PAGE_SIZE);
+ d->evtchn = alloc_xenheap_page();
+
+ if ( d->evtchn == NULL )
+ return -ENOMEM;
+ clear_page(d->evtchn);
+
spin_lock_init(&d->event_lock);
- if ( get_free_port(d) != 0 )
+ if ( get_free_port(d) != 0 ) {
+ free_xenheap_page(d->evtchn);
return -EINVAL;
+ }
evtchn_from_port(d, 0)->state = ECS_RESERVED;
#if MAX_VIRT_CPUS > BITS_PER_LONG
d->poll_mask = xmalloc_array(unsigned long, BITS_TO_LONGS(MAX_VIRT_CPUS));
- if ( !d->poll_mask )
+ if ( !d->poll_mask ) {
+ free_xenheap_page(d->evtchn);
return -ENOMEM;
+ }
bitmap_zero(d->poll_mask, MAX_VIRT_CPUS);
#endif
@@ -1214,6 +1225,8 @@ void evtchn_destroy(struct domain *d)
spin_unlock(&d->event_lock);
clear_global_virq_handlers(d);
+
+ free_xenheap_page(d->evtchn);
}
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 39f85d2..ded7a10 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -260,7 +260,7 @@ struct domain
spinlock_t rangesets_lock;
/* Event channel information. */
- struct evtchn *evtchn[NR_EVTCHN_BUCKETS];
+ struct evtchn **evtchn;
spinlock_t event_lock;
struct grant_table *grant_table;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 02/15] Move event channel macros / struct definition to proper place
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
2013-02-04 17:23 ` [PATCH V2 01/15] Dynamically allocate d->evtchn Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 03/15] Add evtchn_level in struct domain Wei Liu
` (12 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
After remove reference to NR_EVTCHN_BUCKETS in struct domain, we can move
those macros / struct definitions to event.h.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/xen/event.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
xen/include/xen/sched.h | 45 ---------------------------------------------
2 files changed, 46 insertions(+), 45 deletions(-)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 65ac81a..a1574ea 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -15,6 +15,52 @@
#include <asm/bitops.h>
#include <asm/event.h>
+#ifndef CONFIG_COMPAT
+#define BITS_PER_EVTCHN_WORD(d) BITS_PER_LONG
+#else
+#define BITS_PER_EVTCHN_WORD(d) (has_32bit_shinfo(d) ? 32 : BITS_PER_LONG)
+#endif
+#define MAX_EVTCHNS(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d))
+
+#define EVTCHNS_PER_BUCKET 128
+#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
+
+struct evtchn
+{
+#define ECS_FREE 0 /* Channel is available for use. */
+#define ECS_RESERVED 1 /* Channel is reserved. */
+#define ECS_UNBOUND 2 /* Channel is waiting to bind to a remote domain. */
+#define ECS_INTERDOMAIN 3 /* Channel is bound to another domain. */
+#define ECS_PIRQ 4 /* Channel is bound to a physical IRQ line. */
+#define ECS_VIRQ 5 /* Channel is bound to a virtual IRQ line. */
+#define ECS_IPI 6 /* Channel is bound to a virtual IPI line. */
+ u8 state; /* ECS_* */
+ u8 xen_consumer; /* Consumer in Xen, if any? (0 = send to guest) */
+ u16 notify_vcpu_id; /* VCPU for local delivery notification */
+ union {
+ struct {
+ domid_t remote_domid;
+ } unbound; /* state == ECS_UNBOUND */
+ struct {
+ u16 remote_port;
+ struct domain *remote_dom;
+ } interdomain; /* state == ECS_INTERDOMAIN */
+ struct {
+ u16 irq;
+ u16 next_port;
+ u16 prev_port;
+ } pirq; /* state == ECS_PIRQ */
+ u16 virq; /* state == ECS_VIRQ */
+ } u;
+#ifdef FLASK_ENABLE
+ void *ssid;
+#endif
+};
+
+int evtchn_init(struct domain *d); /* from domain_create */
+void evtchn_destroy(struct domain *d); /* from domain_kill */
+void evtchn_destroy_final(struct domain *d); /* from complete_domain_destroy */
+
/*
* send_guest_vcpu_virq: Notify guest via a per-VCPU VIRQ.
* @v: VCPU to which virtual IRQ should be sent
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index ded7a10..45ad6bd 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -45,51 +45,6 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
/* A global pointer to the initial domain (DOM0). */
extern struct domain *dom0;
-#ifndef CONFIG_COMPAT
-#define BITS_PER_EVTCHN_WORD(d) BITS_PER_LONG
-#else
-#define BITS_PER_EVTCHN_WORD(d) (has_32bit_shinfo(d) ? 32 : BITS_PER_LONG)
-#endif
-#define MAX_EVTCHNS(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d))
-#define EVTCHNS_PER_BUCKET 128
-#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
-
-struct evtchn
-{
-#define ECS_FREE 0 /* Channel is available for use. */
-#define ECS_RESERVED 1 /* Channel is reserved. */
-#define ECS_UNBOUND 2 /* Channel is waiting to bind to a remote domain. */
-#define ECS_INTERDOMAIN 3 /* Channel is bound to another domain. */
-#define ECS_PIRQ 4 /* Channel is bound to a physical IRQ line. */
-#define ECS_VIRQ 5 /* Channel is bound to a virtual IRQ line. */
-#define ECS_IPI 6 /* Channel is bound to a virtual IPI line. */
- u8 state; /* ECS_* */
- u8 xen_consumer; /* Consumer in Xen, if any? (0 = send to guest) */
- u16 notify_vcpu_id; /* VCPU for local delivery notification */
- union {
- struct {
- domid_t remote_domid;
- } unbound; /* state == ECS_UNBOUND */
- struct {
- u16 remote_port;
- struct domain *remote_dom;
- } interdomain; /* state == ECS_INTERDOMAIN */
- struct {
- u16 irq;
- u16 next_port;
- u16 prev_port;
- } pirq; /* state == ECS_PIRQ */
- u16 virq; /* state == ECS_VIRQ */
- } u;
-#ifdef FLASK_ENABLE
- void *ssid;
-#endif
-};
-
-int evtchn_init(struct domain *d); /* from domain_create */
-void evtchn_destroy(struct domain *d); /* from domain_kill */
-void evtchn_destroy_final(struct domain *d); /* from complete_domain_destroy */
-
struct waitqueue_vcpu;
struct vcpu
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 03/15] Add evtchn_level in struct domain
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
2013-02-04 17:23 ` [PATCH V2 01/15] Dynamically allocate d->evtchn Wei Liu
2013-02-04 17:23 ` [PATCH V2 02/15] Move event channel macros / struct definition to proper place Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 04/15] Bump EVTCHNS_PER_BUCKET to 512 Wei Liu
` (11 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
This field is manipulated by hypervisor only, so if anything goes wrong it is
a bug.
The default event channel is 2, which has two level lookup structure: a
selector in struct vcpu and a shared bitmap in shared info.
The up coming 3-level event channel utilizes three level lookup structure: a
top level selector and second level selector for every vcpu, and shared
bitmap.
When constructing a domain, it starts with 2-level event channel, which is
guaranteed to be supported by the hypervisor. If a domain wants to use N
(N>=3) level event channel, it must explicitly issue a hypercall to setup
N-level event channel.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/common/event_channel.c | 1 +
xen/include/xen/event.h | 16 +++++++++++++++-
xen/include/xen/sched.h | 1 +
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 3293f91..43ee854 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -1180,6 +1180,7 @@ int evtchn_init(struct domain *d)
clear_page(d->evtchn);
spin_lock_init(&d->event_lock);
+ d->evtchn_level = EVTCHN_DEFAULT_LEVEL;
if ( get_free_port(d) != 0 ) {
free_xenheap_page(d->evtchn);
return -EINVAL;
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index a1574ea..b32b06f 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -20,7 +20,21 @@
#else
#define BITS_PER_EVTCHN_WORD(d) (has_32bit_shinfo(d) ? 32 : BITS_PER_LONG)
#endif
-#define MAX_EVTCHNS(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d))
+#define EVTCHN_2_LEVEL 2
+#define EVTCHN_3_LEVEL 3
+#define EVTCHN_DEFAULT_LEVEL EVTCHN_2_LEVEL
+#define MAX_EVTCHNS_L2(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d))
+#define MAX_EVTCHNS_L3(d) (MAX_EVTCHNS_L2(d) * BITS_PER_EVTCHN_WORD(d))
+#define MAX_EVTCHNS(d) ({ int __v = 0; \
+ switch ( d->evtchn_level ) { \
+ case EVTCHN_2_LEVEL: \
+ __v = MAX_EVTCHNS_L2(d); break; \
+ case EVTCHN_3_LEVEL: \
+ __v = MAX_EVTCHNS_L3(d); break; \
+ default: \
+ BUG(); \
+ }; \
+ __v;})
#define EVTCHNS_PER_BUCKET 128
#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 45ad6bd..2f18fe5 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -217,6 +217,7 @@ struct domain
/* Event channel information. */
struct evtchn **evtchn;
spinlock_t event_lock;
+ unsigned int evtchn_level;
struct grant_table *grant_table;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 04/15] Bump EVTCHNS_PER_BUCKET to 512
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (2 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 03/15] Add evtchn_level in struct domain Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 05/15] Add evtchn_is_{pending, masked} and evtchn_clear_pending Wei Liu
` (10 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
For 64 bit build and 3-level event channel and the original value of
EVTCHNS_PER_BUCKET (128), the space needed to accommodate d->evtchn
would be 4 pages (PAGE_SIZE = 4096). Given that not every domain needs
3-level event channel, this leads to waste of memory. Also we've
restricted d->evtchn to one page, if we move to 3-level event channel,
Xen cannot build.
Having EVTCHN_PER_BUCKETS to be 512 can occupy exact one page.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/xen/event.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index b32b06f..59778cf 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -36,7 +36,7 @@
}; \
__v;})
-#define EVTCHNS_PER_BUCKET 128
+#define EVTCHNS_PER_BUCKET 512
#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
struct evtchn
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 05/15] Add evtchn_is_{pending, masked} and evtchn_clear_pending
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (3 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 04/15] Bump EVTCHNS_PER_BUCKET to 512 Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 06/15] Introduce some macros for event channels Wei Liu
` (9 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Some code paths access the arrays in shared info directly. This only
works with 2-level event channel.
Add functions to abstract away implementation details.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/arch/x86/irq.c | 7 +++----
xen/common/event_channel.c | 22 +++++++++++++++++++---
xen/common/keyhandler.c | 6 ++----
xen/common/schedule.c | 2 +-
xen/include/xen/event.h | 6 ++++++
5 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 068c5a0..216271b 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1452,7 +1452,7 @@ int pirq_guest_unmask(struct domain *d)
{
pirq = pirqs[i]->pirq;
if ( pirqs[i]->masked &&
- !test_bit(pirqs[i]->evtchn, &shared_info(d, evtchn_mask)) )
+ !evtchn_is_masked(d, pirqs[i]->evtchn) )
pirq_guest_eoi(pirqs[i]);
}
} while ( ++pirq < d->nr_pirqs && n == ARRAY_SIZE(pirqs) );
@@ -2093,13 +2093,12 @@ static void dump_irqs(unsigned char key)
info = pirq_info(d, pirq);
printk("%u:%3d(%c%c%c%c)",
d->domain_id, pirq,
- (test_bit(info->evtchn,
- &shared_info(d, evtchn_pending)) ?
+ (evtchn_is_pending(d, info->evtchn) ?
'P' : '-'),
(test_bit(info->evtchn / BITS_PER_EVTCHN_WORD(d),
&vcpu_info(d->vcpu[0], evtchn_pending_sel)) ?
'S' : '-'),
- (test_bit(info->evtchn, &shared_info(d, evtchn_mask)) ?
+ (evtchn_is_masked(d, info->evtchn) ?
'M' : '-'),
(info->masked ? 'M' : '-'));
if ( i != action->nr_guests )
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 43ee854..37fecee 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -95,6 +95,7 @@ static uint8_t get_xen_consumer(xen_event_channel_notification_t fn)
#define xen_notification_fn(e) (xen_consumers[(e)->xen_consumer-1])
static void evtchn_set_pending(struct vcpu *v, int port);
+static void evtchn_clear_pending(struct domain *d, int port);
static int virq_is_global(uint32_t virq)
{
@@ -156,6 +157,16 @@ static int get_free_port(struct domain *d)
return port;
}
+int evtchn_is_pending(struct domain *d, int port)
+{
+ return test_bit(port, &shared_info(d, evtchn_pending));
+}
+
+int evtchn_is_masked(struct domain *d, int port)
+{
+ return test_bit(port, &shared_info(d, evtchn_mask));
+}
+
static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
{
@@ -529,7 +540,7 @@ static long __evtchn_close(struct domain *d1, int port1)
}
/* Clear pending event to avoid unexpected behavior on re-bind. */
- clear_bit(port1, &shared_info(d1, evtchn_pending));
+ evtchn_clear_pending(d1, port1);
/* Reset binding to vcpu0 when the channel is freed. */
chn1->state = ECS_FREE;
@@ -653,6 +664,11 @@ static void evtchn_set_pending(struct vcpu *v, int port)
}
}
+static void evtchn_clear_pending(struct domain *d, int port)
+{
+ clear_bit(port, &shared_info(d, evtchn_pending));
+}
+
int guest_enabled_event(struct vcpu *v, uint32_t virq)
{
return ((v != NULL) && (v->virq_to_evtchn[virq] != 0));
@@ -1283,8 +1299,8 @@ static void domain_dump_evtchn_info(struct domain *d)
printk(" %4u [%d/%d]: s=%d n=%d x=%d",
port,
- !!test_bit(port, &shared_info(d, evtchn_pending)),
- !!test_bit(port, &shared_info(d, evtchn_mask)),
+ !!evtchn_is_pending(d, port),
+ !!evtchn_is_masked(d, port),
chn->state, chn->notify_vcpu_id, chn->xen_consumer);
switch ( chn->state )
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 2c5c230..16bc452 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -301,10 +301,8 @@ static void dump_domains(unsigned char key)
printk("Notifying guest %d:%d (virq %d, port %d, stat %d/%d/%d)\n",
d->domain_id, v->vcpu_id,
VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
- test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
- &shared_info(d, evtchn_pending)),
- test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
- &shared_info(d, evtchn_mask)),
+ evtchn_is_pending(d, v->virq_to_evtchn[VIRQ_DEBUG]),
+ evtchn_is_masked(d, v->virq_to_evtchn[VIRQ_DEBUG]),
test_bit(v->virq_to_evtchn[VIRQ_DEBUG] /
BITS_PER_EVTCHN_WORD(d),
&vcpu_info(v, evtchn_pending_sel)));
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index e6a90d8..1bf010e 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -693,7 +693,7 @@ static long do_poll(struct sched_poll *sched_poll)
goto out;
rc = 0;
- if ( test_bit(port, &shared_info(d, evtchn_pending)) )
+ if ( evtchn_is_pending(d, port) )
goto out;
}
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 59778cf..1021a1a 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -114,6 +114,12 @@ int evtchn_unmask(unsigned int port);
/* Move all PIRQs after a vCPU was moved to another pCPU. */
void evtchn_move_pirqs(struct vcpu *v);
+/* Tell a given event-channel port is pending or not */
+int evtchn_is_pending(struct domain *d, int port);
+
+/* Tell a given event-channel port is masked or not */
+int evtchn_is_masked(struct domain *d, int port);
+
/* Allocate/free a Xen-attached event channel port. */
typedef void (*xen_event_channel_notification_t)(
struct vcpu *v, unsigned int port);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 06/15] Introduce some macros for event channels
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (4 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 05/15] Add evtchn_is_{pending, masked} and evtchn_clear_pending Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 07/15] Update Xen public header Wei Liu
` (8 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
For N-level event channels, the shared bitmaps in the hypervisor are by design
not guaranteed to be contigious.
These macros are used to calculate page number / offset within a page of a
given event channel.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/asm-arm/types.h | 7 +++++--
xen/include/asm-x86/config.h | 4 +++-
xen/include/xen/event.h | 13 +++++++++++++
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/xen/include/asm-arm/types.h b/xen/include/asm-arm/types.h
index 48864f9..65562b8 100644
--- a/xen/include/asm-arm/types.h
+++ b/xen/include/asm-arm/types.h
@@ -41,10 +41,13 @@ typedef char bool_t;
#define test_and_clear_bool(b) xchg(&(b), 0)
#endif /* __ASSEMBLY__ */
+#define BYTE_BITORDER 3
+#define BITS_PER_BYTE (1 << BYTE_BITORDER)
-#define BITS_PER_LONG 32
-#define BYTES_PER_LONG 4
+#define BITS_PER_LONG (1 << LONG_BITORDER)
#define LONG_BYTEORDER 2
+#define LONG_BITORDER (LONG_BYTEORDER + BYTE_BITORDER)
+#define BYTES_PER_LONG (1 << LONG_BYTEORDER)
#endif /* __ARM_TYPES_H__ */
/*
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index da82e73..b921586 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -8,11 +8,13 @@
#define __X86_CONFIG_H__
#define LONG_BYTEORDER 3
+#define BYTE_BITORDER 3
+#define LONG_BITORDER (BYTE_BITORDER + LONG_BYTEORDER)
#define CONFIG_PAGING_LEVELS 4
#define BYTES_PER_LONG (1 << LONG_BYTEORDER)
#define BITS_PER_LONG (BYTES_PER_LONG << 3)
-#define BITS_PER_BYTE 8
+#define BITS_PER_BYTE (1 << BYTE_BITORDER)
#define CONFIG_X86 1
#define CONFIG_X86_HT 1
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 1021a1a..4474296 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -39,6 +39,19 @@
#define EVTCHNS_PER_BUCKET 512
#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
+/* N.B. EVTCHNS_PER_PAGE is always powers of 2, use shifts to optimize */
+#define EVTCHNS_SHIFT (PAGE_SHIFT+BYTE_BITORDER)
+#define EVTCHNS_PER_PAGE (_AC(1,L) << EVTCHNS_SHIFT)
+#define EVTCHN_MASK (~(EVTCHNS_PER_PAGE-1))
+#define EVTCHN_PAGE_NO(chn) ((chn) >> EVTCHNS_SHIFT)
+#define EVTCHN_OFFSET_IN_PAGE(chn) ((chn) & ~EVTCHN_MASK)
+
+#ifndef CONFIG_COMPAT
+#define EVTCHN_WORD_BITORDER(d) LONG_BITORDER
+#else
+#define EVTCHN_WORD_BITORDER(d) (has_32bit_shinfo(d) ? 5 : LONG_BITORDER)
+#endif
+
struct evtchn
{
#define ECS_FREE 0 /* Channel is available for use. */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 07/15] Update Xen public header
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (5 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 06/15] Introduce some macros for event channels Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 08/15] Define N-level event channel registration interface Wei Liu
` (7 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/public/xen.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index fe44eb5..ba5d045 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -554,9 +554,16 @@ DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);
/*
* Event channel endpoints per domain:
+ * 2-level:
* 1024 if a long is 32 bits; 4096 if a long is 64 bits.
+ * 3-level:
+ * 32k if a long is 32 bits; 256k if a long is 64 bits.
*/
-#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
+#define NR_EVENT_CHANNELS_L2 (sizeof(unsigned long) * sizeof(unsigned long) * 64)
+#define NR_EVENT_CHANNELS_L3 (NR_EVENT_CHANNELS_L2 * 64)
+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
+#define NR_EVENT_CHANNELS NR_EVENT_CHANNELS_L2 /* for compatibility */
+#endif
struct vcpu_time_info {
/*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 08/15] Define N-level event channel registration interface
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (6 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 07/15] Update Xen public header Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 09/15] Add control structures for 3-level event channel Wei Liu
` (6 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/public/event_channel.h | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h
index 07ff321..f26d6d5 100644
--- a/xen/include/public/event_channel.h
+++ b/xen/include/public/event_channel.h
@@ -71,6 +71,7 @@
#define EVTCHNOP_bind_vcpu 8
#define EVTCHNOP_unmask 9
#define EVTCHNOP_reset 10
+#define EVTCHNOP_register_nlevel 11
/* ` } */
typedef uint32_t evtchn_port_t;
@@ -258,6 +259,38 @@ struct evtchn_reset {
typedef struct evtchn_reset evtchn_reset_t;
/*
+ * EVTCHNOP_register_nlevel: Register N-level event channel
+ * NOTES:
+ * 1. Currently only 3-level is supported.
+ * 2. Should fall back to 2-level if this call fails.
+ */
+/* 64 bit guests need 8 pages for evtchn_pending and evtchn_mask for
+ * 256k event channels while 32 bit ones only need 1 page for 32k
+ * event channels. */
+#define EVTCHN_MAX_L3_PAGES 8
+struct evtchn_register_3level {
+ /* IN parameters. */
+ uint32_t nr_pages; /* for evtchn_{pending,mask} */
+ uint32_t nr_vcpus; /* for l2sel_{mfns,offsets} */
+ XEN_GUEST_HANDLE(xen_pfn_t) evtchn_pending;
+ XEN_GUEST_HANDLE(xen_pfn_t) evtchn_mask;
+ XEN_GUEST_HANDLE(xen_pfn_t) l2sel_mfns;
+ XEN_GUEST_HANDLE(xen_pfn_t) l2sel_offsets;
+};
+typedef struct evtchn_register_3level evtchn_register_3level_t;
+DEFINE_XEN_GUEST_HANDLE(evtchn_register_3level_t);
+
+struct evtchn_register_nlevel {
+ /* IN parameters. */
+ uint32_t level;
+ union {
+ evtchn_register_3level_t l3;
+ } u;
+};
+typedef struct evtchn_register_nlevel evtchn_register_nlevel_t;
+DEFINE_XEN_GUEST_HANDLE(evtchn_register_nlevel_t);
+
+/*
* ` enum neg_errnoval
* ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op)
* `
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 09/15] Add control structures for 3-level event channel
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (7 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 08/15] Define N-level event channel registration interface Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 10/15] Make NR_EVTCHN_BUCKETS 3-level ready Wei Liu
` (5 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
The references to shared bitmap pending / mask are embedded in struct domain.
And pointer to the second level selector is embedded in struct vcpu.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/xen/sched.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 2f18fe5..1d8c1b5 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -24,6 +24,7 @@
#include <public/sysctl.h>
#include <public/vcpu.h>
#include <public/mem_event.h>
+#include <public/event_channel.h>
#ifdef CONFIG_COMPAT
#include <compat/vcpu.h>
@@ -57,6 +58,9 @@ struct vcpu
struct domain *domain;
+ /* For 3-level event channels */
+ unsigned long *evtchn_pending_sel_l2;
+
struct vcpu *next_in_list;
s_time_t periodic_period;
@@ -218,6 +222,8 @@ struct domain
struct evtchn **evtchn;
spinlock_t event_lock;
unsigned int evtchn_level;
+ unsigned long *evtchn_pending[EVTCHN_MAX_L3_PAGES];
+ unsigned long *evtchn_mask[EVTCHN_MAX_L3_PAGES];
struct grant_table *grant_table;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 10/15] Make NR_EVTCHN_BUCKETS 3-level ready
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (8 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 09/15] Add control structures for 3-level event channel Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 11/15] Genneralized event channel operations Wei Liu
` (4 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/include/xen/event.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 4474296..9640a8c 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -37,7 +37,7 @@
__v;})
#define EVTCHNS_PER_BUCKET 512
-#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
+#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS_L3 / EVTCHNS_PER_BUCKET)
/* N.B. EVTCHNS_PER_PAGE is always powers of 2, use shifts to optimize */
#define EVTCHNS_SHIFT (PAGE_SHIFT+BYTE_BITORDER)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 11/15] Genneralized event channel operations
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (9 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 10/15] Make NR_EVTCHN_BUCKETS 3-level ready Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 12/15] Infrastructure for manipulating 3-level event channel pages Wei Liu
` (3 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Use pointer in struct domain to reference evtchn_pending and evtchn_mask
bitmaps.
When building a domain, the default operation set is 2-level operation
set.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/arch/arm/domain.c | 1 +
xen/arch/x86/domain.c | 1 +
xen/common/event_channel.c | 65 ++++++++++++++++++++++++++++++++++++--------
xen/include/xen/event.h | 3 ++
4 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 59d8d73..bc477f6 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -417,6 +417,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
goto fail;
clear_page(d->shared_info);
+ evtchn_set_default_bitmap(d);
share_xen_page_with_guest(
virt_to_page(d->shared_info), d, XENSHARE_writable);
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index a58cc1a..a669dc0 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -580,6 +580,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
goto fail;
clear_page(d->shared_info);
+ evtchn_set_default_bitmap(d);
share_xen_page_with_guest(
virt_to_page(d->shared_info), d, XENSHARE_writable);
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 37fecee..1ce97b0 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -51,6 +51,9 @@
#define consumer_is_xen(e) (!!(e)->xen_consumer)
+static void evtchn_set_pending(struct vcpu *v, int port);
+static void evtchn_clear_pending(struct domain *d, int port);
+
/*
* The function alloc_unbound_xen_event_channel() allows an arbitrary
* notifier function to be specified. However, very few unique functions
@@ -94,9 +97,6 @@ static uint8_t get_xen_consumer(xen_event_channel_notification_t fn)
/* Get the notification function for a given Xen-bound event channel. */
#define xen_notification_fn(e) (xen_consumers[(e)->xen_consumer-1])
-static void evtchn_set_pending(struct vcpu *v, int port);
-static void evtchn_clear_pending(struct domain *d, int port);
-
static int virq_is_global(uint32_t virq)
{
int rc;
@@ -159,15 +159,18 @@ static int get_free_port(struct domain *d)
int evtchn_is_pending(struct domain *d, int port)
{
- return test_bit(port, &shared_info(d, evtchn_pending));
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
+ return test_bit(offset, d->evtchn_pending[page_no]);
}
int evtchn_is_masked(struct domain *d, int port)
{
- return test_bit(port, &shared_info(d, evtchn_mask));
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
+ return test_bit(offset, d->evtchn_mask[page_no]);
}
-
static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
{
struct evtchn *chn;
@@ -623,7 +626,7 @@ out:
return ret;
}
-static void evtchn_set_pending(struct vcpu *v, int port)
+static void evtchn_set_pending_l2(struct vcpu *v, int port)
{
struct domain *d = v->domain;
int vcpuid;
@@ -664,9 +667,25 @@ static void evtchn_set_pending(struct vcpu *v, int port)
}
}
+static void evtchn_set_pending(struct vcpu *v, int port)
+{
+ struct domain *d = v->domain;
+
+ switch ( d->evtchn_level )
+ {
+ case EVTCHN_2_LEVEL:
+ evtchn_set_pending_l2(v, port);
+ break;
+ default:
+ BUG();
+ }
+}
+
static void evtchn_clear_pending(struct domain *d, int port)
{
- clear_bit(port, &shared_info(d, evtchn_pending));
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
+ clear_bit(offset, d->evtchn_pending[page_no]);
}
int guest_enabled_event(struct vcpu *v, uint32_t virq)
@@ -932,10 +951,12 @@ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id)
}
-int evtchn_unmask(unsigned int port)
+static int evtchn_unmask_l2(unsigned int port)
{
struct domain *d = current->domain;
struct vcpu *v;
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
ASSERT(spin_is_locked(&d->event_lock));
@@ -948,8 +969,8 @@ int evtchn_unmask(unsigned int port)
* These operations must happen in strict order. Based on
* include/xen/event.h:evtchn_set_pending().
*/
- if ( test_and_clear_bit(port, &shared_info(d, evtchn_mask)) &&
- test_bit (port, &shared_info(d, evtchn_pending)) &&
+ if ( test_and_clear_bit(offset, d->evtchn_mask[page_no]) &&
+ test_bit (offset, d->evtchn_pending[page_no]) &&
!test_and_set_bit (port / BITS_PER_EVTCHN_WORD(d),
&vcpu_info(v, evtchn_pending_sel)) )
{
@@ -959,6 +980,23 @@ int evtchn_unmask(unsigned int port)
return 0;
}
+int evtchn_unmask(unsigned int port)
+{
+ struct domain *d = current->domain;
+ int rc = 0;
+
+ switch ( d->evtchn_level )
+ {
+ case EVTCHN_2_LEVEL:
+ rc = evtchn_unmask_l2(port);
+ break;
+ default:
+ BUG();
+ }
+
+ return rc;
+}
+
static long evtchn_reset(evtchn_reset_t *r)
{
@@ -1185,6 +1223,11 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
spin_unlock(&ld->event_lock);
}
+void evtchn_set_default_bitmap(struct domain *d)
+{
+ d->evtchn_pending[0] = (unsigned long *)shared_info(d, evtchn_pending);
+ d->evtchn_mask[0] = (unsigned long *)shared_info(d, evtchn_mask);
+}
int evtchn_init(struct domain *d)
{
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 9640a8c..5fe4149 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -148,6 +148,9 @@ int guest_enabled_event(struct vcpu *v, uint32_t virq);
/* Notify remote end of a Xen-attached event channel.*/
void notify_via_xen_event_channel(struct domain *ld, int lport);
+/* This is called after domain's shared info page is setup */
+void evtchn_set_default_bitmap(struct domain *d);
+
/* Internal event channel object accessors */
#define bucket_from_port(d,p) \
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 12/15] Infrastructure for manipulating 3-level event channel pages
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (10 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 11/15] Genneralized event channel operations Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 13/15] Implement 3-level event channel routines Wei Liu
` (2 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
NOTE: the registration call is always failed because other part of the code is
not yet completed.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/common/event_channel.c | 280 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 280 insertions(+)
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 1ce97b0..411bef8 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -26,6 +26,7 @@
#include <xen/compat.h>
#include <xen/guest_access.h>
#include <xen/keyhandler.h>
+#include <xen/paging.h>
#include <asm/current.h>
#include <public/xen.h>
@@ -1024,6 +1025,260 @@ out:
}
+static long __map_l3_arrays(struct domain *d, xen_pfn_t *pending,
+ xen_pfn_t *mask, int nr_pages)
+{
+ int rc;
+ void *mapping;
+ struct page_info *pginfo;
+ unsigned long gfn;
+ int pending_count = 0, mask_count = 0;
+
+#define __MAP(src, dst, cnt) \
+ for ( (cnt) = 0; (cnt) < nr_pages; (cnt)++ ) \
+ { \
+ rc = -EINVAL; \
+ gfn = (src)[(cnt)]; \
+ pginfo = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC); \
+ if ( !pginfo ) \
+ goto err; \
+ if ( !get_page_type(pginfo, PGT_writable_page) ) \
+ { \
+ put_page(pginfo); \
+ goto err; \
+ } \
+ mapping = __map_domain_page_global(pginfo); \
+ if ( !mapping ) \
+ { \
+ put_page_and_type(pginfo); \
+ rc = -ENOMEM; \
+ goto err; \
+ } \
+ (dst)[(cnt)] = mapping; \
+ }
+
+ __MAP(pending, d->evtchn_pending, pending_count)
+ __MAP(mask, d->evtchn_mask, mask_count)
+#undef __MAP
+
+ rc = 0;
+
+ err:
+ return rc;
+}
+
+static void __unmap_l3_arrays(struct domain *d)
+{
+ int i;
+ unsigned long mfn;
+
+ for ( i = 0; i < EVTCHN_MAX_L3_PAGES; i++ )
+ {
+ if ( d->evtchn_pending[i] != 0 )
+ {
+ mfn = domain_page_map_to_mfn(d->evtchn_pending[i]);
+ unmap_domain_page_global(d->evtchn_pending[i]);
+ put_page_and_type(mfn_to_page(mfn));
+ d->evtchn_pending[i] = 0;
+ }
+ if ( d->evtchn_mask[i] != 0 )
+ {
+ mfn = domain_page_map_to_mfn(d->evtchn_mask[i]);
+ unmap_domain_page_global(d->evtchn_mask[i]);
+ put_page_and_type(mfn_to_page(mfn));
+ d->evtchn_mask[i] = 0;
+ }
+ }
+}
+
+static long __map_l2_selector(struct vcpu *v, unsigned long gfn,
+ unsigned long off)
+{
+ void *mapping;
+ int rc;
+ struct page_info *page;
+ struct domain *d = v->domain;
+
+ rc = -EINVAL; /* common errno for following operations */
+
+ /* Sanity check: L2 selector has maximum size of sizeof(unsigned
+ * long) * 8, this size is equal to the size of shared bitmap
+ * array of 2-level event channel. */
+ if ( off + sizeof(unsigned long) * 8 >= PAGE_SIZE )
+ goto out;
+
+ page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
+ if ( !page )
+ goto out;
+
+ if ( !get_page_type(page, PGT_writable_page) )
+ {
+ put_page(page);
+ goto out;
+ }
+
+ /* Use global mapping here, because these selectors will also be
+ * accessed by other domains when setting pending for inter-domain
+ * event channels.
+ */
+ mapping = __map_domain_page_global(page);
+
+ if ( mapping == NULL )
+ {
+ put_page_and_type(page);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ v->evtchn_pending_sel_l2 = mapping + off;
+ rc = 0;
+
+ out:
+ return rc;
+}
+
+static void __unmap_l2_selector(struct vcpu *v)
+{
+ unsigned long mfn;
+
+ if ( v->evtchn_pending_sel_l2 )
+ {
+ mfn = domain_page_map_to_mfn(v->evtchn_pending_sel_l2);
+ unmap_domain_page_global(v->evtchn_pending_sel_l2);
+ put_page_and_type(mfn_to_page(mfn));
+ v->evtchn_pending_sel_l2 = NULL;
+ }
+}
+
+static void __evtchn_unmap_all_3level(struct domain *d)
+{
+ struct vcpu *v;
+ for_each_vcpu ( d, v )
+ __unmap_l2_selector(v);
+ __unmap_l3_arrays(d);
+}
+
+static void __evtchn_setup_bitmap_l3(struct domain *d)
+{
+ struct vcpu *v;
+
+ /* Easy way to setup 3-level bitmap, just move existing selector
+ * to next level then copy pending array and mask array */
+ for_each_vcpu ( d, v )
+ {
+ memcpy(&v->evtchn_pending_sel_l2[0],
+ &vcpu_info(v, evtchn_pending_sel),
+ sizeof(vcpu_info(v, evtchn_pending_sel)));
+ memset(&vcpu_info(v, evtchn_pending_sel), 0,
+ sizeof(vcpu_info(v, evtchn_pending_sel)));
+ set_bit(0, &vcpu_info(v, evtchn_pending_sel));
+ }
+
+ memcpy(d->evtchn_pending[0], &shared_info(d, evtchn_pending),
+ sizeof(shared_info(d, evtchn_pending)));
+ memcpy(d->evtchn_mask[0], &shared_info(d, evtchn_mask),
+ sizeof(shared_info(d, evtchn_mask)));
+}
+
+static long evtchn_register_3level(evtchn_register_3level_t *arg)
+{
+ struct domain *d = current->domain;
+ struct vcpu *v;
+ int rc = 0;
+ xen_pfn_t evtchn_pending[EVTCHN_MAX_L3_PAGES];
+ xen_pfn_t evtchn_mask[EVTCHN_MAX_L3_PAGES];
+ xen_pfn_t l2sel_mfn = 0;
+ xen_pfn_t l2sel_offset = 0;
+
+ if ( d->evtchn_level == EVTCHN_3_LEVEL )
+ {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if ( arg->nr_vcpus > d->max_vcpus ||
+ arg->nr_pages > EVTCHN_MAX_L3_PAGES )
+ {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ memset(evtchn_pending, 0, sizeof(xen_pfn_t) * EVTCHN_MAX_L3_PAGES);
+ memset(evtchn_mask, 0, sizeof(xen_pfn_t) * EVTCHN_MAX_L3_PAGES);
+
+ rc = -EFAULT; /* common error code for following operations */
+ if ( copy_from_guest(evtchn_pending, arg->evtchn_pending, arg->nr_pages) )
+ goto out;
+ if ( copy_from_guest(evtchn_mask, arg->evtchn_mask, arg->nr_pages) )
+ goto out;
+
+ rc = __map_l3_arrays(d, evtchn_pending, evtchn_mask, arg->nr_pages);
+ if ( rc )
+ goto out;
+
+ for_each_vcpu ( d, v )
+ {
+ int vcpu_id = v->vcpu_id;
+
+ rc = -EFAULT; /* common error code for following operations */
+ if ( unlikely(copy_from_guest_offset(&l2sel_mfn, arg->l2sel_mfns,
+ vcpu_id, 1)) )
+ {
+ __evtchn_unmap_all_3level(d);
+ goto out;
+ }
+ if ( unlikely(copy_from_guest_offset(&l2sel_offset, arg->l2sel_offsets,
+ vcpu_id, 1)) )
+ {
+ __evtchn_unmap_all_3level(d);
+ goto out;
+ }
+
+ if ( (rc = __map_l2_selector(v, l2sel_mfn, l2sel_offset)) )
+ {
+ __evtchn_unmap_all_3level(d);
+ goto out;
+ }
+ }
+
+ __evtchn_setup_bitmap_l3(d);
+
+ d->evtchn_level = EVTCHN_3_LEVEL;
+
+ rc = 0;
+
+ out:
+ return rc;
+}
+
+/*
+ * NOTE to N-level event channel users:
+ * N-level channels are likely to consume lots large global mapping
+ * area in Xen. For example, 3-level event channel consumes 16 +
+ * nr_vcpus pages global mapping area. So *ONLY* enable N-level event
+ * channel for Dom0 or driver domains.
+ */
+static long evtchn_register_nlevel(struct evtchn_register_nlevel *reg)
+{
+ struct domain *d = current->domain;
+ int rc;
+
+ spin_lock(&d->event_lock);
+
+ switch ( reg->level )
+ {
+ case EVTCHN_3_LEVEL:
+ rc = evtchn_register_3level(®->u.l3);
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ spin_unlock(&d->event_lock);
+
+ return rc;
+}
+
long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
{
long rc;
@@ -1132,6 +1387,18 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
+ case EVTCHNOP_register_nlevel: {
+ struct evtchn_register_nlevel reg;
+ if ( copy_from_guest(®, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_register_nlevel(®);
+
+ /* XXX always fails this call because it is not yet completed */
+ rc = -EINVAL;
+
+ break;
+ }
+
default:
rc = -ENOSYS;
break;
@@ -1258,6 +1525,17 @@ int evtchn_init(struct domain *d)
return 0;
}
+static void evtchn_unmap_nlevel(struct domain *d)
+{
+ switch ( d->evtchn_level )
+ {
+ case EVTCHN_3_LEVEL:
+ __evtchn_unmap_all_3level(d);
+ break;
+ default:
+ break;
+ }
+}
void evtchn_destroy(struct domain *d)
{
@@ -1286,6 +1564,8 @@ void evtchn_destroy(struct domain *d)
clear_global_virq_handlers(d);
+ evtchn_unmap_nlevel(d);
+
free_xenheap_page(d->evtchn);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 13/15] Implement 3-level event channel routines
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (11 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 12/15] Infrastructure for manipulating 3-level event channel pages Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-04 17:23 ` [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain Wei Liu
2013-02-04 17:23 ` [PATCH V2 15/15] libxl: add evtchn_l3 flag Wei Liu
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/common/event_channel.c | 110 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 90 insertions(+), 20 deletions(-)
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 411bef8..a91ecba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -627,10 +627,33 @@ out:
return ret;
}
+static void __check_vcpu_polling(struct vcpu *v, int port)
+{
+ int vcpuid;
+ struct domain *d = v->domain;
+
+ /* Check if some VCPU might be polling for this event. */
+ if ( likely(bitmap_empty(d->poll_mask, d->max_vcpus)) )
+ return;
+
+ /* Wake any interested (or potentially interested) pollers. */
+ for ( vcpuid = find_first_bit(d->poll_mask, d->max_vcpus);
+ vcpuid < d->max_vcpus;
+ vcpuid = find_next_bit(d->poll_mask, d->max_vcpus, vcpuid+1) )
+ {
+ v = d->vcpu[vcpuid];
+ if ( ((v->poll_evtchn <= 0) || (v->poll_evtchn == port)) &&
+ test_and_clear_bit(vcpuid, d->poll_mask) )
+ {
+ v->poll_evtchn = 0;
+ vcpu_unblock(v);
+ }
+ }
+}
+
static void evtchn_set_pending_l2(struct vcpu *v, int port)
{
struct domain *d = v->domain;
- int vcpuid;
/*
* The following bit operations must happen in strict order.
@@ -649,23 +672,35 @@ static void evtchn_set_pending_l2(struct vcpu *v, int port)
vcpu_mark_events_pending(v);
}
- /* Check if some VCPU might be polling for this event. */
- if ( likely(bitmap_empty(d->poll_mask, d->max_vcpus)) )
- return;
+ __check_vcpu_polling(v, port);
+}
- /* Wake any interested (or potentially interested) pollers. */
- for ( vcpuid = find_first_bit(d->poll_mask, d->max_vcpus);
- vcpuid < d->max_vcpus;
- vcpuid = find_next_bit(d->poll_mask, d->max_vcpus, vcpuid+1) )
+static void evtchn_set_pending_l3(struct vcpu *v, int port)
+{
+ struct domain *d = v->domain;
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
+ unsigned int l1bit = port >> (EVTCHN_WORD_BITORDER(d) << 1);
+ unsigned int l2bit = port >> EVTCHN_WORD_BITORDER(d);
+
+ /*
+ * The following bit operations must happen in strict order.
+ * NB. On x86, the atomic bit operations also act as memory barriers.
+ * There is therefore sufficiently strict ordering for this architecture --
+ * others may require explicit memory barriers.
+ */
+
+ if ( test_and_set_bit(offset, d->evtchn_pending[page_no]) )
+ return;
+
+ if ( !test_bit(offset, d->evtchn_mask[page_no]) &&
+ !test_and_set_bit(l2bit, v->evtchn_pending_sel_l2) &&
+ !test_and_set_bit(l1bit, &vcpu_info(v, evtchn_pending_sel)) )
{
- v = d->vcpu[vcpuid];
- if ( ((v->poll_evtchn <= 0) || (v->poll_evtchn == port)) &&
- test_and_clear_bit(vcpuid, d->poll_mask) )
- {
- v->poll_evtchn = 0;
- vcpu_unblock(v);
- }
+ vcpu_mark_events_pending(v);
}
+
+ __check_vcpu_polling(v, port);
}
static void evtchn_set_pending(struct vcpu *v, int port)
@@ -677,6 +712,9 @@ static void evtchn_set_pending(struct vcpu *v, int port)
case EVTCHN_2_LEVEL:
evtchn_set_pending_l2(v, port);
break;
+ case 3:
+ evtchn_set_pending_l3(v, port);
+ break;
default:
BUG();
}
@@ -981,6 +1019,37 @@ static int evtchn_unmask_l2(unsigned int port)
return 0;
}
+static int evtchn_unmask_l3(unsigned int port)
+{
+ struct domain *d = current->domain;
+ struct vcpu *v;
+ unsigned int page_no = EVTCHN_PAGE_NO(port);
+ unsigned int offset = EVTCHN_OFFSET_IN_PAGE(port);
+ unsigned int l1bit = port >> (EVTCHN_WORD_BITORDER(d) << 1);
+ unsigned int l2bit = port >> EVTCHN_WORD_BITORDER(d);
+
+ ASSERT(spin_is_locked(&d->event_lock));
+
+ if ( unlikely(!port_is_valid(d, port)) )
+ return -EINVAL;
+
+ v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id];
+
+ /*
+ * These operations must happen in strict order. Based on
+ * include/xen/event.h:evtchn_set_pending().
+ */
+ if ( test_and_clear_bit(offset, d->evtchn_mask[page_no]) &&
+ test_bit (offset, d->evtchn_pending[page_no]) &&
+ !test_and_set_bit (l2bit, v->evtchn_pending_sel_l2) &&
+ !test_and_set_bit (l1bit, &vcpu_info(v, evtchn_pending_sel)) )
+ {
+ vcpu_mark_events_pending(v);
+ }
+
+ return 0;
+}
+
int evtchn_unmask(unsigned int port)
{
struct domain *d = current->domain;
@@ -991,6 +1060,9 @@ int evtchn_unmask(unsigned int port)
case EVTCHN_2_LEVEL:
rc = evtchn_unmask_l2(port);
break;
+ case 3:
+ rc = evtchn_unmask_l3(port);
+ break;
default:
BUG();
}
@@ -1392,10 +1464,6 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( copy_from_guest(®, arg, 1) != 0 )
return -EFAULT;
rc = evtchn_register_nlevel(®);
-
- /* XXX always fails this call because it is not yet completed */
- rc = -EINVAL;
-
break;
}
@@ -1604,8 +1672,10 @@ static void domain_dump_evtchn_info(struct domain *d)
bitmap_scnlistprintf(keyhandler_scratch, sizeof(keyhandler_scratch),
d->poll_mask, d->max_vcpus);
printk("Event channel information for domain %d:\n"
+ "Using %d-level event channel\n"
"Polling vCPUs: {%s}\n"
- " port [p/m]\n", d->domain_id, keyhandler_scratch);
+ " port [p/m]\n",
+ d->domain_id, d->evtchn_level, keyhandler_scratch);
spin_lock(&d->event_lock);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (12 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 13/15] Implement 3-level event channel routines Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
2013-02-06 8:28 ` Jan Beulich
2013-02-04 17:23 ` [PATCH V2 15/15] libxl: add evtchn_l3 flag Wei Liu
14 siblings, 1 reply; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
For non-Dom0 domains, add a flag to indicate whether it can use 3-level event
channel, admins can specify this flag when creating a driver domain.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/common/domain.c | 3 +++
xen/common/domctl.c | 5 ++++-
xen/common/event_channel.c | 3 +++
xen/include/public/domctl.h | 3 +++
xen/include/xen/sched.h | 5 +++++
5 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 07f62b3..28405b8 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -250,6 +250,9 @@ struct domain *domain_create(
if ( domcr_flags & DOMCRF_dummy )
return d;
+ if ( domcr_flags & DOMCRF_evtchn_l3 )
+ d->evtchn_l3 = 1;
+
if ( !is_idle_domain(d) )
{
if ( (err = xsm_domain_create(XSM_HOOK, d, ssidref)) != 0 )
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index a713ce6..fb61e40 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -369,7 +369,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
if ( supervisor_mode_kernel ||
(op->u.createdomain.flags &
~(XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap |
- XEN_DOMCTL_CDF_s3_integrity | XEN_DOMCTL_CDF_oos_off)) )
+ XEN_DOMCTL_CDF_s3_integrity | XEN_DOMCTL_CDF_oos_off |
+ XEN_DOMCTL_CDF_evtchn_l3)) )
break;
dom = op->domain;
@@ -405,6 +406,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
domcr_flags |= DOMCRF_s3_integrity;
if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
domcr_flags |= DOMCRF_oos_off;
+ if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_evtchn_l3 )
+ domcr_flags |= DOMCRF_evtchn_l3;
d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
if ( IS_ERR(d) )
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index a91ecba..2d9d0bb 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -1262,6 +1262,9 @@ static long evtchn_register_3level(evtchn_register_3level_t *arg)
xen_pfn_t l2sel_mfn = 0;
xen_pfn_t l2sel_offset = 0;
+ if ( d->evtchn_l3 == 0 && d->domain_id != 0 )
+ return -EPERM;
+
if ( d->evtchn_level == EVTCHN_3_LEVEL )
{
rc = -EINVAL;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 74160b0..4dacf95 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -59,6 +59,9 @@ struct xen_domctl_createdomain {
/* Disable out-of-sync shadow page tables? */
#define _XEN_DOMCTL_CDF_oos_off 3
#define XEN_DOMCTL_CDF_oos_off (1U<<_XEN_DOMCTL_CDF_oos_off)
+ /* Can this domain use 3-level event channel? */
+#define _XEN_DOMCTL_CDF_evtchn_l3 4
+#define XEN_DOMCTL_CDF_evtchn_l3 (1U<<_XEN_DOMCTL_CDF_evtchn_l3)
uint32_t flags;
};
typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 1d8c1b5..931655f 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -224,6 +224,8 @@ struct domain
unsigned int evtchn_level;
unsigned long *evtchn_pending[EVTCHN_MAX_L3_PAGES];
unsigned long *evtchn_mask[EVTCHN_MAX_L3_PAGES];
+ /* Can the domain use 3-level event channel? */
+ bool_t evtchn_l3;
struct grant_table *grant_table;
@@ -411,6 +413,9 @@ struct domain *domain_create(
/* DOMCRF_oos_off: dont use out-of-sync optimization for shadow page tables */
#define _DOMCRF_oos_off 4
#define DOMCRF_oos_off (1U<<_DOMCRF_oos_off)
+/* DOMCRF_evtchn_l3: this domain can use 3-level event channel (driver domain) */
+#define _DOMCRF_evtchn_l3 5
+#define DOMCRF_evtchn_l3 (1U<<_DOMCRF_evtchn_l3)
/*
* rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH V2 15/15] libxl: add evtchn_l3 flag
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
` (13 preceding siblings ...)
2013-02-04 17:23 ` [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain Wei Liu
@ 2013-02-04 17:23 ` Wei Liu
14 siblings, 0 replies; 17+ messages in thread
From: Wei Liu @ 2013-02-04 17:23 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.campbell, jbeulich, david.vrabel
Admins can add "evtchn_l3 = 1" in domain config file to enable 3-level event
channel for a domain.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_create.c | 3 +++
tools/libxl/libxl_types.idl | 1 +
tools/libxl/xl_cmdimpl.c | 2 ++
tools/libxl/xl_sxp.c | 1 +
4 files changed, 7 insertions(+)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index a8dfe61..b72efde 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -35,6 +35,8 @@ int libxl__domain_create_info_setdefault(libxl__gc *gc,
libxl_defbool_setdefault(&c_info->oos, true);
}
+ libxl_defbool_setdefault(&c_info->evtchn_l3, false);
+
libxl_defbool_setdefault(&c_info->run_hotplug_scripts, true);
return 0;
@@ -375,6 +377,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0;
flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off;
}
+ flags |= libxl_defbool_val(info->evtchn_l3) ? XEN_DOMCTL_CDF_evtchn_l3 : 0;
*domid = -1;
/* Ultimately, handle is an array of 16 uint8_t, same as uuid */
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index acc4bc9..7aa573e 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -236,6 +236,7 @@ libxl_domain_create_info = Struct("domain_create_info",[
("type", libxl_domain_type),
("hap", libxl_defbool),
("oos", libxl_defbool),
+ ("evtchn_l3", libxl_defbool),
("ssidref", uint32),
("name", string),
("uuid", libxl_uuid),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 080bbd8..06fd9ed 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -651,6 +651,8 @@ static void parse_config_data(const char *config_source,
xlu_cfg_get_defbool(config, "oos", &c_info->oos, 0);
+ xlu_cfg_get_defbool(config, "evtchn_l3", &c_info->evtchn_l3, 0);
+
if (!xlu_cfg_get_string (config, "pool", &buf, 0)) {
c_info->poolid = -1;
cpupool_qualifier_to_cpupoolid(buf, &c_info->poolid, NULL);
diff --git a/tools/libxl/xl_sxp.c b/tools/libxl/xl_sxp.c
index a16a025..9fd44c4 100644
--- a/tools/libxl/xl_sxp.c
+++ b/tools/libxl/xl_sxp.c
@@ -44,6 +44,7 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config)
printf("\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM);
printf("\t(hap %s)\n", libxl_defbool_to_string(c_info->hap));
printf("\t(oos %s)\n", libxl_defbool_to_string(c_info->oos));
+ printf("\t(evtchn_l3 %s)\n", libxl_defbool_to_string(c_info->evtchn_l3));
printf("\t(ssidref %d)\n", c_info->ssidref);
printf("\t(name %s)\n", c_info->name);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain
2013-02-04 17:23 ` [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain Wei Liu
@ 2013-02-06 8:28 ` Jan Beulich
0 siblings, 0 replies; 17+ messages in thread
From: Jan Beulich @ 2013-02-06 8:28 UTC (permalink / raw)
To: Wei Liu; +Cc: xen-devel, david.vrabel, ian.campbell
>>> On 04.02.13 at 18:23, Wei Liu <wei.liu2@citrix.com> wrote:
> @@ -411,6 +413,9 @@ struct domain *domain_create(
> /* DOMCRF_oos_off: dont use out-of-sync optimization for shadow page tables
> */
> #define _DOMCRF_oos_off 4
> #define DOMCRF_oos_off (1U<<_DOMCRF_oos_off)
> +/* DOMCRF_evtchn_l3: this domain can use 3-level event channel (driver domain) */
> +#define _DOMCRF_evtchn_l3 5
> +#define DOMCRF_evtchn_l3 (1U<<_DOMCRF_evtchn_l3)
Please don't use "l3" in this name; instead, make it generic to say
"extended event channels" in some way.
Also, the patch description should explain why this restriction is
being put in place.
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2013-02-06 8:28 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-04 17:23 [PATCH V2] Implement 3-level event channel in Xen Wei Liu
2013-02-04 17:23 ` [PATCH V2 01/15] Dynamically allocate d->evtchn Wei Liu
2013-02-04 17:23 ` [PATCH V2 02/15] Move event channel macros / struct definition to proper place Wei Liu
2013-02-04 17:23 ` [PATCH V2 03/15] Add evtchn_level in struct domain Wei Liu
2013-02-04 17:23 ` [PATCH V2 04/15] Bump EVTCHNS_PER_BUCKET to 512 Wei Liu
2013-02-04 17:23 ` [PATCH V2 05/15] Add evtchn_is_{pending, masked} and evtchn_clear_pending Wei Liu
2013-02-04 17:23 ` [PATCH V2 06/15] Introduce some macros for event channels Wei Liu
2013-02-04 17:23 ` [PATCH V2 07/15] Update Xen public header Wei Liu
2013-02-04 17:23 ` [PATCH V2 08/15] Define N-level event channel registration interface Wei Liu
2013-02-04 17:23 ` [PATCH V2 09/15] Add control structures for 3-level event channel Wei Liu
2013-02-04 17:23 ` [PATCH V2 10/15] Make NR_EVTCHN_BUCKETS 3-level ready Wei Liu
2013-02-04 17:23 ` [PATCH V2 11/15] Genneralized event channel operations Wei Liu
2013-02-04 17:23 ` [PATCH V2 12/15] Infrastructure for manipulating 3-level event channel pages Wei Liu
2013-02-04 17:23 ` [PATCH V2 13/15] Implement 3-level event channel routines Wei Liu
2013-02-04 17:23 ` [PATCH V2 14/15] Only allow 3-level event channel on Dom0 and driver domain Wei Liu
2013-02-06 8:28 ` Jan Beulich
2013-02-04 17:23 ` [PATCH V2 15/15] libxl: add evtchn_l3 flag Wei Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).