From: Alex Zeffertt <alex.zeffertt@eu.citrix.com>
To: "xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: [PATCH 14/24] [xen-unstable.hg] xen-internal API to allow xenstore stubdom to be registered to handle VIRQ_DOM_EXC
Date: Mon, 23 Mar 2009 15:21:13 +0000 [thread overview]
Message-ID: <49C7A8E9.8090605@eu.citrix.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3 bytes --]
[-- Attachment #2: xen_virq_handler_api --]
[-- Type: text/plain, Size: 6039 bytes --]
I sent these to Keir in an earlier state. He semeed to agree with the
general approach. Here was my explanation:
Xenstored needs to know when domains are dead/dying.
When xenstored ran in dom0, this was the process:
1) Hypervisor sends VIRQ_DOM_EXC to dom0.
2) xenstored gets the domain info on each of its known domains to figure
out who is dead/dying.
Those were two separate items that no longer worked when moving
xenstored into a dedicated domain:
1) The xenstore domain does not receive the event if it is sent to dom0.
2) Getting domain info is restricted to fully privileged domains.
I've created a new hypercall so that dom0 can delegate the handling of
VIRQ_DOM_EXC to the xenstore domain. I've also added an exception
allowing the handler of VIRQ_DOM_EXC to query for domain info.
01_xen_virq_handler_api Adds VIRQ handler functions [1].
02_xen_use_virq_handler_api Converts most users to the above.
03_xen_virq_handler_hypercall New hypercall to set VIRQ handler.
04_xen_virq_handler_dom_exc Whitelist VIRQ_DOM_EXC for handling,
permissions exception.
[1] There's a new table of global VIRQ handlers: indexed by VIRQ number,
values are domain struct pointers. When you want to send a global VIRQ
with this mechanism, you only give the VIRQ number (not a domain). If
the corresponding domain struct pointer is not NULL, the event is sent
to that domain. Otherwise, it's sent to dom0. These handlers can't be
modified arbitrarily: changing the handler to the explicit dom0 pointer
allows that handler to be modified in the future.
Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com>
Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com>
---
diff -r 62da7b4ee641 xen/common/domain.c
--- a/xen/common/domain.c Wed Mar 18 12:59:28 2009 +0000
+++ b/xen/common/domain.c Wed Mar 18 15:00:11 2009 +0000
@@ -560,6 +560,8 @@
arch_domain_destroy(d);
+ clear_global_virq_handler(d);
+
rangeset_domain_destroy(d);
sched_destroy_domain(d);
diff -r 62da7b4ee641 xen/common/event_channel.c
--- a/xen/common/event_channel.c Wed Mar 18 12:59:28 2009 +0000
+++ b/xen/common/event_channel.c Wed Mar 18 15:00:11 2009 +0000
@@ -56,6 +56,8 @@
rc = (_errno); \
goto out; \
} while ( 0 )
+
+extern struct domain *dom0;
static int evtchn_set_pending(struct vcpu *v, int port);
@@ -643,6 +645,92 @@
return evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
}
+/* NULL => locked to dom0 */
+/* dom0 => unlocked, but send to dom0 currently */
+/* else => unlocked, but send to this domain currently */
+static struct domain* global_virq_handlers[NR_VIRQS];
+
+/* TODO: check use of locking and {get,put}_domain */
+spinlock_t global_virq_handlers_lock = SPIN_LOCK_UNLOCKED;
+
+static struct domain* _get_global_virq_handler(int virq)
+{
+ struct domain *d;
+
+ d = global_virq_handlers[virq];
+ return d != NULL ? d : dom0;
+}
+
+int is_global_virq_handler(struct domain *d, int virq)
+{
+ ASSERT(virq >= 0 && virq < NR_VIRQS);
+ ASSERT(virq_is_global(virq));
+
+ return _get_global_virq_handler(virq) == d;
+}
+
+void send_handler_global_virq(int virq)
+{
+ ASSERT(virq >= 0 && virq < NR_VIRQS);
+ ASSERT(virq_is_global(virq));
+
+ send_guest_global_virq(_get_global_virq_handler(virq), virq);
+}
+
+int set_global_virq_handler(struct domain *d, int virq)
+{
+ struct domain *old;
+ int rc;
+
+ if (virq < 0 || virq >= NR_VIRQS)
+ return -EINVAL;
+ if (!virq_is_global(virq))
+ return -EINVAL;
+
+ if (global_virq_handlers[virq] == d)
+ return 0;
+
+ if (unlikely(!get_domain(d)))
+ return -EINVAL;
+
+ spin_lock(&global_virq_handlers_lock);
+
+ old = global_virq_handlers[virq];
+ if (d != dom0 && old == NULL) {
+ rc = -EINVAL;
+ put_domain(d);
+ } else {
+ if (old != NULL) {
+ global_virq_handlers[virq] = NULL;
+ put_domain(old);
+ }
+ global_virq_handlers[virq] = d;
+ rc = 0;
+ }
+
+ spin_unlock(&global_virq_handlers_lock);
+
+ return rc;
+}
+
+void clear_global_virq_handler(struct domain *d)
+{
+ int virq;
+
+ if (d == dom0)
+ return;
+
+ spin_lock(&global_virq_handlers_lock);
+
+ for (virq = 0; virq < NR_VIRQS; virq++) {
+ if (unlikely(global_virq_handlers[virq] == d)) {
+ global_virq_handlers[virq] = dom0;
+ put_domain(d);
+ }
+ }
+
+ spin_unlock(&global_virq_handlers_lock);
+}
static long evtchn_status(evtchn_status_t *status)
{
diff -r 62da7b4ee641 xen/include/xen/event.h
--- a/xen/include/xen/event.h Wed Mar 18 12:59:28 2009 +0000
+++ b/xen/include/xen/event.h Wed Mar 18 15:00:11 2009 +0000
@@ -29,6 +29,36 @@
* @virq: Virtual IRQ number (VIRQ_*)
*/
void send_guest_global_virq(struct domain *d, int virq);
+
+/* TODO: check comment formatting style: */
+
+/*
+ * send_handler_global_virq: Notify handler via a global VIRQ.
+ * @virq: Virtual IRQ number (VIRQ_*), must be global
+ * The event will be sent to the explicitly set handler (see
+ * set_global_virq_handler), or dom0.
+ */
+void send_handler_global_virq(int virq);
+
+/*
+ * sent_global_virq_handler: Set a global VIRQ handler.
+ * @d: Domain to which future virtual IRQ's should be sent
+ * @virq: Virtual IRQ number (VIRQ_*), must be global
+ */
+int set_global_virq_handler(struct domain *d, int virq);
+
+/*
+ * clear_global_virq_handler: Remove this handler from all global VIRQs.
+ * @d: Domain to no longer handle global virtual IRQs
+ */
+void clear_global_virq_handler(struct domain *d);
+
+/*
+ * is_global_virq_handler: Query if domain is the handler for this global VIRQ.
+ * @d: Domain which may be the handler
+ * @virq: Virtual IRQ number (VIRQ_*), must be global
+ */
+int is_global_virq_handler(struct domain *d, int virq);
/*
* send_guest_pirq:
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
reply other threads:[~2009-03-23 15:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49C7A8E9.8090605@eu.citrix.com \
--to=alex.zeffertt@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.