Changes from v4: - Add --internal-db flag to use TDB_INTERNAL on non-stubdom - Fewer #ifdefs Changes from v3: - mini-os configuration files moved into stubdom/ - mini-os extra console support now a config option - Fewer #ifdefs - grant table setup uses hypercall bounce - Xenstore stub domain syslog support re-enabled Changes from v2: - configuration support added to mini-os build system - add mini-os support for conditionally compiling frontends, xenbus - XENMEM_remove_from_physmap moved out of arch-specific code - use uint32_t for virqs - warn when dropping grant v2-only flags when switching versions - IOCTL_XENBUS_BACKEND_SETUP name changed so userspace can implement compat - ioctl now returns -EEXIST if xenstored has already been connected - various cosmetic cleanups, shuffling Changes from v1: - set_virq_handler implemented in libxc - added custom domain builder for xenstored - xenstore/console domain IDs now pulled from xenstore - migration support when using split xenstored (untested, should work) - slightly less intrusive NO_SOCKETS xenstored patch (still has many ifdefs to avoid pulling in socket headers or symbols) - virq handlers removed from dying domain when clearing event channels - dummy XSM module restricts getdomaininfo similar to no-XSM case - formatting/type fixups - partial ioctl compatibility with legacy IOCTL_XENBUS_ALLOC To start xenstored, run: tools/xenstore/init-xenstore-domain stubdom/mini-os-x86_64-xenstore/mini-os 20 system_u:system_r:domU_t This will populate the xenstore domid key /tool/xenstore/domid Other notes: The console for xenstored is not currently set up by init-xenstore-domain. If the hypervisor is compiled with VERBOSE or debug=y, output from xenstored will be visible on the hypervisor serial console (or ring buffer if enabled with console_to_ring). The xenstore stub domain itself supports console output, and init-xenstore-domain could be extended to daemonize and spool this output to a log file. The normal xenconsole daemon cannot be used here due to the possibility of a deadlock. ---- [PATCH 01/24] xen: reinstate previously unused [PATCH 02/24] xen: allow global VIRQ handlers to be delegated to [PATCH 03/24] xen: change virq parameters from int to uint32_t [PATCH 04/24] xen: use XSM instead of IS_PRIV for getdomaininfo [PATCH 05/24] xen: Preserve reserved grant entries when switching [PATCH 06/24] tools/libxl: pull xenstore/console domids from [PATCH 07/24] lib{xc,xl}: Seed grant tables with xenstore and [PATCH 08/24] mini-os: avoid crash if no console is provided [PATCH 09/24] mini-os: remove per-fd evtchn limit [PATCH 10/24] mini-os: create app-specific configuration [PATCH 11/24] mini-os: Move test functions into test.c [PATCH 12/24] mini-os: make frontends and xenbus optional [PATCH 13/24] mini-os: fix list.h include guard name [PATCH 14/24] xenstored: use grant references instead of [PATCH 15/24] xenstored: refactor socket setup code [PATCH 16/24] xenstored: add NO_SOCKETS compilation option [PATCH 17/24] xenstored: support for tdb_copy with TDB_INTERNAL [PATCH 18/24] xenstored: add --internal-db flag [PATCH 19/24] xenstored: support running in minios stubdom [PATCH 20/24] stubdom: enable xenstored build [PATCH 21/24] xenstored: add --event parameter for bootstrapping [PATCH 22/24] xenstored: use domain_is_unprivileged instead of [PATCH 23/24] xenstored: add --priv-domid parameter [PATCH 24/24] xenstored: Add stub domain builder Linux patch unchanged since v3, not reposted this time: [PATCH] xenbus: Add support for xenbus backend in stub domain
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 01/24] xen: reinstate previously unused XENMEM_remove_from_physmap hypercall
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> This patch reinstates the XENMEM_remove_from_physmap hypercall which was removed in 19041:ee62aaafff46 because it was not used. However, is now needed in order to support xenstored stub domains. The xenstored stub domain is not priviliged like dom0 and so cannot unilaterally map the xenbus page of other guests into it''s address space. Therefore, before creating a domU the domain builder needs to seed its grant table with a grant ref allowing the xenstored stub domain to access the new domU''s xenbus page. At present domU''s do not start with their grant table mapped. Instead it gets mapped when the guest requests a grant table from the hypervisor. In order to seed the grant table, the domain builder first needs to map it into dom0 address space. But the hypercall to do this requires a gpfn (guest pfn), which is an mfn for PV guest, but a pfn for HVM guests. Therfore, in order to seed the grant table of an HVM guest, dom0 needs to *temporarily* map it into the guest''s "physical" address space. Hence the need to reinstate the XENMEM_remove_from_physmap hypercall. Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- xen/common/compat/memory.c | 14 ++++++++++++++ xen/common/memory.c | 37 +++++++++++++++++++++++++++++++++++++ xen/include/asm-ia64/mm.h | 1 + xen/include/public/memory.h | 16 ++++++++++++++++ xen/include/xlat.lst | 1 + xen/include/xsm/xsm.h | 6 ++++++ xen/xsm/dummy.c | 6 ++++++ xen/xsm/flask/hooks.c | 6 ++++++ 8 files changed, 87 insertions(+), 0 deletions(-) diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index 2402984..e7257cc 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -25,6 +25,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) XEN_GUEST_HANDLE(void) hnd; struct xen_memory_reservation *rsrv; struct xen_memory_exchange *xchg; + struct xen_remove_from_physmap *xrfp; } nat; union { struct compat_memory_reservation rsrv; @@ -179,6 +180,18 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) nat.hnd = compat; break; + case XENMEM_remove_from_physmap: + { + struct compat_remove_from_physmap cmp; + + if ( copy_from_guest(&cmp, compat, 1) ) + return -EFAULT; + + XLAT_remove_from_physmap(nat.xrfp, &cmp); + + break; + } + default: return compat_arch_memory_op(cmd, compat); } @@ -284,6 +297,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) case XENMEM_current_reservation: case XENMEM_maximum_reservation: case XENMEM_maximum_gpfn: + case XENMEM_remove_from_physmap: break; default: diff --git a/xen/common/memory.c b/xen/common/memory.c index 8d45439..53886ce 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -659,6 +659,43 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg) break; + case XENMEM_remove_from_physmap: + { + struct xen_remove_from_physmap xrfp; + unsigned long mfn; + struct domain *d; + + if ( copy_from_guest(&xrfp, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(xrfp.domid, &d); + if ( rc != 0 ) + return rc; + + if ( xsm_remove_from_physmap(current->domain, d) ) + { + rcu_unlock_domain(d); + return -EPERM; + } + + domain_lock(d); + + mfn = get_gfn_untyped(d, xrfp.gpfn); + + if ( mfn_valid(mfn) ) + guest_physmap_remove_page(d, xrfp.gpfn, mfn, PAGE_ORDER_4K); + else + rc = -ENOENT; + + put_gfn(d, xrfp.gpfn); + + domain_unlock(d); + + rcu_unlock_domain(d); + + break; + } + default: rc = arch_memory_op(op, arg); break; diff --git a/xen/include/asm-ia64/mm.h b/xen/include/asm-ia64/mm.h index d09c363..a2bfc02 100644 --- a/xen/include/asm-ia64/mm.h +++ b/xen/include/asm-ia64/mm.h @@ -550,6 +550,7 @@ extern u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, #define gmfn_to_mfn(_d, gpfn) \ gmfn_to_mfn_foreign((_d), (gpfn)) +#define get_gfn_untyped(d, gpfn) gmfn_to_mfn(d, gpfn) #define put_gfn(d, g) ((void)0) #define __gpfn_invalid(_d, gpfn) \ diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index c5b78a8..308deff 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -229,6 +229,22 @@ struct xen_add_to_physmap { typedef struct xen_add_to_physmap xen_add_to_physmap_t; DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); +/* + * Unmaps the page appearing at a particular GPFN from the specified guest''s + * pseudophysical address space. + * arg == addr of xen_remove_from_physmap_t. + */ +#define XENMEM_remove_from_physmap 15 +struct xen_remove_from_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* GPFN of the current mapping of the page. */ + xen_pfn_t gpfn; +}; +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); + /*** REMOVED ***/ /*#define XENMEM_translate_gpfn_list 8*/ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index f602155..3d4f1e3 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -60,6 +60,7 @@ ! memory_map memory.h ! memory_reservation memory.h ! pod_target memory.h +! remove_from_physmap memory.h ? physdev_eoi physdev.h ? physdev_get_free_pirq physdev.h ? physdev_irq physdev.h diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index df6cec2..566c808 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -169,6 +169,7 @@ struct xsm_operations { int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); + int (*remove_from_physmap) (struct domain *d1, struct domain *d2); int (*sendtrigger) (struct domain *d); int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*unbind_pt_irq) (struct domain *d); @@ -738,6 +739,11 @@ static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) return xsm_call(add_to_physmap(d1, d2)); } +static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +{ + return xsm_call(remove_from_physmap(d1, d2)); +} + static inline int xsm_sendtrigger(struct domain *d) { return xsm_call(sendtrigger(d)); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 4bbfbff..65daa4e 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -529,6 +529,11 @@ static int dummy_add_to_physmap (struct domain *d1, struct domain *d2) return 0; } +static int dummy_remove_from_physmap (struct domain *d1, struct domain *d2) +{ + return 0; +} + static int dummy_sendtrigger (struct domain *d) { return 0; @@ -690,6 +695,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, mmu_machphys_update); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); + set_to_dummy_if_null(ops, remove_from_physmap); set_to_dummy_if_null(ops, sendtrigger); set_to_dummy_if_null(ops, bind_pt_irq); set_to_dummy_if_null(ops, pin_mem_cacheattr); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 0d35767..a2020a9 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1283,6 +1283,11 @@ static int flask_add_to_physmap(struct domain *d1, struct domain *d2) return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); } +static int flask_remove_from_physmap(struct domain *d1, struct domain *d2) +{ + return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); +} + static int flask_sendtrigger(struct domain *d) { return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); @@ -1550,6 +1555,7 @@ static struct xsm_operations flask_ops = { .mmu_machphys_update = flask_mmu_machphys_update, .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, + .remove_from_physmap = flask_remove_from_physmap, .sendtrigger = flask_sendtrigger, .get_device_group = flask_get_device_group, .test_assign_device = flask_test_assign_device, -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 02/24] xen: allow global VIRQ handlers to be delegated to other domains
This patch sends global VIRQs to a domain designated as the VIRQ handler instead of sending all global VIRQ events to dom0. This is required in order to run xenstored in a stubdom, because VIRQ_DOM_EXC must be sent to xenstored for domain destruction to work properly. This patch was inspired by the xenstored stubdomain patch series sent to xen-devel by Alex Zeffertt in 2009. Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/flask/policy/policy/flask/access_vectors | 1 + tools/libxc/xc_domain.c | 10 ++++ tools/libxc/xenctrl.h | 9 +++ xen/arch/x86/cpu/mcheck/amd_nonfatal.c | 2 +- xen/arch/x86/cpu/mcheck/mce.c | 2 +- xen/arch/x86/cpu/mcheck/mce_intel.c | 6 +- xen/arch/x86/cpu/mcheck/non-fatal.c | 2 +- xen/common/cpu.c | 4 +- xen/common/domain.c | 8 ++-- xen/common/domctl.c | 17 ++++++ xen/common/event_channel.c | 66 +++++++++++++++++++++++- xen/common/trace.c | 2 +- xen/drivers/char/console.c | 4 +- xen/include/public/domctl.h | 8 +++ xen/include/xen/event.h | 12 +++- xen/include/xsm/xsm.h | 6 ++ xen/xsm/dummy.c | 6 ++ xen/xsm/flask/hooks.c | 6 ++ xen/xsm/flask/include/av_perm_to_string.h | 1 + xen/xsm/flask/include/av_permissions.h | 1 + 20 files changed, 154 insertions(+), 19 deletions(-) diff --git a/tools/flask/policy/policy/flask/access_vectors b/tools/flask/policy/policy/flask/access_vectors index 644f2e1..5901911 100644 --- a/tools/flask/policy/policy/flask/access_vectors +++ b/tools/flask/policy/policy/flask/access_vectors @@ -85,6 +85,7 @@ class domain getpodtarget setpodtarget set_misc_info + set_virq_handler } class hvm diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index ab019b8..d98e68b 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -1504,6 +1504,16 @@ int xc_domain_set_access_required(xc_interface *xch, return do_domctl(xch, &domctl); } +int xc_domain_set_virq_handler(xc_interface *xch, uint32_t domid, int virq) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_set_virq_handler; + domctl.domain = domid; + domctl.u.set_virq_handler.virq = virq; + return do_domctl(xch, &domctl); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 37b0fd6..2ffdd85 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -749,6 +749,15 @@ int xc_domain_p2m_audit(xc_interface *xch, int xc_domain_set_access_required(xc_interface *xch, uint32_t domid, unsigned int required); +/** + * This function sets the handler of global VIRQs sent by the hypervisor + * + * @parm xch a handle to an open hypervisor interface + * @parm domid the domain id which will handle the VIRQ + * @parm virq the virq number (VIRQ_*) + * return 0 on success, -1 on failure + */ +int xc_domain_set_virq_handler(xc_interface *xch, uint32_t domid, int virq); /* * CPUPOOL MANAGEMENT FUNCTIONS diff --git a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c index 50288bd..9222098 100644 --- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c +++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c @@ -100,7 +100,7 @@ static void mce_amd_checkregs(void *info) if (dom0_vmce_enabled()) { mctelem_commit(mctc); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } else if (++dumpcount >= 10) { x86_mcinfo_dump((struct mc_info *)mctelem_dataptr(mctc)); mctelem_dismiss(mctc); diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index b592041..c4e4477 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -594,7 +594,7 @@ void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code, if (dom0_vmce_enabled()) { if (mctc != NULL) mctelem_commit(mctc); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } else { x86_mcinfo_dump(mci); if (mctc != NULL) diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index 0986025..0894080 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -354,7 +354,7 @@ static void mce_softirq(void) /* Step2: Send Log to DOM0 through vIRQ */ if (dom0_vmce_enabled()) { mce_printk(MCE_VERBOSE, "MCE: send MCE# to DOM0 through virq\n"); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } } @@ -1085,7 +1085,7 @@ static void cmci_discover(void) if (bs.errcnt && mctc != NULL) { if (dom0_vmce_enabled()) { mctelem_commit(mctc); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } else { x86_mcinfo_dump(mctelem_dataptr(mctc)); mctelem_dismiss(mctc); @@ -1205,7 +1205,7 @@ fastcall void smp_cmci_interrupt(struct cpu_user_regs *regs) if (dom0_vmce_enabled()) { mctelem_commit(mctc); mce_printk(MCE_VERBOSE, "CMCI: send CMCI to DOM0 through virq\n"); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } else { x86_mcinfo_dump(mctelem_dataptr(mctc)); mctelem_dismiss(mctc); diff --git a/xen/arch/x86/cpu/mcheck/non-fatal.c b/xen/arch/x86/cpu/mcheck/non-fatal.c index c57688f..1dded9b 100644 --- a/xen/arch/x86/cpu/mcheck/non-fatal.c +++ b/xen/arch/x86/cpu/mcheck/non-fatal.c @@ -55,7 +55,7 @@ static void mce_checkregs (void *info) if (dom0_vmce_enabled()) { mctelem_commit(mctc); - send_guest_global_virq(dom0, VIRQ_MCA); + send_global_virq(VIRQ_MCA); } else if (++dumpcount >= 10) { x86_mcinfo_dump((struct mc_info *)mctelem_dataptr(mctc)); mctelem_dismiss(mctc); diff --git a/xen/common/cpu.c b/xen/common/cpu.c index 79abdb7..630881e 100644 --- a/xen/common/cpu.c +++ b/xen/common/cpu.c @@ -108,7 +108,7 @@ int cpu_down(unsigned int cpu) notifier_rc = notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu, NULL); BUG_ON(notifier_rc != NOTIFY_DONE); - send_guest_global_virq(dom0, VIRQ_PCPU_STATE); + send_global_virq(VIRQ_PCPU_STATE); cpu_hotplug_done(); return 0; @@ -148,7 +148,7 @@ int cpu_up(unsigned int cpu) notifier_rc = notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu, NULL); BUG_ON(notifier_rc != NOTIFY_DONE); - send_guest_global_virq(dom0, VIRQ_PCPU_STATE); + send_global_virq(VIRQ_PCPU_STATE); cpu_hotplug_done(); return 0; diff --git a/xen/common/domain.c b/xen/common/domain.c index fd20210..500c7a2 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -86,7 +86,7 @@ static void __domain_finalise_shutdown(struct domain *d) if ( (d->shutdown_code == SHUTDOWN_suspend) && d->suspend_evtchn ) evtchn_send(d, d->suspend_evtchn); else - send_guest_global_virq(dom0, VIRQ_DOM_EXC); + send_global_virq(VIRQ_DOM_EXC); } static void vcpu_check_shutdown(struct vcpu *v) @@ -480,7 +480,7 @@ int domain_kill(struct domain *d) } d->is_dying = DOMDYING_dead; put_domain(d); - send_guest_global_virq(dom0, VIRQ_DOM_EXC); + send_global_virq(VIRQ_DOM_EXC); /* fallthrough */ case DOMDYING_dead: break; @@ -621,7 +621,7 @@ void domain_pause_for_debugger(void) for_each_vcpu ( d, v ) vcpu_sleep_nosync(v); - send_guest_global_virq(dom0, VIRQ_DEBUGGER); + send_global_virq(VIRQ_DEBUGGER); } /* Complete domain destroy after RCU readers are not holding old references. */ @@ -680,7 +680,7 @@ static void complete_domain_destroy(struct rcu_head *head) free_cpumask_var(d->domain_dirty_cpumask); free_domain_struct(d); - send_guest_global_virq(dom0, VIRQ_DOM_EXC); + send_global_virq(VIRQ_DOM_EXC); } /* Release resources belonging to task @p. */ diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 5b0fc4a..8001a91 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -995,6 +995,23 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) } break; + case XEN_DOMCTL_set_virq_handler: + { + struct domain *d; + uint32_t virq = op->u.set_virq_handler.virq; + + ret = -ESRCH; + d = rcu_lock_domain_by_id(op->domain); + if ( d != NULL ) + { + ret = xsm_set_virq_handler(d, virq); + if ( !ret ) + ret = set_global_virq_handler(d, virq); + rcu_unlock_domain(d); + } + } + break; + default: ret = arch_do_domctl(op, u_domctl); break; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 9212042..43bd167 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -689,7 +689,7 @@ void send_guest_vcpu_virq(struct vcpu *v, int virq) spin_unlock_irqrestore(&v->virq_lock, flags); } -void send_guest_global_virq(struct domain *d, int virq) +static void send_guest_global_virq(struct domain *d, int virq) { unsigned long flags; int port; @@ -739,6 +739,68 @@ int send_guest_pirq(struct domain *d, const struct pirq *pirq) return evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port); } +static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly; + +static DEFINE_SPINLOCK(global_virq_handlers_lock); + +void send_global_virq(uint32_t virq) +{ + ASSERT(virq < NR_VIRQS); + ASSERT(virq_is_global(virq)); + + send_guest_global_virq(global_virq_handlers[virq] ?: dom0, virq); +} + +int set_global_virq_handler(struct domain *d, uint32_t virq) +{ + struct domain *old; + + if (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]; + global_virq_handlers[virq] = d; + spin_unlock(&global_virq_handlers_lock); + + if (old != NULL) + put_domain(old); + + return 0; +} + +static void clear_global_virq_handlers(struct domain *d) +{ + uint32_t virq; + int put_count = 0; + + spin_lock(&global_virq_handlers_lock); + + for (virq = 0; virq < NR_VIRQS; virq++) + { + if (global_virq_handlers[virq] == d) + { + global_virq_handlers[virq] = NULL; + put_count++; + } + } + + spin_unlock(&global_virq_handlers_lock); + + while (put_count) + { + put_domain(d); + put_count--; + } +} static long evtchn_status(evtchn_status_t *status) { @@ -1160,6 +1222,8 @@ void evtchn_destroy(struct domain *d) d->evtchn[i] = NULL; } spin_unlock(&d->event_lock); + + clear_global_virq_handlers(d); } diff --git a/xen/common/trace.c b/xen/common/trace.c index 5772f24..58cbf39 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -661,7 +661,7 @@ static inline void insert_lost_records(struct t_buf *buf) */ static void trace_notify_dom0(unsigned long unused) { - send_guest_global_virq(dom0, VIRQ_TBUF); + send_global_virq(VIRQ_TBUF); } static DECLARE_SOFTIRQ_TASKLET(trace_notify_dom0_tasklet, trace_notify_dom0, 0); diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 89cf4f8..6560182 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -288,7 +288,7 @@ static void __serial_rx(char c, struct cpu_user_regs *regs) if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE ) serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c; /* Always notify the guest: prevents receive path from getting stuck. */ - send_guest_global_virq(dom0, VIRQ_CONSOLE); + send_global_virq(VIRQ_CONSOLE); } static void serial_rx(char c, struct cpu_user_regs *regs) @@ -315,7 +315,7 @@ static void serial_rx(char c, struct cpu_user_regs *regs) static void notify_dom0_con_ring(unsigned long unused) { - send_guest_global_virq(dom0, VIRQ_CON_RING); + send_global_virq(VIRQ_CON_RING); } static DECLARE_SOFTIRQ_TASKLET(notify_dom0_con_ring_tasklet, notify_dom0_con_ring, 0); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index c7640aa..75be370 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -813,6 +813,12 @@ struct xen_domctl_audit_p2m { typedef struct xen_domctl_audit_p2m xen_domctl_audit_p2m_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_audit_p2m_t); +struct xen_domctl_set_virq_handler { + uint32_t virq; /* IN */ +}; +typedef struct xen_domctl_set_virq_handler xen_domctl_set_virq_handler_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_virq_handler_t); + #if defined(__i386__) || defined(__x86_64__) /* XEN_DOMCTL_setvcpuextstate */ /* XEN_DOMCTL_getvcpuextstate */ @@ -912,6 +918,7 @@ struct xen_domctl { #define XEN_DOMCTL_getvcpuextstate 63 #define XEN_DOMCTL_set_access_required 64 #define XEN_DOMCTL_audit_p2m 65 +#define XEN_DOMCTL_set_virq_handler 66 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -966,6 +973,7 @@ struct xen_domctl { #endif struct xen_domctl_set_access_required access_required; struct xen_domctl_audit_p2m audit_p2m; + struct xen_domctl_set_virq_handler set_virq_handler; struct xen_domctl_gdbsx_memio gdbsx_guest_memio; struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu; struct xen_domctl_gdbsx_domstatus gdbsx_domstatus; diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 232d50e..40b8a7a 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -23,11 +23,17 @@ void send_guest_vcpu_virq(struct vcpu *v, int virq); /* - * send_guest_global_virq: Notify guest via a global VIRQ. - * @d: Domain to which virtual IRQ should be sent + * send_global_virq: Notify the domain handling a global VIRQ. * @virq: Virtual IRQ number (VIRQ_*) */ -void send_guest_global_virq(struct domain *d, int virq); +void send_global_virq(uint32_t virq); + +/* + * sent_global_virq_handler: Set a global VIRQ handler. + * @d: New target domain for this VIRQ + * @virq: Virtual IRQ number (VIRQ_*), must be global + */ +int set_global_virq_handler(struct domain *d, uint32_t virq); /* * send_guest_pirq: diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 566c808..e3cae60 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -64,6 +64,7 @@ struct xsm_operations { int (*domain_settime) (struct domain *d); int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); + int (*set_virq_handler) (struct domain *d, uint32_t virq); int (*tbufcontrol) (void); int (*readconsole) (uint32_t clear); int (*sched_id) (void); @@ -265,6 +266,11 @@ static inline int xsm_domctl (struct domain *d, int cmd) return xsm_call(domctl(d, cmd)); } +static inline int xsm_set_virq_handler (struct domain *d, uint32_t virq) +{ + return xsm_call(set_virq_handler(d, virq)); +} + static inline int xsm_tbufcontrol (void) { return xsm_call(tbufcontrol()); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 65daa4e..acf9c8a 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -94,6 +94,11 @@ static int dummy_domctl(struct domain *d, int cmd) return 0; } +static int dummy_set_virq_handler(struct domain *d, uint32_t virq) +{ + return 0; +} + static int dummy_tbufcontrol (void) { return 0; @@ -596,6 +601,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, domain_settime); set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); + set_to_dummy_if_null(ops, set_virq_handler); set_to_dummy_if_null(ops, tbufcontrol); set_to_dummy_if_null(ops, readconsole); set_to_dummy_if_null(ops, sched_id); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index a2020a9..543dc77 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -597,6 +597,11 @@ static int flask_domctl(struct domain *d, int cmd) return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); } +static int flask_set_virq_handler(struct domain *d, uint32_t virq) +{ + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); +} + static int flask_tbufcontrol(void) { return domain_has_xen(current->domain, XEN__TBUFCONTROL); @@ -1460,6 +1465,7 @@ static struct xsm_operations flask_ops = { .domain_settime = flask_domain_settime, .set_target = flask_set_target, .domctl = flask_domctl, + .set_virq_handler = flask_set_virq_handler, .tbufcontrol = flask_tbufcontrol, .readconsole = flask_readconsole, .sched_id = flask_sched_id, diff --git a/xen/xsm/flask/include/av_perm_to_string.h b/xen/xsm/flask/include/av_perm_to_string.h index 85cbffc..17a1c36 100644 --- a/xen/xsm/flask/include/av_perm_to_string.h +++ b/xen/xsm/flask/include/av_perm_to_string.h @@ -60,6 +60,7 @@ S_(SECCLASS_DOMAIN, DOMAIN__GETPODTARGET, "getpodtarget") S_(SECCLASS_DOMAIN, DOMAIN__SETPODTARGET, "setpodtarget") S_(SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO, "set_misc_info") + S_(SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER, "set_virq_handler") S_(SECCLASS_HVM, HVM__SETHVMC, "sethvmc") S_(SECCLASS_HVM, HVM__GETHVMC, "gethvmc") S_(SECCLASS_HVM, HVM__SETPARAM, "setparam") diff --git a/xen/xsm/flask/include/av_permissions.h b/xen/xsm/flask/include/av_permissions.h index 9e55a86..42eaf81 100644 --- a/xen/xsm/flask/include/av_permissions.h +++ b/xen/xsm/flask/include/av_permissions.h @@ -61,6 +61,7 @@ #define DOMAIN__GETPODTARGET 0x10000000UL #define DOMAIN__SETPODTARGET 0x20000000UL #define DOMAIN__SET_MISC_INFO 0x40000000UL +#define DOMAIN__SET_VIRQ_HANDLER 0x80000000UL #define HVM__SETHVMC 0x00000001UL #define HVM__GETHVMC 0x00000002UL -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 03/24] xen: change virq parameters from int to uint32_t
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- xen/common/event_channel.c | 10 +++++----- xen/include/asm-ia64/event.h | 2 +- xen/include/asm-x86/event.h | 2 +- xen/include/xen/event.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 43bd167..f784254 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -104,11 +104,11 @@ static uint8_t get_xen_consumer(xen_event_channel_notification_t fn) static int evtchn_set_pending(struct vcpu *v, int port); -static int virq_is_global(int virq) +static int virq_is_global(uint32_t virq) { int rc; - ASSERT((virq >= 0) && (virq < NR_VIRQS)); + ASSERT(virq < NR_VIRQS); switch ( virq ) { @@ -665,12 +665,12 @@ static int evtchn_set_pending(struct vcpu *v, int port) return 0; } -int guest_enabled_event(struct vcpu *v, int virq) +int guest_enabled_event(struct vcpu *v, uint32_t virq) { return ((v != NULL) && (v->virq_to_evtchn[virq] != 0)); } -void send_guest_vcpu_virq(struct vcpu *v, int virq) +void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq) { unsigned long flags; int port; @@ -689,7 +689,7 @@ void send_guest_vcpu_virq(struct vcpu *v, int virq) spin_unlock_irqrestore(&v->virq_lock, flags); } -static void send_guest_global_virq(struct domain *d, int virq) +static void send_guest_global_virq(struct domain *d, uint32_t virq) { unsigned long flags; int port; diff --git a/xen/include/asm-ia64/event.h b/xen/include/asm-ia64/event.h index c99babd..4463cb3 100644 --- a/xen/include/asm-ia64/event.h +++ b/xen/include/asm-ia64/event.h @@ -63,7 +63,7 @@ static inline void local_event_delivery_enable(void) current->vcpu_info->evtchn_upcall_mask = 0; } -static inline int arch_virq_is_global(int virq) +static inline int arch_virq_is_global(uint32_t virq) { int rc; diff --git a/xen/include/asm-x86/event.h b/xen/include/asm-x86/event.h index 606ec6d..06057c7 100644 --- a/xen/include/asm-x86/event.h +++ b/xen/include/asm-x86/event.h @@ -39,7 +39,7 @@ static inline void local_event_delivery_enable(void) } /* No arch specific virq definition now. Default to global. */ -static inline int arch_virq_is_global(int virq) +static inline int arch_virq_is_global(uint32_t virq) { return 1; } diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 40b8a7a..22fc6a3 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -20,7 +20,7 @@ * @v: VCPU to which virtual IRQ should be sent * @virq: Virtual IRQ number (VIRQ_*) */ -void send_guest_vcpu_virq(struct vcpu *v, int virq); +void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq); /* * send_global_virq: Notify the domain handling a global VIRQ. @@ -65,7 +65,7 @@ void free_xen_event_channel( struct vcpu *local_vcpu, int port); /* Query if event channel is in use by the guest */ -int guest_enabled_event(struct vcpu *v, int virq); +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); -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 04/24] xen: use XSM instead of IS_PRIV for getdomaininfo
The XEN_DOMCTL_getdomaininfo domctl does not allow manipulation of domains, only basic information such as size and state, so its use does not fully justify making a domain privileged. XSM modules can also provide fine-grained control over what domains are visible to domains that call getdomaininfo. If XSM is disabled (either at compile time or by using the dummy XSM module) then there is no change in behavior: only IS_PRIV domains can use this domctl. If enabled, the XSM module controls access. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- xen/common/domctl.c | 4 ++++ xen/xsm/dummy.c | 2 ++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 8001a91..904fb45 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -264,6 +264,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) return -EPERM; break; } +#ifdef XSM_ENABLE + case XEN_DOMCTL_getdomaininfo: + break; +#endif default: if ( !IS_PRIV(current->domain) ) return -EPERM; diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index acf9c8a..d99f886 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -66,6 +66,8 @@ static int dummy_scheduler (struct domain *d) static int dummy_getdomaininfo (struct domain *d) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 05/24] xen: Preserve reserved grant entries when switching versions
In order for the toolstack to use reserved grant table entries, the grant table for a guest must be initialized prior to the guest''s boot. When the guest switches grant table versions (necessary if the guest is using v2 grant tables, or on kexec if switching grant versions), these initial grants will be cleared. Instead of clearing them, preserve the grants across the type change. Attempting to preserve v2-only features such as sub-page grants will produce a warning and invalidate the resulting v1 grant entry. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- xen/common/grant_table.c | 48 +++++++++++++++++++++++++++++++++---- xen/include/public/grant_table.h | 7 +++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 0c55fd1..6f24a94 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -2111,6 +2111,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) struct domain *d = current->domain; struct grant_table *gt = d->grant_table; struct active_grant_entry *act; + grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES]; long res; int i; @@ -2131,7 +2132,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) /* (You need to change the version number for e.g. kexec.) */ if ( gt->gt_version != 0 ) { - for ( i = 0; i < nr_grant_entries(gt); i++ ) + for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ ) { act = &active_entry(gt, i); if ( act->pin != 0 ) @@ -2156,15 +2157,50 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) goto out_unlock; } + /* Preserve the first 8 entries (toolstack reserved grants) */ + if (gt->gt_version == 1) + { + memcpy(reserved_entries, gt->shared_v1[0], sizeof(reserved_entries)); + } + else if (gt->gt_version == 2) + { + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES && i < nr_grant_entries(gt); i++ ) + { + reserved_entries[i].flags = shared_entry_v2(gt, i).hdr.flags; + reserved_entries[i].domid = shared_entry_v2(gt, i).hdr.domid; + reserved_entries[i].frame = shared_entry_v2(gt, i).full_page.frame; + reserved_entries[i].flags |= status_entry(gt, i); + if ((reserved_entries[i].flags & GTF_type_mask) > GTF_permit_access) + { + gdprintk(XENLOG_INFO, "d%d: bad flags %x in grant %d when switching grant version\n", + d->domain_id, reserved_entries[i].flags, i); + reserved_entries[i].flags = GTF_invalid; + } + } + } + if ( op.version < 2 && gt->gt_version == 2 ) gnttab_unpopulate_status_frames(d, gt); - if ( op.version != gt->gt_version ) + /* Make sure there''s no crud left over in the table from the + old version. */ + for ( i = 0; i < nr_grant_frames(gt); i++ ) + memset(gt->shared_raw[i], 0, PAGE_SIZE); + + /* Restore the first 8 entries (toolstack reserved grants) */ + if (gt->gt_version != 0 && op.version == 1) { - /* Make sure there''s no crud left over in the table from the - old version. */ - for ( i = 0; i < nr_grant_frames(gt); i++ ) - memset(gt->shared_raw[i], 0, PAGE_SIZE); + memcpy(gt->shared_v1[0], reserved_entries, sizeof(reserved_entries)); + } + else if (gt->gt_version != 0 && op.version == 2) + { + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ ) + { + status_entry(gt, i) = reserved_entries[i].flags & (GTF_reading|GTF_writing); + shared_entry_v2(gt, i).hdr.flags = reserved_entries[i].flags & ~(GTF_reading|GTF_writing); + shared_entry_v2(gt, i).hdr.domid = reserved_entries[i].domid; + shared_entry_v2(gt, i).full_page.frame = reserved_entries[i].frame; + } } gt->gt_version = op.version; diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h index 54d9551..292d724 100644 --- a/xen/include/public/grant_table.h +++ b/xen/include/public/grant_table.h @@ -117,6 +117,13 @@ struct grant_entry_v1 { }; typedef struct grant_entry_v1 grant_entry_v1_t; +/* The first few grant table entries will be preserved across grant table + * version changes and may be pre-populated at domain creation by tools. + */ +#define GNTTAB_NR_RESERVED_ENTRIES 8 +#define GNTTAB_RESERVED_CONSOLE 0 +#define GNTTAB_RESERVED_XENSTORE 1 + /* * Type of grant entry. * GTF_invalid: This grant entry grants no privileges. -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 06/24] tools/libxl: pull xenstore/console domids from xenstore
Instead of assuming that xenstored and xenconsoled are running in dom0, pull the domain IDs from xenstore. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/libxl/libxl_dom.c | 14 ++++++++++++-- tools/libxl/libxl_internal.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 91643a2..3828c62 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -64,6 +64,7 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid, { libxl_ctx *ctx = libxl__gc_owner(gc); int tsc_mode; + char *xs_domid, *con_domid; xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus); xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + LIBXL_MAXMEM_CONSTANT); if (info->type == LIBXL_DOMAIN_TYPE_PV) @@ -95,9 +96,18 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid, xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); } - state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); - state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); + xs_domid = xs_read(ctx->xsh, XBT_NULL, "/tool/xenstored/domid", NULL); + state->store_domid = xs_domid ? atoi(xs_domid) : 0; + free(xs_domid); + + con_domid = xs_read(ctx->xsh, XBT_NULL, "/tool/xenconsoled/domid", NULL); + state->console_domid = con_domid ? atoi(con_domid) : 0; + free(con_domid); + + state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid); + state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid); state->vm_generationid_addr = 0; + return 0; } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 3c8da45..965dbd0 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -243,9 +243,11 @@ _hidden int libxl__domain_shutdown_reason(libxl__gc *gc, uint32_t domid); libxl__domain_type((gc), (domid)) == LIBXL_DOMAIN_TYPE_##type typedef struct { uint32_t store_port; + uint32_t store_domid; unsigned long store_mfn; uint32_t console_port; + uint32_t console_domid; unsigned long console_mfn; unsigned long vm_generationid_addr; } libxl__domain_build_state; -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 07/24] lib{xc, xl}: Seed grant tables with xenstore and console grants
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> This patch claims one reserved grant entry for the console and another for the xenstore. It modifies the builder to fill in the grant table entries for the console and the xenstore. Previous versions of this patch have been sent to xen-devel. See http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01491.html Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/libxc/xc_dom.h | 13 +++ tools/libxc/xc_dom_boot.c | 158 +++++++++++++++++++++++++++++++++++++ tools/libxc/xc_dom_compat_linux.c | 2 + tools/libxc/xc_domain_restore.c | 19 ++++- tools/libxc/xenguest.h | 3 +- tools/libxl/libxl_dom.c | 18 ++++- tools/xcutils/xc_restore.c | 4 +- 7 files changed, 210 insertions(+), 7 deletions(-) diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h index e72f066..6c36403 100644 --- a/tools/libxc/xc_dom.h +++ b/tools/libxc/xc_dom.h @@ -106,7 +106,9 @@ struct xc_dom_image { /* misc xen domain config stuff */ unsigned long flags; unsigned int console_evtchn; + unsigned int console_domid; unsigned int xenstore_evtchn; + unsigned int xenstore_domid; xen_pfn_t shared_info_mfn; xc_interface *xch; @@ -200,6 +202,17 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, xen_pfn_t count); int xc_dom_boot_image(struct xc_dom_image *dom); int xc_dom_compat_check(struct xc_dom_image *dom); +int xc_dom_gnttab_init(struct xc_dom_image *dom); +int xc_dom_gnttab_hvm_seed(xc_interface *xch, uint32_t domid, + unsigned long console_gmfn, + unsigned long xenstore_gmfn, + uint32_t console_domid, + uint32_t xenstore_domid); +int xc_dom_gnttab_seed(xc_interface *xch, uint32_t domid, + unsigned long console_gmfn, + unsigned long xenstore_gmfn, + uint32_t console_domid, + uint32_t xenstore_domid); /* --- debugging bits ---------------------------------------------- */ diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c index 65f60df..5f609de 100644 --- a/tools/libxc/xc_dom_boot.c +++ b/tools/libxc/xc_dom_boot.c @@ -34,6 +34,7 @@ #include "xg_private.h" #include "xc_dom.h" #include <xen/hvm/params.h> +#include <xen/grant_table.h> /* ------------------------------------------------------------------------ */ @@ -275,6 +276,163 @@ int xc_dom_boot_image(struct xc_dom_image *dom) return rc; } +static unsigned long xc_dom_gnttab_setup(xc_interface *xch, uint32_t domid) +{ + gnttab_setup_table_t setup; + DECLARE_HYPERCALL_BUFFER(unsigned long, gmfnp); + int rc; + unsigned long gmfn; + + gmfnp = xc_hypercall_buffer_alloc(xch, gmfnp, sizeof(*gmfnp)); + if (gmfnp == NULL) + return -1; + + setup.dom = domid; + setup.nr_frames = 1; + set_xen_guest_handle(setup.frame_list, gmfnp); + setup.status = 0; + + rc = xc_gnttab_op(xch, GNTTABOP_setup_table, &setup, sizeof(setup), 1); + gmfn = *gmfnp; + xc_hypercall_buffer_free(xch, gmfnp); + + if ( rc != 0 || setup.status != GNTST_okay ) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to setup domU grant table " + "[errno=%d, status=%" PRId16 "]\n", + __FUNCTION__, rc != 0 ? errno : 0, setup.status); + return -1; + } + + return gmfn; +} + +int xc_dom_gnttab_seed(xc_interface *xch, uint32_t domid, + unsigned long console_gmfn, + unsigned long xenstore_gmfn, + uint32_t console_domid, + uint32_t xenstore_domid) +{ + + unsigned long gnttab_gmfn; + grant_entry_v1_t *gnttab; + + gnttab_gmfn = xc_dom_gnttab_setup(xch, domid); + if ( gnttab_gmfn == -1 ) + return -1; + + gnttab = xc_map_foreign_range(xch, + domid, + PAGE_SIZE, + PROT_READ|PROT_WRITE, + gnttab_gmfn); + if ( gnttab == NULL ) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to map domU grant table " + "[errno=%d]\n", + __FUNCTION__, errno); + return -1; + } + + if ( domid != console_domid && console_gmfn != -1) + { + gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access; + gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid; + gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn; + } + if ( domid != xenstore_domid && xenstore_gmfn != -1) + { + gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access; + gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid; + gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn; + } + + if ( munmap(gnttab, PAGE_SIZE) == -1 ) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to unmap domU grant table " + "[errno=%d]\n", + __FUNCTION__, errno); + return -1; + } + + return 0; +} + +int xc_dom_gnttab_hvm_seed(xc_interface *xch, uint32_t domid, + unsigned long console_gpfn, + unsigned long xenstore_gpfn, + uint32_t console_domid, + uint32_t xenstore_domid) +{ +#define SCRATCH_PFN_GNTTAB 0xFFFFE + + int rc; + struct xen_add_to_physmap xatp = { + .domid = domid, + .space = XENMAPSPACE_grant_table, + .idx = 0, + .gpfn = SCRATCH_PFN_GNTTAB + }; + struct xen_remove_from_physmap xrfp = { + .domid = domid, + .gpfn = SCRATCH_PFN_GNTTAB + }; + + rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp)); + if ( rc != 0 ) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to add gnttab to physmap " + "[errno=%d]\n", + __FUNCTION__, errno); + return -1; + } + + rc = xc_dom_gnttab_seed(xch, domid, + console_gpfn, xenstore_gpfn, + console_domid, xenstore_domid); + if (rc != 0) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to seed gnttab entries\n", + __FUNCTION__); + (void) do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); + return -1; + } + + rc = do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); + if (rc != 0) + { + xc_dom_panic(xch, XC_INTERNAL_ERROR, + "%s: failed to remove gnttab from physmap " + "[errno=%d]\n", + __FUNCTION__, errno); + return -1; + } + + return 0; +} + +int xc_dom_gnttab_init(struct xc_dom_image *dom) +{ + unsigned long console_gmfn; + unsigned long xenstore_gmfn; + int autotranslated; + + autotranslated = xc_dom_feature_translated(dom); + console_gmfn = autotranslated ? + dom->console_pfn : xc_dom_p2m_host(dom, dom->console_pfn); + xenstore_gmfn = autotranslated ? + dom->xenstore_pfn : xc_dom_p2m_host(dom, dom->xenstore_pfn); + + return xc_dom_gnttab_seed(dom->xch, dom->guest_domid, + console_gmfn, xenstore_gmfn, + dom->console_domid, dom->xenstore_domid); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xc_dom_compat_linux.c b/tools/libxc/xc_dom_compat_linux.c index 0e78842..2183a3b 100644 --- a/tools/libxc/xc_dom_compat_linux.c +++ b/tools/libxc/xc_dom_compat_linux.c @@ -62,6 +62,8 @@ static int xc_linux_build_internal(struct xc_dom_image *dom, goto out; if ( (rc = xc_dom_boot_image(dom)) != 0 ) goto out; + if ( (rc = xc_dom_gnttab_init(dom)) != 0) + goto out; *console_mfn = xc_dom_p2m_host(dom, dom->console_pfn); *store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn); diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 3fda6f8..8bee684 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -1259,7 +1259,8 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx, int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, - unsigned int console_evtchn, unsigned long *console_mfn, + uint32_t store_domid, unsigned int console_evtchn, + unsigned long *console_mfn, uint32_t console_domid, unsigned int hvm, unsigned int pae, int superpages, int no_incr_generationid, unsigned long *vm_generationid_addr) @@ -2018,6 +2019,14 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, memcpy(ctx->live_p2m, ctx->p2m, dinfo->p2m_size * sizeof(xen_pfn_t)); munmap(ctx->live_p2m, P2M_FL_ENTRIES * PAGE_SIZE); + rc = xc_dom_gnttab_seed(xch, dom, *console_mfn, *store_mfn, + console_domid, store_domid); + if (rc != 0) + { + ERROR("error seeding grant table"); + goto out; + } + DPRINTF("Domain ready to be built.\n"); rc = 0; goto out; @@ -2076,6 +2085,14 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, goto out; } + rc = xc_dom_gnttab_hvm_seed(xch, dom, *console_mfn, *store_mfn, + console_domid, store_domid); + if (rc != 0) + { + ERROR("error seeding grant table"); + goto out; + } + /* HVM success! */ rc = 0; diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 6026370..3bd5549 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -79,7 +79,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter */ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, - unsigned int console_evtchn, unsigned long *console_mfn, + uint32_t store_domid, unsigned int console_evtchn, + unsigned long *console_mfn, uint32_t console_domid, unsigned int hvm, unsigned int pae, int superpages, int no_incr_generationid, unsigned long *vm_generationid_addr); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 3828c62..28646e0 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -224,7 +224,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, dom->flags = flags; dom->console_evtchn = state->console_port; + dom->console_domid = state->console_domid; dom->xenstore_evtchn = state->store_port; + dom->xenstore_domid = state->store_domid; if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_xen_init failed"); @@ -250,6 +252,10 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_image failed"); goto out; } + if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_gnttab_init failed"); + goto out; + } state->console_mfn = xc_dom_p2m_host(dom, dom->console_pfn); state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn); @@ -263,7 +269,8 @@ out: static int hvm_build_set_params(xc_interface *handle, uint32_t domid, libxl_domain_build_info *info, int store_evtchn, unsigned long *store_mfn, - int console_evtchn, unsigned long *console_mfn) + int console_evtchn, unsigned long *console_mfn, + uint32_t store_domid, uint32_t console_domid) { struct hvm_info_table *va_hvm; uint8_t *va_map, sum; @@ -296,6 +303,8 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid, xc_set_hvm_param(handle, domid, HVM_PARAM_NESTEDHVM, info->u.hvm.nested_hvm); xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn); xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn); + + xc_dom_gnttab_hvm_seed(handle, domid, *console_mfn, *store_mfn, console_domid, store_domid); return 0; } @@ -349,7 +358,9 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid, goto out; } ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port, - &state->store_mfn, state->console_port, &state->console_mfn); + &state->store_mfn, state->console_port, + &state->console_mfn, state->store_domid, + state->console_domid); if (ret) { LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm build set params failed"); goto out; @@ -387,7 +398,8 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid, } rc = xc_domain_restore(ctx->xch, fd, domid, state->store_port, &state->store_mfn, - state->console_port, &state->console_mfn, + state->store_domid, state->console_port, + &state->console_mfn, state->console_domid, hvm, pae, superpages, no_incr_generationid, &state->vm_generationid_addr); if ( rc ) { diff --git a/tools/xcutils/xc_restore.c b/tools/xcutils/xc_restore.c index 63d53a8..e41a133 100644 --- a/tools/xcutils/xc_restore.c +++ b/tools/xcutils/xc_restore.c @@ -45,8 +45,8 @@ main(int argc, char **argv) else superpages = !!hvm; - ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn, - console_evtchn, &console_mfn, hvm, pae, superpages, + ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn, 0, + console_evtchn, &console_mfn, 0, hvm, pae, superpages, 0, NULL); if ( ret == 0 ) -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 08/24] mini-os: avoid crash if no console is provided
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- extras/mini-os/console/xencons_ring.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/extras/mini-os/console/xencons_ring.c b/extras/mini-os/console/xencons_ring.c index 22fd618..af0afed 100644 --- a/extras/mini-os/console/xencons_ring.c +++ b/extras/mini-os/console/xencons_ring.c @@ -25,7 +25,10 @@ static inline void notify_daemon(struct consfront_dev *dev) static inline struct xencons_interface *xencons_interface(void) { - return mfn_to_virt(start_info.console.domU.mfn); + if (start_info.console.domU.evtchn) + return mfn_to_virt(start_info.console.domU.mfn); + else + return NULL; } int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len) @@ -38,6 +41,8 @@ int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, uns intf = xencons_interface(); else intf = dev->ring; + if (!intf) + return sent; cons = intf->out_cons; prod = intf->out_prod; -- 1.7.7.6
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> This changes the minios evtchn implementation to use a list instead of an array which ahis allows it to grow as necessary to support any number of ports, only limited by Xen (NR_EVS is 1024, should be enough for now). Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- extras/mini-os/include/lib.h | 16 +++--- tools/libxc/xc_minios.c | 139 ++++++++++++++++++++++-------------------- 2 files changed, 81 insertions(+), 74 deletions(-) diff --git a/extras/mini-os/include/lib.h b/extras/mini-os/include/lib.h index bd3eeaf..12070c3 100644 --- a/extras/mini-os/include/lib.h +++ b/extras/mini-os/include/lib.h @@ -53,6 +53,7 @@ #include <xen/xen.h> #include <xen/event_channel.h> #include "gntmap.h" +#include "list.h" #ifdef HAVE_LIBC #include <stdio.h> @@ -143,7 +144,12 @@ enum fd_type { FTYPE_SAVEFILE, }; -#define MAX_EVTCHN_PORTS 16 +struct evtchn_port_info { + struct minios_list_head list; + evtchn_port_t port; + unsigned long pending; + int bound; +}; extern struct file { enum fd_type type; @@ -158,13 +164,7 @@ extern struct file { off_t offset; } file; struct { - /* To each event channel FD is associated a series of ports which - * wakes select for this FD. */ - struct { - evtchn_port_t port; - unsigned long pending; - int bound; - } ports[MAX_EVTCHN_PORTS]; + struct minios_list_head ports; } evtchn; struct gntmap gntmap; struct { diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index 8bbfd18..29cce63 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -210,15 +210,34 @@ static struct xc_osdep_ops minios_privcmd_ops = { }, }; + +/* XXX Note: This is not threadsafe */ +static struct evtchn_port_info* port_alloc(int fd) { + struct evtchn_port_info *port_info; + port_info = malloc(sizeof(struct evtchn_port_info)); + if (port_info == NULL) + return NULL; + port_info->pending = 0; + port_info->port = -1; + port_info->bound = 0; + + minios_list_add(&port_info->list, &files[fd].evtchn.ports); + return port_info; +} + +static void port_dealloc(struct evtchn_port_info *port_info) { + if (port_info->bound) + unbind_evtchn(port_info->port); + minios_list_del(&port_info->list); + free(port_info); +} + static xc_osdep_handle minios_evtchn_open(xc_evtchn *xce) { - int fd = alloc_fd(FTYPE_EVTCHN), i; + int fd = alloc_fd(FTYPE_EVTCHN); if ( fd == -1 ) return XC_OSDEP_OPEN_ERROR; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) { - files[fd].evtchn.ports[i].port = -1; - files[fd].evtchn.ports[i].bound = 0; - } + MINIOS_INIT_LIST_HEAD(&files[fd].evtchn.ports); printf("evtchn_open() -> %d\n", fd); return (xc_osdep_handle)fd; } @@ -231,10 +250,10 @@ static int minios_evtchn_close(xc_evtchn *xce, xc_osdep_handle h) void minios_evtchn_close_fd(int fd) { - int i; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) - if (files[fd].evtchn.ports[i].bound) - unbind_evtchn(files[fd].evtchn.ports[i].port); + struct evtchn_port_info *port_info, *tmp; + minios_list_for_each_entry_safe(port_info, tmp, &files[fd].evtchn.ports, list) + port_dealloc(port_info); + files[fd].type = FTYPE_NONE; } @@ -256,35 +275,21 @@ static int minios_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t return ret; } -/* XXX Note: This is not threadsafe */ -static int port_alloc(int fd) { - int i; - for (i= 0; i < MAX_EVTCHN_PORTS; i++) - if (files[fd].evtchn.ports[i].port == -1) - break; - if (i == MAX_EVTCHN_PORTS) { - printf("Too many ports in xc handle\n"); - errno = EMFILE; - return -1; - } - files[fd].evtchn.ports[i].pending = 0; - return i; -} - static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { int fd = (int)(intptr_t)data; - int i; + struct evtchn_port_info *port_info; assert(files[fd].type == FTYPE_EVTCHN); mask_evtchn(port); - for (i= 0; i < MAX_EVTCHN_PORTS; i++) - if (files[fd].evtchn.ports[i].port == port) - break; - if (i == MAX_EVTCHN_PORTS) { - printk("Unknown port for handle %d\n", fd); - return; + minios_list_for_each_entry(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port == port) + goto found; } - files[fd].evtchn.ports[i].pending = 1; + printk("Unknown port for handle %d\n", fd); + return; + + found: + port_info->pending = 1; files[fd].read = 1; wake_up(&event_queue); } @@ -292,12 +297,13 @@ static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) static evtchn_port_or_error_t minios_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid) { int fd = (int)h; - int ret, i; + struct evtchn_port_info *port_info; + int ret; evtchn_port_t port; assert(get_current() == main_thread); - i = port_alloc(fd); - if (i == -1) + port_info = port_alloc(fd); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_unbound_port(%d)", domid); @@ -305,11 +311,12 @@ static evtchn_port_or_error_t minios_evtchn_bind_unbound_port(xc_evtchn *xce, xc printf(" = %d\n", ret); if (ret < 0) { + port_dealloc(port_info); errno = -ret; return -1; } - files[fd].evtchn.ports[i].bound = 1; - files[fd].evtchn.ports[i].port = port; + port_info->bound = 1; + port_info->port = port; unmask_evtchn(port); return port; } @@ -318,12 +325,13 @@ static evtchn_port_or_error_t minios_evtchn_bind_interdomain(xc_evtchn *xce, xc_ evtchn_port_t remote_port) { int fd = (int)h; + struct evtchn_port_info *port_info; evtchn_port_t local_port; - int ret, i; + int ret; assert(get_current() == main_thread); - i = port_alloc(fd); - if (i == -1) + port_info = port_alloc(fd); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port); @@ -331,11 +339,12 @@ static evtchn_port_or_error_t minios_evtchn_bind_interdomain(xc_evtchn *xce, xc_ printf(" = %d\n", ret); if (ret < 0) { + port_dealloc(port_info); errno = -ret; return -1; } - files[fd].evtchn.ports[i].bound = 1; - files[fd].evtchn.ports[i].port = local_port; + port_info->bound = 1; + port_info->port = local_port; unmask_evtchn(local_port); return local_port; } @@ -343,42 +352,40 @@ static evtchn_port_or_error_t minios_evtchn_bind_interdomain(xc_evtchn *xce, xc_ static int minios_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port) { int fd = (int)h; - int i; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) - if (files[fd].evtchn.ports[i].port == port) { - files[fd].evtchn.ports[i].port = -1; - break; - } - if (i == MAX_EVTCHN_PORTS) { - printf("Warning: couldn''t find port %"PRId32" for xc handle %x\n", port, fd); - errno = -EINVAL; - return -1; + struct evtchn_port_info *port_info; + + minios_list_for_each_entry(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port == port) { + port_dealloc(port_info); + return 0; + } } - files[fd].evtchn.ports[i].bound = 0; - unbind_evtchn(port); - return 0; + printf("Warning: couldn''t find port %"PRId32" for xc handle %x\n", port, fd); + errno = -EINVAL; + return -1; } static evtchn_port_or_error_t minios_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq) { int fd = (int)h; + struct evtchn_port_info *port_info; evtchn_port_t port; - int i; assert(get_current() == main_thread); - i = port_alloc(fd); - if (i == -1) + port_info = port_alloc(fd); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_virq(%d)", virq); port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)fd); if (port < 0) { + port_dealloc(port_info); errno = -port; return -1; } - files[fd].evtchn.ports[i].bound = 1; - files[fd].evtchn.ports[i].port = port; + port_info->bound = 1; + port_info->port = port; unmask_evtchn(port); return port; } @@ -386,18 +393,18 @@ static evtchn_port_or_error_t minios_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_h static evtchn_port_or_error_t minios_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h) { int fd = (int)h; - int i; + struct evtchn_port_info *port_info; unsigned long flags; evtchn_port_t ret = -1; local_irq_save(flags); files[fd].read = 0; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) { - evtchn_port_t port = files[fd].evtchn.ports[i].port; - if (port != -1 && files[fd].evtchn.ports[i].pending) { + + minios_list_for_each_entry(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port != -1 && port_info->pending) { if (ret == -1) { - ret = port; - files[fd].evtchn.ports[i].pending = 0; + ret = port_info->port; + port_info->pending = 0; } else { files[fd].read = 1; break; -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 10/24] mini-os: create app-specific configuration
Instead of using CONFIG_QEMU and CONFIG_GRUB to enable or disable minios code, create CONFIG_ items for features and use application-specific configuration files to enable or disable the features. The configuration flags are currently added to the compiler command line; as the number of flags grows this may need to move to a header. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- extras/mini-os/Makefile | 52 ++++++++++++++++++++++++++++++++++++++++----- extras/mini-os/main.c | 16 +++++++------- extras/mini-os/minios.mk | 4 +- stubdom/Makefile | 8 +++--- stubdom/grub/minios.cfg | 2 + stubdom/ioemu-minios.cfg | 1 + 6 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 stubdom/c/minios.cfg create mode 100644 stubdom/caml/minios.cfg create mode 100644 stubdom/grub/minios.cfg create mode 100644 stubdom/ioemu-minios.cfg diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index c2ee062..be38170 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -8,10 +8,25 @@ export XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/Config.mk OBJ_DIR ?= $(CURDIR) -ifneq ($(stubdom),y) +ifeq ($(MINIOS_CONFIG),) include Config.mk +else +EXTRA_DEPS += $(MINIOS_CONFIG) +include $(MINIOS_CONFIG) endif +# Configuration defaults +CONFIG_START_NETWORK ?= y +CONFIG_SPARSE_BSS ?= y +CONFIG_QEMU_XS_ARGS ?= n + +# Export config items as compiler directives +flags-$(CONFIG_START_NETWORK) += -DCONFIG_START_NETWORK +flags-$(CONFIG_SPARSE_BSS) += -DCONFIG_SPARSE_BSS +flags-$(CONFIG_QEMU_XS_ARGS) += -DCONFIG_QEMU_XS_ARGS + +DEF_CFLAGS += $(flags-y) + # Include common mini-os makerules. include minios.mk @@ -34,13 +49,38 @@ TARGET := mini-os # Subdirectories common to mini-os SUBDIRS := lib xenbus console +src-y += blkfront.c +src-y += daytime.c +src-y += events.c +src-y += fbfront.c +src-y += gntmap.c +src-y += gnttab.c +src-y += hypervisor.c +src-y += kernel.c +src-y += lock.c +src-y += main.c +src-y += mm.c +src-y += netfront.c +src-y += pcifront.c +src-y += sched.c + +src-y += lib/ctype.c +src-y += lib/math.c +src-y += lib/printf.c +src-y += lib/stack_chk_fail.c +src-y += lib/string.c +src-y += lib/sys.c +src-y += lib/xmalloc.c +src-y += lib/xs.c + +src-y += xenbus/xenbus.c + +src-y += console/console.c +src-y += console/xencons_ring.c + # The common mini-os objects to build. APP_OBJS :-OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c)) -OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard lib/*.c)) -OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard xenbus/*.c)) -OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard console/*.c)) - +OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(src-y)) .PHONY: default default: $(OBJ_DIR)/$(TARGET) diff --git a/extras/mini-os/main.c b/extras/mini-os/main.c index b95b889..aeda548 100644 --- a/extras/mini-os/main.c +++ b/extras/mini-os/main.c @@ -43,13 +43,13 @@ extern char __app_bss_start, __app_bss_end; static void call_main(void *p) { char *c, quote; -#ifdef CONFIG_QEMU +#ifdef CONFIG_QEMU_XS_ARGS char *domargs, *msg; #endif int argc; char **argv; char *envp[] = { NULL }; -#ifdef CONFIG_QEMU +#ifdef CONFIG_QEMU_XS_ARGS char *vm; char path[128]; int domid; @@ -60,15 +60,15 @@ static void call_main(void *p) * crashing. */ //sleep(1); -#ifndef CONFIG_GRUB +#ifdef CONFIG_SPARSE_BSS sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start); -#if defined(HAVE_LWIP) && !defined(CONFIG_QEMU) - start_networking(); #endif +#if defined(HAVE_LWIP) && defined(CONFIG_START_NETWORK) + start_networking(); #endif create_thread("pcifront", pcifront_watches, NULL); -#ifdef CONFIG_QEMU +#ifdef CONFIG_QEMU_XS_ARGS /* Fetch argc, argv from XenStore */ domid = xenbus_read_integer("target"); if (domid == -1) { @@ -132,7 +132,7 @@ static void call_main(void *p) #define PARSE_ARGS_STORE(ARGS) PARSE_ARGS(ARGS, argv[argc++] = c, memmove(c, c + 1, strlen(c + 1) + 1), *c++ = 0) PARSE_ARGS_COUNT((char*)start_info.cmd_line); -#ifdef CONFIG_QEMU +#ifdef CONFIG_QEMU_XS_ARGS PARSE_ARGS_COUNT(domargs); #endif @@ -141,7 +141,7 @@ static void call_main(void *p) argc = 1; PARSE_ARGS_STORE((char*)start_info.cmd_line) -#ifdef CONFIG_QEMU +#ifdef CONFIG_QEMU_XS_ARGS PARSE_ARGS_STORE(domargs) #endif diff --git a/extras/mini-os/minios.mk b/extras/mini-os/minios.mk index 698648a..48ed768 100644 --- a/extras/mini-os/minios.mk +++ b/extras/mini-os/minios.mk @@ -39,8 +39,8 @@ LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS) # Special build dependencies. # Rebuild all after touching this/these file(s) -EXTRA_DEPS = $(MINI-OS_ROOT)/minios.mk \ - $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk +EXTRA_DEPS += $(MINI-OS_ROOT)/minios.mk +EXTRA_DEPS += $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk # Find all header files for checking dependencies. HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h) diff --git a/stubdom/Makefile b/stubdom/Makefile index e9dbf02..d4da2bb 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -341,19 +341,19 @@ grub: grub-upstream $(CROSS_ROOT) .PHONY: ioemu-stubdom ioemu-stubdom: APP_OBJS=$(CURDIR)/ioemu/i386-stubdom/qemu.a $(CURDIR)/ioemu/i386-stubdom/libqemu.a $(CURDIR)/ioemu/libqemu_common.a ioemu-stubdom: mini-os-$(XEN_TARGET_ARCH)-ioemu lwip-$(XEN_TARGET_ARCH) libxc ioemu - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_QEMU $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS="$(APP_OBJS)" + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/ioemu-minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS="$(APP_OBJS)" .PHONY: caml-stubdom caml-stubdom: mini-os-$(XEN_TARGET_ARCH)-caml lwip-$(XEN_TARGET_ARCH) libxc cross-ocaml caml - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_CAML $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS="$(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a" + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/caml/minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS="$(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a" .PHONY: c-stubdom c-stubdom: mini-os-$(XEN_TARGET_ARCH)-c lwip-$(XEN_TARGET_ARCH) libxc c - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_C $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS=$(CURDIR)/c/main.a + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/c/minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS=$(CURDIR)/c/main.a .PHONY: pv-grub pv-grub: mini-os-$(XEN_TARGET_ARCH)-grub libxc grub - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_GRUB $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub-$(XEN_TARGET_ARCH)/main.a + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/grub/minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub-$(XEN_TARGET_ARCH)/main.a ######### # install diff --git a/stubdom/c/minios.cfg b/stubdom/c/minios.cfg new file mode 100644 index 0000000..e69de29 diff --git a/stubdom/caml/minios.cfg b/stubdom/caml/minios.cfg new file mode 100644 index 0000000..e69de29 diff --git a/stubdom/grub/minios.cfg b/stubdom/grub/minios.cfg new file mode 100644 index 0000000..40cfa68 --- /dev/null +++ b/stubdom/grub/minios.cfg @@ -0,0 +1,2 @@ +CONFIG_START_NETWORK=n +CONFIG_SPARSE_BSS=n diff --git a/stubdom/ioemu-minios.cfg b/stubdom/ioemu-minios.cfg new file mode 100644 index 0000000..7ea1d2f --- /dev/null +++ b/stubdom/ioemu-minios.cfg @@ -0,0 +1 @@ +CONFIG_QEMU_XS_ARGS=y -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 11/24] mini-os: Move test functions into test.c
While useful, these test functions should not be compiled into every mini-os instance that we compile. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- extras/mini-os/Makefile | 1 + extras/mini-os/kernel.c | 414 ----------------------------------------- extras/mini-os/test.c | 469 +++++++++++++++++++++++++++++++++++++++++++++++ stubdom/c/minios.cfg | 1 + stubdom/caml/minios.cfg | 1 + 5 files changed, 472 insertions(+), 414 deletions(-) create mode 100644 extras/mini-os/test.c diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index be38170..96c661a 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -63,6 +63,7 @@ src-y += mm.c src-y += netfront.c src-y += pcifront.c src-y += sched.c +src-$(CONFIG_TEST) += test.c src-y += lib/ctype.c src-y += lib/math.c diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index 2875bf1..c8b9b8c 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -46,8 +46,6 @@ #include <xen/features.h> #include <xen/version.h> -static struct netfront_dev *net_dev; - uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32]; void setup_xen_features(void) @@ -66,407 +64,10 @@ void setup_xen_features(void) } } -void test_xenbus(void); - -static void xenbus_tester(void *p) -{ - printk("Xenbus tests disabled, because of a Xend bug.\n"); - /* test_xenbus(); */ -} - -static void periodic_thread(void *p) -{ - struct timeval tv; - printk("Periodic thread started.\n"); - for(;;) - { - gettimeofday(&tv, NULL); - printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); - msleep(1000); - } -} - -static void netfront_thread(void *p) -{ - net_dev = init_netfront(NULL, NULL, NULL, NULL); -} - -static struct blkfront_dev *blk_dev; -static struct blkfront_info blk_info; -static uint64_t blk_size_read; -static uint64_t blk_size_write; - -struct blk_req { - struct blkfront_aiocb aiocb; - int rand_value; - struct blk_req *next; -}; - -#ifdef BLKTEST_WRITE -static struct blk_req *blk_to_read; -#endif - -static struct blk_req *blk_alloc_req(uint64_t sector) -{ - struct blk_req *req = xmalloc(struct blk_req); - req->aiocb.aio_dev = blk_dev; - req->aiocb.aio_buf = _xmalloc(blk_info.sector_size, blk_info.sector_size); - req->aiocb.aio_nbytes = blk_info.sector_size; - req->aiocb.aio_offset = sector * blk_info.sector_size; - req->aiocb.data = req; - req->next = NULL; - return req; -} - -static void blk_read_completed(struct blkfront_aiocb *aiocb, int ret) -{ - struct blk_req *req = aiocb->data; - if (ret) - printk("got error code %d when reading at offset %ld\n", ret, aiocb->aio_offset); - else - blk_size_read += blk_info.sector_size; - free(aiocb->aio_buf); - free(req); -} - -static void blk_read_sector(uint64_t sector) -{ - struct blk_req *req; - - req = blk_alloc_req(sector); - req->aiocb.aio_cb = blk_read_completed; - - blkfront_aio_read(&req->aiocb); -} - -#ifdef BLKTEST_WRITE -static void blk_write_read_completed(struct blkfront_aiocb *aiocb, int ret) -{ - struct blk_req *req = aiocb->data; - int rand_value; - int i; - int *buf; - - if (ret) { - printk("got error code %d when reading back at offset %ld\n", ret, aiocb->aio_offset); - free(aiocb->aio_buf); - free(req); - return; - } - blk_size_read += blk_info.sector_size; - buf = (int*) aiocb->aio_buf; - rand_value = req->rand_value; - for (i = 0; i < blk_info.sector_size / sizeof(int); i++) { - if (buf[i] != rand_value) { - printk("bogus data at offset %ld\n", aiocb->aio_offset + i); - break; - } - rand_value *= RAND_MIX; - } - free(aiocb->aio_buf); - free(req); -} - -static void blk_write_completed(struct blkfront_aiocb *aiocb, int ret) -{ - struct blk_req *req = aiocb->data; - if (ret) { - printk("got error code %d when writing at offset %ld\n", ret, aiocb->aio_offset); - free(aiocb->aio_buf); - free(req); - return; - } - blk_size_write += blk_info.sector_size; - /* Push write check */ - req->next = blk_to_read; - blk_to_read = req; -} - -static void blk_write_sector(uint64_t sector) -{ - struct blk_req *req; - int rand_value; - int i; - int *buf; - - req = blk_alloc_req(sector); - req->aiocb.aio_cb = blk_write_completed; - req->rand_value = rand_value = rand(); - - buf = (int*) req->aiocb.aio_buf; - for (i = 0; i < blk_info.sector_size / sizeof(int); i++) { - buf[i] = rand_value; - rand_value *= RAND_MIX; - } - - blkfront_aio_write(&req->aiocb); -} -#endif - -static void blkfront_thread(void *p) -{ - time_t lasttime = 0; - - blk_dev = init_blkfront(NULL, &blk_info); - if (!blk_dev) - return; - - if (blk_info.info & VDISK_CDROM) - printk("Block device is a CDROM\n"); - if (blk_info.info & VDISK_REMOVABLE) - printk("Block device is removable\n"); - if (blk_info.info & VDISK_READONLY) - printk("Block device is read-only\n"); - -#ifdef BLKTEST_WRITE - if (blk_info.mode == O_RDWR) { - blk_write_sector(0); - blk_write_sector(blk_info.sectors-1); - } else -#endif - { - blk_read_sector(0); - blk_read_sector(blk_info.sectors-1); - } - - while (1) { - uint64_t sector = rand() % blk_info.sectors; - struct timeval tv; -#ifdef BLKTEST_WRITE - if (blk_info.mode == O_RDWR) - blk_write_sector(sector); - else -#endif - blk_read_sector(sector); - blkfront_aio_poll(blk_dev); - gettimeofday(&tv, NULL); - if (tv.tv_sec > lasttime + 10) { - printk("%llu read, %llu write\n", blk_size_read, blk_size_write); - lasttime = tv.tv_sec; - } - -#ifdef BLKTEST_WRITE - while (blk_to_read) { - struct blk_req *req = blk_to_read; - blk_to_read = blk_to_read->next; - req->aiocb.aio_cb = blk_write_read_completed; - blkfront_aio_read(&req->aiocb); - } -#endif - } -} - -#define WIDTH 800 -#define HEIGHT 600 -#define DEPTH 32 - -static uint32_t *fb; -static int refresh_period = 50; -static struct fbfront_dev *fb_dev; -static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0); - -static void fbfront_drawvert(int x, int y1, int y2, uint32_t color) -{ - int y; - if (x < 0) - return; - if (x >= WIDTH) - return; - if (y1 < 0) - y1 = 0; - if (y2 >= HEIGHT) - y2 = HEIGHT-1; - for (y = y1; y <= y2; y++) - fb[x + y*WIDTH] ^= color; -} - -static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color) -{ - int x; - if (y < 0) - return; - if (y >= HEIGHT) - return; - if (x1 < 0) - x1 = 0; - if (x2 >= WIDTH) - x2 = WIDTH-1; - for (x = x1; x <= x2; x++) - fb[x + y*WIDTH] ^= color; -} - -static void fbfront_thread(void *p) -{ - size_t line_length = WIDTH * (DEPTH / 8); - size_t memsize = HEIGHT * line_length; - unsigned long *mfns; - int i, n = (memsize + PAGE_SIZE-1) / PAGE_SIZE; - - memsize = n * PAGE_SIZE; - fb = _xmalloc(memsize, PAGE_SIZE); - memset(fb, 0, memsize); - mfns = xmalloc_array(unsigned long, n); - for (i = 0; i < n; i++) - mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE); - fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n); - xfree(mfns); - if (!fb_dev) { - xfree(fb); - return; - } - up(&fbfront_sem); -} - -static void clip_cursor(int *x, int *y) -{ - if (*x < 0) - *x = 0; - if (*x >= WIDTH) - *x = WIDTH - 1; - if (*y < 0) - *y = 0; - if (*y >= HEIGHT) - *y = HEIGHT - 1; -} - -static void refresh_cursor(int new_x, int new_y) -{ - static int old_x = -1, old_y = -1; - - if (!refresh_period) - return; - - if (old_x != -1 && old_y != -1) { - fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff); - fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff); - fbfront_update(fb_dev, old_x, old_y, 9, 9); - } - old_x = new_x; - old_y = new_y; - fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff); - fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff); - fbfront_update(fb_dev, new_x, new_y, 9, 9); -} - -static struct kbdfront_dev *kbd_dev; -static void kbdfront_thread(void *p) -{ - DEFINE_WAIT(w); - DEFINE_WAIT(w2); - int x = WIDTH / 2, y = HEIGHT / 2, z = 0; - - kbd_dev = init_kbdfront(NULL, 1); - if (!kbd_dev) - return; - - down(&fbfront_sem); - refresh_cursor(x, y); - while (1) { - union xenkbd_in_event kbdevent; - union xenfb_in_event fbevent; - int sleep = 1; - - add_waiter(w, kbdfront_queue); - add_waiter(w2, fbfront_queue); - - while (kbdfront_receive(kbd_dev, &kbdevent, 1) != 0) { - sleep = 0; - switch(kbdevent.type) { - case XENKBD_TYPE_MOTION: - printk("motion x:%d y:%d z:%d\n", - kbdevent.motion.rel_x, - kbdevent.motion.rel_y, - kbdevent.motion.rel_z); - x += kbdevent.motion.rel_x; - y += kbdevent.motion.rel_y; - z += kbdevent.motion.rel_z; - clip_cursor(&x, &y); - refresh_cursor(x, y); - break; - case XENKBD_TYPE_POS: - printk("pos x:%d y:%d dz:%d\n", - kbdevent.pos.abs_x, - kbdevent.pos.abs_y, - kbdevent.pos.rel_z); - x = kbdevent.pos.abs_x; - y = kbdevent.pos.abs_y; - z = kbdevent.pos.rel_z; - clip_cursor(&x, &y); - refresh_cursor(x, y); - break; - case XENKBD_TYPE_KEY: - printk("key %d %s\n", - kbdevent.key.keycode, - kbdevent.key.pressed ? "pressed" : "released"); - if (kbdevent.key.keycode == BTN_LEFT) { - printk("mouse %s at (%d,%d,%d)\n", - kbdevent.key.pressed ? "clic" : "release", x, y, z); - if (kbdevent.key.pressed) { - uint32_t color = rand(); - fbfront_drawvert(x - 16, y - 16, y + 15, color); - fbfront_drawhoriz(x - 16, x + 15, y + 16, color); - fbfront_drawvert(x + 16, y - 15, y + 16, color); - fbfront_drawhoriz(x - 15, x + 16, y - 16, color); - fbfront_update(fb_dev, x - 16, y - 16, 33, 33); - } - } else if (kbdevent.key.keycode == KEY_Q) { - struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; - HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); - do_exit(); - } - break; - } - } - while (fbfront_receive(fb_dev, &fbevent, 1) != 0) { - sleep = 0; - switch(fbevent.type) { - case XENFB_TYPE_REFRESH_PERIOD: - refresh_period = fbevent.refresh_period.period; - printk("refresh period %d\n", refresh_period); - refresh_cursor(x, y); - break; - } - } - if (sleep) - schedule(); - } -} - -static struct pcifront_dev *pci_dev; - -static void print_pcidev(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun) -{ - unsigned int vendor, device, rev, class; - - pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x00, 2, &vendor); - pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x02, 2, &device); - pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x08, 1, &rev); - pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x0a, 2, &class); - - printk("%04x:%02x:%02x.%02x %04x: %04x:%04x (rev %02x)\n", domain, bus, slot, fun, class, vendor, device, rev); -} - -static void pcifront_thread(void *p) -{ - pcifront_watches(NULL); - pci_dev = init_pcifront(NULL); - if (!pci_dev) - return; - printk("PCI devices:\n"); - pcifront_scan(pci_dev, print_pcidev); -} - /* This should be overridden by the application we are linked against. */ __attribute__((weak)) int app_main(start_info_t *si) { printk("Dummy main: start_info=%p\n", si); - create_thread("xenbus_tester", xenbus_tester, si); - create_thread("periodic_thread", periodic_thread, si); - create_thread("netfront", netfront_thread, si); - create_thread("blkfront", blkfront_thread, si); - create_thread("fbfront", fbfront_thread, si); - create_thread("kbdfront", kbdfront_thread, si); - create_thread("pcifront", pcifront_thread, si); return 0; } @@ -534,21 +135,6 @@ void start_kernel(start_info_t *si) void stop_kernel(void) { - if (net_dev) - shutdown_netfront(net_dev); - - if (blk_dev) - shutdown_blkfront(blk_dev); - - if (fb_dev) - shutdown_fbfront(fb_dev); - - if (kbd_dev) - shutdown_kbdfront(kbd_dev); - - if (pci_dev) - shutdown_pcifront(pci_dev); - /* TODO: fs import */ local_irq_disable(); diff --git a/extras/mini-os/test.c b/extras/mini-os/test.c new file mode 100644 index 0000000..9039cb3 --- /dev/null +++ b/extras/mini-os/test.c @@ -0,0 +1,469 @@ +/****************************************************************************** + * test.c + * + * Test code for all the various frontends; split from kernel.c + * + * Copyright (c) 2002-2003, K A Fraser & R Neugebauer + * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge + * Copyright (c) 2006, Robert Kaiser, FH Wiesbaden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <mini-os/os.h> +#include <mini-os/hypervisor.h> +#include <mini-os/mm.h> +#include <mini-os/events.h> +#include <mini-os/time.h> +#include <mini-os/types.h> +#include <mini-os/lib.h> +#include <mini-os/sched.h> +#include <mini-os/xenbus.h> +#include <mini-os/gnttab.h> +#include <mini-os/netfront.h> +#include <mini-os/blkfront.h> +#include <mini-os/fbfront.h> +#include <mini-os/pcifront.h> +#include <mini-os/xmalloc.h> +#include <fcntl.h> +#include <xen/features.h> +#include <xen/version.h> + +static struct netfront_dev *net_dev; + +void test_xenbus(void); + +static void xenbus_tester(void *p) +{ + printk("Xenbus tests disabled, because of a Xend bug.\n"); + /* test_xenbus(); */ +} + +static void periodic_thread(void *p) +{ + struct timeval tv; + printk("Periodic thread started.\n"); + for(;;) + { + gettimeofday(&tv, NULL); + printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); + msleep(1000); + } +} + +static void netfront_thread(void *p) +{ + net_dev = init_netfront(NULL, NULL, NULL, NULL); +} + +static struct blkfront_dev *blk_dev; +static struct blkfront_info blk_info; +static uint64_t blk_size_read; +static uint64_t blk_size_write; + +struct blk_req { + struct blkfront_aiocb aiocb; + int rand_value; + struct blk_req *next; +}; + +#ifdef BLKTEST_WRITE +static struct blk_req *blk_to_read; +#endif + +static struct blk_req *blk_alloc_req(uint64_t sector) +{ + struct blk_req *req = xmalloc(struct blk_req); + req->aiocb.aio_dev = blk_dev; + req->aiocb.aio_buf = _xmalloc(blk_info.sector_size, blk_info.sector_size); + req->aiocb.aio_nbytes = blk_info.sector_size; + req->aiocb.aio_offset = sector * blk_info.sector_size; + req->aiocb.data = req; + req->next = NULL; + return req; +} + +static void blk_read_completed(struct blkfront_aiocb *aiocb, int ret) +{ + struct blk_req *req = aiocb->data; + if (ret) + printk("got error code %d when reading at offset %ld\n", ret, aiocb->aio_offset); + else + blk_size_read += blk_info.sector_size; + free(aiocb->aio_buf); + free(req); +} + +static void blk_read_sector(uint64_t sector) +{ + struct blk_req *req; + + req = blk_alloc_req(sector); + req->aiocb.aio_cb = blk_read_completed; + + blkfront_aio_read(&req->aiocb); +} + +#ifdef BLKTEST_WRITE +static void blk_write_read_completed(struct blkfront_aiocb *aiocb, int ret) +{ + struct blk_req *req = aiocb->data; + int rand_value; + int i; + int *buf; + + if (ret) { + printk("got error code %d when reading back at offset %ld\n", ret, aiocb->aio_offset); + free(aiocb->aio_buf); + free(req); + return; + } + blk_size_read += blk_info.sector_size; + buf = (int*) aiocb->aio_buf; + rand_value = req->rand_value; + for (i = 0; i < blk_info.sector_size / sizeof(int); i++) { + if (buf[i] != rand_value) { + printk("bogus data at offset %ld\n", aiocb->aio_offset + i); + break; + } + rand_value *= RAND_MIX; + } + free(aiocb->aio_buf); + free(req); +} + +static void blk_write_completed(struct blkfront_aiocb *aiocb, int ret) +{ + struct blk_req *req = aiocb->data; + if (ret) { + printk("got error code %d when writing at offset %ld\n", ret, aiocb->aio_offset); + free(aiocb->aio_buf); + free(req); + return; + } + blk_size_write += blk_info.sector_size; + /* Push write check */ + req->next = blk_to_read; + blk_to_read = req; +} + +static void blk_write_sector(uint64_t sector) +{ + struct blk_req *req; + int rand_value; + int i; + int *buf; + + req = blk_alloc_req(sector); + req->aiocb.aio_cb = blk_write_completed; + req->rand_value = rand_value = rand(); + + buf = (int*) req->aiocb.aio_buf; + for (i = 0; i < blk_info.sector_size / sizeof(int); i++) { + buf[i] = rand_value; + rand_value *= RAND_MIX; + } + + blkfront_aio_write(&req->aiocb); +} +#endif + +static void blkfront_thread(void *p) +{ + time_t lasttime = 0; + + blk_dev = init_blkfront(NULL, &blk_info); + if (!blk_dev) + return; + + if (blk_info.info & VDISK_CDROM) + printk("Block device is a CDROM\n"); + if (blk_info.info & VDISK_REMOVABLE) + printk("Block device is removable\n"); + if (blk_info.info & VDISK_READONLY) + printk("Block device is read-only\n"); + +#ifdef BLKTEST_WRITE + if (blk_info.mode == O_RDWR) { + blk_write_sector(0); + blk_write_sector(blk_info.sectors-1); + } else +#endif + { + blk_read_sector(0); + blk_read_sector(blk_info.sectors-1); + } + + while (1) { + uint64_t sector = rand() % blk_info.sectors; + struct timeval tv; +#ifdef BLKTEST_WRITE + if (blk_info.mode == O_RDWR) + blk_write_sector(sector); + else +#endif + blk_read_sector(sector); + blkfront_aio_poll(blk_dev); + gettimeofday(&tv, NULL); + if (tv.tv_sec > lasttime + 10) { + printk("%llu read, %llu write\n", blk_size_read, blk_size_write); + lasttime = tv.tv_sec; + } + +#ifdef BLKTEST_WRITE + while (blk_to_read) { + struct blk_req *req = blk_to_read; + blk_to_read = blk_to_read->next; + req->aiocb.aio_cb = blk_write_read_completed; + blkfront_aio_read(&req->aiocb); + } +#endif + } +} + +#define WIDTH 800 +#define HEIGHT 600 +#define DEPTH 32 + +static uint32_t *fb; +static int refresh_period = 50; +static struct fbfront_dev *fb_dev; +static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0); + +static void fbfront_drawvert(int x, int y1, int y2, uint32_t color) +{ + int y; + if (x < 0) + return; + if (x >= WIDTH) + return; + if (y1 < 0) + y1 = 0; + if (y2 >= HEIGHT) + y2 = HEIGHT-1; + for (y = y1; y <= y2; y++) + fb[x + y*WIDTH] ^= color; +} + +static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color) +{ + int x; + if (y < 0) + return; + if (y >= HEIGHT) + return; + if (x1 < 0) + x1 = 0; + if (x2 >= WIDTH) + x2 = WIDTH-1; + for (x = x1; x <= x2; x++) + fb[x + y*WIDTH] ^= color; +} + +static void fbfront_thread(void *p) +{ + size_t line_length = WIDTH * (DEPTH / 8); + size_t memsize = HEIGHT * line_length; + unsigned long *mfns; + int i, n = (memsize + PAGE_SIZE-1) / PAGE_SIZE; + + memsize = n * PAGE_SIZE; + fb = _xmalloc(memsize, PAGE_SIZE); + memset(fb, 0, memsize); + mfns = xmalloc_array(unsigned long, n); + for (i = 0; i < n; i++) + mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE); + fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n); + xfree(mfns); + if (!fb_dev) { + xfree(fb); + return; + } + up(&fbfront_sem); +} + +static void clip_cursor(int *x, int *y) +{ + if (*x < 0) + *x = 0; + if (*x >= WIDTH) + *x = WIDTH - 1; + if (*y < 0) + *y = 0; + if (*y >= HEIGHT) + *y = HEIGHT - 1; +} + +static void refresh_cursor(int new_x, int new_y) +{ + static int old_x = -1, old_y = -1; + + if (!refresh_period) + return; + + if (old_x != -1 && old_y != -1) { + fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff); + fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff); + fbfront_update(fb_dev, old_x, old_y, 9, 9); + } + old_x = new_x; + old_y = new_y; + fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff); + fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff); + fbfront_update(fb_dev, new_x, new_y, 9, 9); +} + +static struct kbdfront_dev *kbd_dev; +static void kbdfront_thread(void *p) +{ + DEFINE_WAIT(w); + DEFINE_WAIT(w2); + int x = WIDTH / 2, y = HEIGHT / 2, z = 0; + + kbd_dev = init_kbdfront(NULL, 1); + if (!kbd_dev) + return; + + down(&fbfront_sem); + refresh_cursor(x, y); + while (1) { + union xenkbd_in_event kbdevent; + union xenfb_in_event fbevent; + int sleep = 1; + + add_waiter(w, kbdfront_queue); + add_waiter(w2, fbfront_queue); + + while (kbdfront_receive(kbd_dev, &kbdevent, 1) != 0) { + sleep = 0; + switch(kbdevent.type) { + case XENKBD_TYPE_MOTION: + printk("motion x:%d y:%d z:%d\n", + kbdevent.motion.rel_x, + kbdevent.motion.rel_y, + kbdevent.motion.rel_z); + x += kbdevent.motion.rel_x; + y += kbdevent.motion.rel_y; + z += kbdevent.motion.rel_z; + clip_cursor(&x, &y); + refresh_cursor(x, y); + break; + case XENKBD_TYPE_POS: + printk("pos x:%d y:%d dz:%d\n", + kbdevent.pos.abs_x, + kbdevent.pos.abs_y, + kbdevent.pos.rel_z); + x = kbdevent.pos.abs_x; + y = kbdevent.pos.abs_y; + z = kbdevent.pos.rel_z; + clip_cursor(&x, &y); + refresh_cursor(x, y); + break; + case XENKBD_TYPE_KEY: + printk("key %d %s\n", + kbdevent.key.keycode, + kbdevent.key.pressed ? "pressed" : "released"); + if (kbdevent.key.keycode == BTN_LEFT) { + printk("mouse %s at (%d,%d,%d)\n", + kbdevent.key.pressed ? "clic" : "release", x, y, z); + if (kbdevent.key.pressed) { + uint32_t color = rand(); + fbfront_drawvert(x - 16, y - 16, y + 15, color); + fbfront_drawhoriz(x - 16, x + 15, y + 16, color); + fbfront_drawvert(x + 16, y - 15, y + 16, color); + fbfront_drawhoriz(x - 15, x + 16, y - 16, color); + fbfront_update(fb_dev, x - 16, y - 16, 33, 33); + } + } else if (kbdevent.key.keycode == KEY_Q) { + struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; + HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + do_exit(); + } + break; + } + } + while (fbfront_receive(fb_dev, &fbevent, 1) != 0) { + sleep = 0; + switch(fbevent.type) { + case XENFB_TYPE_REFRESH_PERIOD: + refresh_period = fbevent.refresh_period.period; + printk("refresh period %d\n", refresh_period); + refresh_cursor(x, y); + break; + } + } + if (sleep) + schedule(); + } +} + +static struct pcifront_dev *pci_dev; + +static void print_pcidev(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun) +{ + unsigned int vendor, device, rev, class; + + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x00, 2, &vendor); + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x02, 2, &device); + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x08, 1, &rev); + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x0a, 2, &class); + + printk("%04x:%02x:%02x.%02x %04x: %04x:%04x (rev %02x)\n", domain, bus, slot, fun, class, vendor, device, rev); +} + +static void pcifront_thread(void *p) +{ + pcifront_watches(NULL); + pci_dev = init_pcifront(NULL); + if (!pci_dev) + return; + printk("PCI devices:\n"); + pcifront_scan(pci_dev, print_pcidev); +} + +int app_main(start_info_t *si) +{ + printk("Test main: start_info=%p\n", si); + create_thread("xenbus_tester", xenbus_tester, si); + create_thread("periodic_thread", periodic_thread, si); + create_thread("netfront", netfront_thread, si); + create_thread("blkfront", blkfront_thread, si); + create_thread("fbfront", fbfront_thread, si); + create_thread("kbdfront", kbdfront_thread, si); + create_thread("pcifront", pcifront_thread, si); + return 0; +} + +void shutdown_frontends(void) +{ + if (net_dev) + shutdown_netfront(net_dev); + + if (blk_dev) + shutdown_blkfront(blk_dev); + + if (fb_dev) + shutdown_fbfront(fb_dev); + + if (kbd_dev) + shutdown_kbdfront(kbd_dev); + + if (pci_dev) + shutdown_pcifront(pci_dev); +} diff --git a/stubdom/c/minios.cfg b/stubdom/c/minios.cfg index e69de29..e1faee5 100644 --- a/stubdom/c/minios.cfg +++ b/stubdom/c/minios.cfg @@ -0,0 +1 @@ +CONFIG_TEST=y diff --git a/stubdom/caml/minios.cfg b/stubdom/caml/minios.cfg index e69de29..e1faee5 100644 --- a/stubdom/caml/minios.cfg +++ b/stubdom/caml/minios.cfg @@ -0,0 +1 @@ +CONFIG_TEST=y -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:44 UTC
[PATCH 12/24] mini-os: make frontends and xenbus optional
This adds compile-time logic to disable certain frontends in mini-os: - pcifront is disabled by default, enabled for ioemu - blkfront, netfront, fbfront, kbdfront, consfront are enabled by default - xenbus is required for any frontend, and is enabled by default If all frontends and xenbus are disabled, mini-os will run without needing to communicate with xenstore, making it suitable to run the xenstore daemon. The console frontend is not required for the initial console, only consoles opened via openpt or ptmx. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- extras/mini-os/Makefile | 32 ++++- extras/mini-os/console/console.c | 5 - extras/mini-os/console/console.h | 2 + extras/mini-os/console/xenbus.c | 197 +++++++++++++++++++++++++++++++++ extras/mini-os/console/xencons_ring.c | 182 +------------------------------ extras/mini-os/include/lib.h | 2 + extras/mini-os/include/xenbus.h | 12 ++ extras/mini-os/kernel.c | 4 - extras/mini-os/lib/sys.c | 43 +++++++ extras/mini-os/main.c | 6 +- stubdom/ioemu-minios.cfg | 1 + 11 files changed, 289 insertions(+), 197 deletions(-) create mode 100644 extras/mini-os/console/console.h create mode 100644 extras/mini-os/console/xenbus.c diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index 96c661a..ea5d0b5 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -19,11 +19,25 @@ endif CONFIG_START_NETWORK ?= y CONFIG_SPARSE_BSS ?= y CONFIG_QEMU_XS_ARGS ?= n +CONFIG_PCIFRONT ?= n +CONFIG_BLKFRONT ?= y +CONFIG_NETFRONT ?= y +CONFIG_FBFRONT ?= y +CONFIG_KBDFRONT ?= y +CONFIG_CONSFRONT ?= y +CONFIG_XENBUS ?= y # Export config items as compiler directives flags-$(CONFIG_START_NETWORK) += -DCONFIG_START_NETWORK flags-$(CONFIG_SPARSE_BSS) += -DCONFIG_SPARSE_BSS flags-$(CONFIG_QEMU_XS_ARGS) += -DCONFIG_QEMU_XS_ARGS +flags-$(CONFIG_PCIFRONT) += -DCONFIG_PCIFRONT +flags-$(CONFIG_BLKFRONT) += -DCONFIG_BLKFRONT +flags-$(CONFIG_NETFRONT) += -DCONFIG_NETFRONT +flags-$(CONFIG_KBDFRONT) += -DCONFIG_KBDFRONT +flags-$(CONFIG_FBFRONT) += -DCONFIG_FBFRONT +flags-$(CONFIG_CONSFRONT) += -DCONFIG_CONSFRONT +flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS DEF_CFLAGS += $(flags-y) @@ -49,10 +63,10 @@ TARGET := mini-os # Subdirectories common to mini-os SUBDIRS := lib xenbus console -src-y += blkfront.c +src-$(CONFIG_BLKFRONT) += blkfront.c src-y += daytime.c src-y += events.c -src-y += fbfront.c +src-$(CONFIG_FBFRONT) += fbfront.c src-y += gntmap.c src-y += gnttab.c src-y += hypervisor.c @@ -60,8 +74,8 @@ src-y += kernel.c src-y += lock.c src-y += main.c src-y += mm.c -src-y += netfront.c -src-y += pcifront.c +src-$(CONFIG_NETFRONT) += netfront.c +src-$(CONFIG_PCIFRONT) += pcifront.c src-y += sched.c src-$(CONFIG_TEST) += test.c @@ -72,12 +86,13 @@ src-y += lib/stack_chk_fail.c src-y += lib/string.c src-y += lib/sys.c src-y += lib/xmalloc.c -src-y += lib/xs.c +src-$(CONFIG_XENBUS) += lib/xs.c -src-y += xenbus/xenbus.c +src-$(CONFIG_XENBUS) += xenbus/xenbus.c src-y += console/console.c src-y += console/xencons_ring.c +src-$(CONFIG_CONSFRONT) += console/xenbus.c # The common mini-os objects to build. APP_OBJS :@@ -108,7 +123,10 @@ ifeq ($(lwip),y) LWC := $(shell find $(LWIPDIR)/ -type f -name ''*.c'') LWC := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC)) LWO := $(patsubst %.c,%.o,$(LWC)) -LWO += $(addprefix $(OBJ_DIR)/,lwip-arch.o lwip-net.o) +LWO += $(OBJ_DIR)/lwip-arch.o +ifeq ($(CONFIG_NETFRONT),y) +LWO += $(OBJ_DIR)/lwip-net.o +endif $(OBJ_DIR)/lwip.a: $(LWO) $(RM) $@ diff --git a/extras/mini-os/console/console.c b/extras/mini-os/console/console.c index 2b4ed9f..fec3791 100644 --- a/extras/mini-os/console/console.c +++ b/extras/mini-os/console/console.c @@ -158,8 +158,3 @@ void init_console(void) /* This is also required to notify the daemon */ printk("done.\n"); } - -void fini_console(struct consfront_dev *dev) -{ - if (dev) free_consfront(dev); -} diff --git a/extras/mini-os/console/console.h b/extras/mini-os/console/console.h new file mode 100644 index 0000000..e85147a --- /dev/null +++ b/extras/mini-os/console/console.h @@ -0,0 +1,2 @@ + +void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data); diff --git a/extras/mini-os/console/xenbus.c b/extras/mini-os/console/xenbus.c new file mode 100644 index 0000000..a7c517d --- /dev/null +++ b/extras/mini-os/console/xenbus.c @@ -0,0 +1,197 @@ +#include <mini-os/types.h> +#include <mini-os/wait.h> +#include <mini-os/mm.h> +#include <mini-os/hypervisor.h> +#include <mini-os/events.h> +#include <mini-os/os.h> +#include <mini-os/lib.h> +#include <mini-os/xenbus.h> +#include <xen/io/console.h> +#include <xen/io/protocols.h> +#include <xen/io/ring.h> +#include <mini-os/xmalloc.h> +#include <mini-os/gnttab.h> +#include "console.h" + +void free_consfront(struct consfront_dev *dev) +{ + char* err = NULL; + XenbusState state; + + char path[strlen(dev->backend) + 1 + 5 + 1]; + char nodename[strlen(dev->nodename) + 1 + 5 + 1]; + + snprintf(path, sizeof(path), "%s/state", dev->backend); + snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename); + + if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) { + printk("free_consfront: error changing state to %d: %s\n", + XenbusStateClosing, err); + goto close; + } + state = xenbus_read_integer(path); + while (err == NULL && state < XenbusStateClosing) + err = xenbus_wait_for_state_change(path, &state, &dev->events); + if (err) free(err); + + if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) { + printk("free_consfront: error changing state to %d: %s\n", + XenbusStateClosed, err); + goto close; + } + +close: + if (err) free(err); + xenbus_unwatch_path_token(XBT_NIL, path, path); + + mask_evtchn(dev->evtchn); + unbind_evtchn(dev->evtchn); + free(dev->backend); + free(dev->nodename); + + gnttab_end_access(dev->ring_ref); + + free_page(dev->ring); + free(dev); +} + +struct consfront_dev *init_consfront(char *_nodename) +{ + xenbus_transaction_t xbt; + char* err; + char* message=NULL; + int retry=0; + char* msg = NULL; + char nodename[256]; + char path[256]; + static int consfrontends = 3; + struct consfront_dev *dev; + int res; + + if (!_nodename) + snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends); + else + strncpy(nodename, _nodename, sizeof(nodename)); + + printk("******************* CONSFRONT for %s **********\n\n\n", nodename); + + consfrontends++; + dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); + dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif + + snprintf(path, sizeof(path), "%s/backend-id", nodename); + if ((res = xenbus_read_integer(path)) < 0) + return NULL; + else + dev->dom = res; + evtchn_alloc_unbound(dev->dom, console_handle_input, dev, &dev->evtchn); + + dev->ring = (struct xencons_interface *) alloc_page(); + memset(dev->ring, 0, PAGE_SIZE); + dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0); + + dev->events = NULL; + +again: + err = xenbus_transaction_start(&xbt); + if (err) { + printk("starting transaction\n"); + free(err); + } + + err = xenbus_printf(xbt, nodename, "ring-ref","%u", + dev->ring_ref); + if (err) { + message = "writing ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, + "port", "%u", dev->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, + "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); + if (err) { + message = "writing protocol"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu"); + if (err) { + message = "writing type"; + goto abort_transaction; + } + + snprintf(path, sizeof(path), "%s/state", nodename); + err = xenbus_switch_state(xbt, path, XenbusStateConnected); + if (err) { + message = "switching state"; + goto abort_transaction; + } + + + err = xenbus_transaction_end(xbt, 0, &retry); + if (err) free(err); + if (retry) { + goto again; + printk("completing transaction\n"); + } + + goto done; + +abort_transaction: + free(err); + err = xenbus_transaction_end(xbt, 1, &retry); + goto error; + +done: + + snprintf(path, sizeof(path), "%s/backend", nodename); + msg = xenbus_read(XBT_NIL, path, &dev->backend); + if (msg) { + printk("Error %s when reading the backend path %s\n", msg, path); + goto error; + } + + printk("backend at %s\n", dev->backend); + + { + XenbusState state; + char path[strlen(dev->backend) + 1 + 19 + 1]; + snprintf(path, sizeof(path), "%s/state", dev->backend); + + xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); + msg = NULL; + state = xenbus_read_integer(path); + while (msg == NULL && state < XenbusStateConnected) + msg = xenbus_wait_for_state_change(path, &state, &dev->events); + if (msg != NULL || state != XenbusStateConnected) { + printk("backend not available, state=%d\n", state); + xenbus_unwatch_path_token(XBT_NIL, path, path); + goto error; + } + } + unmask_evtchn(dev->evtchn); + + printk("**************************\n"); + + return dev; + +error: + free(msg); + free(err); + free_consfront(dev); + return NULL; +} + +void fini_console(struct consfront_dev *dev) +{ + if (dev) free_consfront(dev); +} + diff --git a/extras/mini-os/console/xencons_ring.c b/extras/mini-os/console/xencons_ring.c index af0afed..81c8e99 100644 --- a/extras/mini-os/console/xencons_ring.c +++ b/extras/mini-os/console/xencons_ring.c @@ -11,6 +11,7 @@ #include <xen/io/ring.h> #include <mini-os/xmalloc.h> #include <mini-os/gnttab.h> +#include "console.h" DECLARE_WAIT_QUEUE_HEAD(console_queue); @@ -70,7 +71,7 @@ int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len) -static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *data) +void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data) { struct consfront_dev *dev = (struct consfront_dev *) data; #ifdef HAVE_LIBC @@ -173,7 +174,7 @@ struct consfront_dev *xencons_ring_init(void) dev->evtchn = start_info.console.domU.evtchn; dev->ring = (struct xencons_interface *) mfn_to_virt(start_info.console.domU.mfn); - err = bind_evtchn(dev->evtchn, handle_input, dev); + err = bind_evtchn(dev->evtchn, console_handle_input, dev); if (err <= 0) { printk("XEN console request chn bind failed %i\n", err); free(dev); @@ -187,183 +188,6 @@ struct consfront_dev *xencons_ring_init(void) return dev; } -void free_consfront(struct consfront_dev *dev) -{ - char* err = NULL; - XenbusState state; - - char path[strlen(dev->backend) + 1 + 5 + 1]; - char nodename[strlen(dev->nodename) + 1 + 5 + 1]; - - snprintf(path, sizeof(path), "%s/state", dev->backend); - snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename); - - if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) { - printk("free_consfront: error changing state to %d: %s\n", - XenbusStateClosing, err); - goto close; - } - state = xenbus_read_integer(path); - while (err == NULL && state < XenbusStateClosing) - err = xenbus_wait_for_state_change(path, &state, &dev->events); - if (err) free(err); - - if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) { - printk("free_consfront: error changing state to %d: %s\n", - XenbusStateClosed, err); - goto close; - } - -close: - if (err) free(err); - xenbus_unwatch_path_token(XBT_NIL, path, path); - - mask_evtchn(dev->evtchn); - unbind_evtchn(dev->evtchn); - free(dev->backend); - free(dev->nodename); - - gnttab_end_access(dev->ring_ref); - - free_page(dev->ring); - free(dev); -} - -struct consfront_dev *init_consfront(char *_nodename) -{ - xenbus_transaction_t xbt; - char* err; - char* message=NULL; - int retry=0; - char* msg = NULL; - char nodename[256]; - char path[256]; - static int consfrontends = 3; - struct consfront_dev *dev; - int res; - - if (!_nodename) - snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends); - else - strncpy(nodename, _nodename, sizeof(nodename)); - - printk("******************* CONSFRONT for %s **********\n\n\n", nodename); - - consfrontends++; - dev = malloc(sizeof(*dev)); - memset(dev, 0, sizeof(*dev)); - dev->nodename = strdup(nodename); -#ifdef HAVE_LIBC - dev->fd = -1; -#endif - - snprintf(path, sizeof(path), "%s/backend-id", nodename); - if ((res = xenbus_read_integer(path)) < 0) - return NULL; - else - dev->dom = res; - evtchn_alloc_unbound(dev->dom, handle_input, dev, &dev->evtchn); - - dev->ring = (struct xencons_interface *) alloc_page(); - memset(dev->ring, 0, PAGE_SIZE); - dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0); - - dev->events = NULL; - -again: - err = xenbus_transaction_start(&xbt); - if (err) { - printk("starting transaction\n"); - free(err); - } - - err = xenbus_printf(xbt, nodename, "ring-ref","%u", - dev->ring_ref); - if (err) { - message = "writing ring-ref"; - goto abort_transaction; - } - err = xenbus_printf(xbt, nodename, - "port", "%u", dev->evtchn); - if (err) { - message = "writing event-channel"; - goto abort_transaction; - } - err = xenbus_printf(xbt, nodename, - "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); - if (err) { - message = "writing protocol"; - goto abort_transaction; - } - - err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu"); - if (err) { - message = "writing type"; - goto abort_transaction; - } - - snprintf(path, sizeof(path), "%s/state", nodename); - err = xenbus_switch_state(xbt, path, XenbusStateConnected); - if (err) { - message = "switching state"; - goto abort_transaction; - } - - - err = xenbus_transaction_end(xbt, 0, &retry); - if (err) free(err); - if (retry) { - goto again; - printk("completing transaction\n"); - } - - goto done; - -abort_transaction: - free(err); - err = xenbus_transaction_end(xbt, 1, &retry); - goto error; - -done: - - snprintf(path, sizeof(path), "%s/backend", nodename); - msg = xenbus_read(XBT_NIL, path, &dev->backend); - if (msg) { - printk("Error %s when reading the backend path %s\n", msg, path); - goto error; - } - - printk("backend at %s\n", dev->backend); - - { - XenbusState state; - char path[strlen(dev->backend) + 1 + 19 + 1]; - snprintf(path, sizeof(path), "%s/state", dev->backend); - - xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); - msg = NULL; - state = xenbus_read_integer(path); - while (msg == NULL && state < XenbusStateConnected) - msg = xenbus_wait_for_state_change(path, &state, &dev->events); - if (msg != NULL || state != XenbusStateConnected) { - printk("backend not available, state=%d\n", state); - xenbus_unwatch_path_token(XBT_NIL, path, path); - goto error; - } - } - unmask_evtchn(dev->evtchn); - - printk("**************************\n"); - - return dev; - -error: - free(msg); - free(err); - free_consfront(dev); - return NULL; -} - void xencons_resume(void) { (void)xencons_ring_init(); diff --git a/extras/mini-os/include/lib.h b/extras/mini-os/include/lib.h index 12070c3..9c69440 100644 --- a/extras/mini-os/include/lib.h +++ b/extras/mini-os/include/lib.h @@ -182,11 +182,13 @@ extern struct file { struct { struct consfront_dev *dev; } cons; +#ifdef CONFIG_XENBUS struct { /* To each xenbus FD is associated a queue of watch events for this * FD. */ xenbus_event_queue events; } xenbus; +#endif }; int read; /* maybe available for read */ } files[]; diff --git a/extras/mini-os/include/xenbus.h b/extras/mini-os/include/xenbus.h index de618fc..cd6316e 100644 --- a/extras/mini-os/include/xenbus.h +++ b/extras/mini-os/include/xenbus.h @@ -6,8 +6,14 @@ typedef unsigned long xenbus_transaction_t; #define XBT_NIL ((xenbus_transaction_t)0) +#ifdef CONFIG_XENBUS /* Initialize the XenBus system. */ void init_xenbus(void); +#else +static inline void init_xenbus(void) +{ +} +#endif /* Read the value associated with a path. Returns a malloc''d error string on failure and sets *value to NULL. On success, *value is @@ -98,7 +104,13 @@ char* xenbus_printf(xenbus_transaction_t xbt, /* Utility function to figure out our domain id */ domid_t xenbus_get_self_id(void); +#ifdef CONFIG_XENBUS /* Reset the XenBus system. */ void fini_xenbus(void); +#else +static inline void fini_xenbus(void) +{ +} +#endif #endif /* XENBUS_H__ */ diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index c8b9b8c..a8dfe6d 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -142,10 +142,6 @@ void stop_kernel(void) /* Reset grant tables */ fini_gnttab(); - /* Reset the console driver. */ - fini_console(NULL); - /* TODO: record new ring mfn & event in start_info */ - /* Reset XenBus */ fini_xenbus(); diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c index b7b3aff..dcdf096 100644 --- a/extras/mini-os/lib/sys.c +++ b/extras/mini-os/lib/sys.c @@ -164,6 +164,7 @@ int mkdir(const char *pathname, mode_t mode) return -1; } +#ifdef CONFIG_CONSFRONT int posix_openpt(int flags) { struct consfront_dev *dev; @@ -192,6 +193,18 @@ int open_savefile(const char *path, int save) printk("fd(%d) = open_savefile\n", dev->fd); return(dev->fd); } +#else +int posix_openpt(int flags) +{ + errno = EIO; + return -1; +} +int open_savefile(const char *path, int save) +{ + errno = EIO; + return -1; +} +#endif int open(const char *pathname, int flags, ...) { @@ -241,6 +254,7 @@ int read(int fd, void *buf, size_t nbytes) case FTYPE_SOCKET: return lwip_read(files[fd].socket.fd, buf, nbytes); #endif +#ifdef CONFIG_NETFRONT case FTYPE_TAP: { ssize_t ret; ret = netfront_receive(files[fd].tap.dev, buf, nbytes); @@ -250,6 +264,8 @@ int read(int fd, void *buf, size_t nbytes) } return ret; } +#endif +#ifdef CONFIG_KBDFRONT case FTYPE_KBD: { int ret, n; n = nbytes / sizeof(union xenkbd_in_event); @@ -260,6 +276,8 @@ int read(int fd, void *buf, size_t nbytes) } return ret * sizeof(union xenkbd_in_event); } +#endif +#ifdef CONFIG_FBFRONT case FTYPE_FB: { int ret, n; n = nbytes / sizeof(union xenfb_in_event); @@ -270,6 +288,7 @@ int read(int fd, void *buf, size_t nbytes) } return ret * sizeof(union xenfb_in_event); } +#endif default: break; } @@ -297,9 +316,11 @@ int write(int fd, const void *buf, size_t nbytes) case FTYPE_SOCKET: return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); #endif +#ifdef CONFIG_NETFRONT case FTYPE_TAP: netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes); return nbytes; +#endif default: break; } @@ -326,9 +347,11 @@ int close(int fd) default: files[fd].type = FTYPE_NONE; return 0; +#ifdef CONFIG_XENBUS case FTYPE_XENBUS: xs_daemon_close((void*)(intptr_t) fd); return 0; +#endif #ifdef HAVE_LWIP case FTYPE_SOCKET: { int res = lwip_close(files[fd].socket.fd); @@ -345,27 +368,37 @@ int close(int fd) case FTYPE_GNTMAP: minios_gnttab_close_fd(fd); return 0; +#ifdef CONFIG_NETFRONT case FTYPE_TAP: shutdown_netfront(files[fd].tap.dev); files[fd].type = FTYPE_NONE; return 0; +#endif +#ifdef CONFIG_BLKFRONT case FTYPE_BLK: shutdown_blkfront(files[fd].blk.dev); files[fd].type = FTYPE_NONE; return 0; +#endif +#ifdef CONFIG_KBDFRONT case FTYPE_KBD: shutdown_kbdfront(files[fd].kbd.dev); files[fd].type = FTYPE_NONE; return 0; +#endif +#ifdef CONFIG_FBFRONT case FTYPE_FB: shutdown_fbfront(files[fd].fb.dev); files[fd].type = FTYPE_NONE; return 0; +#endif +#ifdef CONFIG_CONSFRONT case FTYPE_SAVEFILE: case FTYPE_CONSOLE: fini_console(files[fd].cons.dev); files[fd].type = FTYPE_NONE; return 0; +#endif case FTYPE_NONE: break; } @@ -611,6 +644,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce n++; FD_CLR(i, exceptfds); break; +#ifdef CONFIG_XENBUS case FTYPE_XENBUS: if (FD_ISSET(i, readfds)) { if (files[i].xenbus.events) @@ -621,6 +655,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce FD_CLR(i, writefds); FD_CLR(i, exceptfds); break; +#endif case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: @@ -727,11 +762,19 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, /* Tell people we''re going to sleep before looking at what they are * saying, hence letting them wake us if events happen between here and * schedule() */ +#ifdef CONFIG_NETFRONT add_waiter(w1, netfront_queue); +#endif add_waiter(w2, event_queue); +#ifdef CONFIG_BLKFRONT add_waiter(w3, blkfront_queue); +#endif +#ifdef CONFIG_XENBUS add_waiter(w4, xenbus_watch_queue); +#endif +#ifdef CONFIG_KBDFRONT add_waiter(w5, kbdfront_queue); +#endif add_waiter(w6, console_queue); if (readfds) diff --git a/extras/mini-os/main.c b/extras/mini-os/main.c index aeda548..73eb6fb 100644 --- a/extras/mini-os/main.c +++ b/extras/mini-os/main.c @@ -63,10 +63,12 @@ static void call_main(void *p) #ifdef CONFIG_SPARSE_BSS sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start); #endif -#if defined(HAVE_LWIP) && defined(CONFIG_START_NETWORK) +#if defined(HAVE_LWIP) && defined(CONFIG_START_NETWORK) && defined(CONFIG_NETFRONT) start_networking(); #endif +#ifdef CONFIG_PCIFRONT create_thread("pcifront", pcifront_watches, NULL); +#endif #ifdef CONFIG_QEMU_XS_ARGS /* Fetch argc, argv from XenStore */ @@ -169,7 +171,7 @@ void _exit(int ret) close_all_files(); __libc_fini_array(); printk("main returned %d\n", ret); -#ifdef HAVE_LWIP +#if defined(HAVE_LWIP) && defined(CONFIG_NETFRONT) stop_networking(); #endif stop_kernel(); diff --git a/stubdom/ioemu-minios.cfg b/stubdom/ioemu-minios.cfg index 7ea1d2f..e3a96da 100644 --- a/stubdom/ioemu-minios.cfg +++ b/stubdom/ioemu-minios.cfg @@ -1 +1,2 @@ CONFIG_QEMU_XS_ARGS=y +CONFIG_PCIFRONT=y -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 13/24] mini-os: fix list.h include guard name
The symbol _LINUX_LIST_H collides with other header files. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- extras/mini-os/include/list.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/mini-os/include/list.h b/extras/mini-os/include/list.h index a60ae23..4e6a2ac 100644 --- a/extras/mini-os/include/list.h +++ b/extras/mini-os/include/list.h @@ -1,5 +1,5 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H +#ifndef _MINIOS_LIST_H +#define _MINIOS_LIST_H /* * Simple doubly linked list implementation. @@ -186,5 +186,5 @@ static __inline__ void minios_list_splice(struct minios_list_head *list, struct n = minios_list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = minios_list_entry(n->member.next, typeof(*n), member)) -#endif /* _LINUX_LIST_H */ +#endif /* _MINIOS_LIST_H */ -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 14/24] xenstored: use grant references instead of map_foreign_range
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> make xenstored use grantref rather than map_foreign_range (which can only be used by privileged domains) This patch modifies the xenstore daemon to use xc_gnttab_map_grant_ref instead of xc_map_foreign_range where available. Previous versions of this patch have been sent to xen-devel. See http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01492.html Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/xenstore/xenstored_domain.c | 54 ++++++++++++++++++++++++++++++++---- 1 files changed, 48 insertions(+), 6 deletions(-) diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 443af82..c521e52 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -32,8 +32,10 @@ #include "xenstored_watch.h" #include <xenctrl.h> +#include <xen/grant_table.h> static xc_interface **xc_handle; +static xc_gnttab **xcg_handle; static evtchn_port_t virq_port; xc_evtchn *xce_handle = NULL; @@ -163,6 +165,26 @@ static int readchn(struct connection *conn, void *data, unsigned int len) return len; } +static void *map_interface(domid_t domid, unsigned long mfn) +{ + if (*xcg_handle >= 0) { + /* this is the preferred method */ + return xc_gnttab_map_grant_ref(*xcg_handle, domid, + GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); + } else { + return xc_map_foreign_range(*xc_handle, domid, + getpagesize(), PROT_READ|PROT_WRITE, mfn); + } +} + +static void unmap_interface(void *interface) +{ + if (*xcg_handle >= 0) + xc_gnttab_munmap(*xcg_handle, interface, 1); + else + munmap(interface, getpagesize()); +} + static int destroy_domain(void *_domain) { struct domain *domain = _domain; @@ -174,8 +196,14 @@ static int destroy_domain(void *_domain) eprintf("> Unbinding port %i failed!\n", domain->port); } - if (domain->interface) - munmap(domain->interface, getpagesize()); + if (domain->interface) { + /* Domain 0 was mapped by dom0_init, so it must be unmapped + using munmap() and not the grant unmap call. */ + if (domain->domid == 0) + munmap(domain->interface, getpagesize()); + else + unmap_interface(domain->interface); + } fire_watches(NULL, "@releaseDomain", false); @@ -344,9 +372,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) domain = find_domain_by_domid(domid); if (domain == NULL) { - interface = xc_map_foreign_range( - *xc_handle, domid, - getpagesize(), PROT_READ|PROT_WRITE, mfn); + interface = map_interface(domid, mfn); if (!interface) { send_error(conn, errno); return; @@ -354,7 +380,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) /* Hang domain off "in" until we''re finished. */ domain = new_domain(in, domid, port); if (!domain) { - munmap(interface, getpagesize()); + unmap_interface(interface); send_error(conn, errno); return; } @@ -552,6 +578,12 @@ static int close_xc_handle(void *_handle) return 0; } +static int close_xcg_handle(void *_handle) +{ + xc_gnttab_close(*(xc_gnttab **)_handle); + return 0; +} + /* Returns the implicit path of a connection (only domains have this) */ const char *get_implicit_path(const struct connection *conn) { @@ -603,6 +635,16 @@ void domain_init(void) talloc_set_destructor(xc_handle, close_xc_handle); + xcg_handle = talloc(talloc_autofree_context(), xc_gnttab*); + if (!xcg_handle) + barf_perror("Failed to allocate domain gnttab handle"); + + *xcg_handle = xc_gnttab_open(NULL, 0); + if (*xcg_handle < 0) + xprintf("WARNING: Failed to open connection to gnttab\n"); + else + talloc_set_destructor(xcg_handle, close_xcg_handle); + xce_handle = xc_evtchn_open(NULL, 0); if (xce_handle == NULL) -- 1.7.7.6
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/xenstore/xenstored_core.c | 85 +++++++++++++++++++++------------------ 1 files changed, 46 insertions(+), 39 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 9e6c2c7..0e7d43f 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -343,13 +343,6 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, return max; } -static int destroy_fd(void *_fd) -{ - int *fd = _fd; - close(*fd); - return 0; -} - /* Is child a subnode of parent, or equal? */ bool is_child(const char *child, const char *parent) { @@ -1705,6 +1698,51 @@ static void daemonize(void) umask(0); } +static int destroy_fd(void *_fd) +{ + int *fd = _fd; + close(*fd); + return 0; +} + +static void init_sockets(int **psock, int **pro_sock) +{ + struct sockaddr_un addr; + int *sock, *ro_sock; + /* Create sockets for them to listen to. */ + *psock = sock = talloc(talloc_autofree_context(), int); + *sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (*sock < 0) + barf_perror("Could not create socket"); + *pro_sock = ro_sock = talloc(talloc_autofree_context(), int); + *ro_sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (*ro_sock < 0) + barf_perror("Could not create socket"); + talloc_set_destructor(sock, destroy_fd); + talloc_set_destructor(ro_sock, destroy_fd); + + /* FIXME: Be more sophisticated, don''t mug running daemon. */ + unlink(xs_daemon_socket()); + unlink(xs_daemon_socket_ro()); + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, xs_daemon_socket()); + if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) + barf_perror("Could not bind socket to %s", xs_daemon_socket()); + strcpy(addr.sun_path, xs_daemon_socket_ro()); + if (bind(*ro_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) + barf_perror("Could not bind socket to %s", + xs_daemon_socket_ro()); + if (chmod(xs_daemon_socket(), 0600) != 0 + || chmod(xs_daemon_socket_ro(), 0660) != 0) + barf_perror("Could not chmod sockets"); + + if (listen(*sock, 1) != 0 + || listen(*ro_sock, 1) != 0) + barf_perror("Could not listen on sockets"); + + +} static void usage(void) { @@ -1753,7 +1791,6 @@ extern void dump_conn(struct connection *conn); int main(int argc, char *argv[]) { int opt, *sock, *ro_sock, max; - struct sockaddr_un addr; fd_set inset, outset; bool dofork = true; bool outputpid = false; @@ -1837,40 +1874,10 @@ int main(int argc, char *argv[]) if (!dofork) talloc_enable_leak_report_full(); - /* Create sockets for them to listen to. */ - sock = talloc(talloc_autofree_context(), int); - *sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (*sock < 0) - barf_perror("Could not create socket"); - ro_sock = talloc(talloc_autofree_context(), int); - *ro_sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (*ro_sock < 0) - barf_perror("Could not create socket"); - talloc_set_destructor(sock, destroy_fd); - talloc_set_destructor(ro_sock, destroy_fd); - /* Don''t kill us with SIGPIPE. */ signal(SIGPIPE, SIG_IGN); - /* FIXME: Be more sophisticated, don''t mug running daemon. */ - unlink(xs_daemon_socket()); - unlink(xs_daemon_socket_ro()); - - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, xs_daemon_socket()); - if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) - barf_perror("Could not bind socket to %s", xs_daemon_socket()); - strcpy(addr.sun_path, xs_daemon_socket_ro()); - if (bind(*ro_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) - barf_perror("Could not bind socket to %s", - xs_daemon_socket_ro()); - if (chmod(xs_daemon_socket(), 0600) != 0 - || chmod(xs_daemon_socket_ro(), 0660) != 0) - barf_perror("Could not chmod sockets"); - - if (listen(*sock, 1) != 0 - || listen(*ro_sock, 1) != 0) - barf_perror("Could not listen on sockets"); + init_sockets(&sock, &ro_sock); if (pipe(reopen_log_pipe)) { barf_perror("pipe"); -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 16/24] xenstored: add NO_SOCKETS compilation option
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Add option for compiling xenstored without unix sockets to support running on mini-OS Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/xenstore/xenstored_core.c | 28 +++++++++++++++++++++++----- 1 files changed, 23 insertions(+), 5 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 0e7d43f..c1ee932 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -19,9 +19,11 @@ #include <sys/types.h> #include <sys/stat.h> -#include <sys/socket.h> #include <sys/select.h> +#ifndef NO_SOCKETS +#include <sys/socket.h> #include <sys/un.h> +#endif #include <sys/time.h> #include <time.h> #include <unistd.h> @@ -320,8 +322,10 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, FD_ZERO(inset); FD_ZERO(outset); - set_fd(sock, inset, &max); - set_fd(ro_sock, inset, &max); + if (sock != -1) + set_fd(sock, inset, &max); + if (ro_sock != -1) + set_fd(ro_sock, inset, &max); set_fd(reopen_log_pipe[0], inset, &max); if (xce_handle != NULL) @@ -1345,6 +1349,11 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read) return new; } +#ifdef NO_SOCKETS +static void accept_connection(int sock, bool canwrite) +{ +} +#else static int writefd(struct connection *conn, const void *data, unsigned int len) { int rc; @@ -1399,6 +1408,7 @@ static void accept_connection(int sock, bool canwrite) } else close(fd); } +#endif #define TDB_FLAGS 0 @@ -1698,6 +1708,13 @@ static void daemonize(void) umask(0); } +#ifdef NO_SOCKETS +static void init_sockets(int **psock, int **pro_sock) +{ + static int minus_one = -1; + *psock = *pro_sock = &minus_one; +} +#else static int destroy_fd(void *_fd) { int *fd = _fd; @@ -1743,6 +1760,7 @@ static void init_sockets(int **psock, int **pro_sock) } +#endif static void usage(void) { @@ -1938,10 +1956,10 @@ int main(int argc, char *argv[]) reopen_log(); } - if (FD_ISSET(*sock, &inset)) + if (*sock != -1 && FD_ISSET(*sock, &inset)) accept_connection(*sock, true); - if (FD_ISSET(*ro_sock, &inset)) + if (*ro_sock != -1 && FD_ISSET(*ro_sock, &inset)) accept_connection(*ro_sock, false); if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset)) -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 17/24] xenstored: support for tdb_copy with TDB_INTERNAL
From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> The tdb_copy function should honor the TDB_INTERNAL flag for in-memory databases; this is required to run in mini-os which does not use a filesystem. Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/xenstore/tdb.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/tools/xenstore/tdb.c b/tools/xenstore/tdb.c index 63205e1..3ecd3fc 100644 --- a/tools/xenstore/tdb.c +++ b/tools/xenstore/tdb.c @@ -2103,6 +2103,41 @@ TDB_CONTEXT *tdb_copy(TDB_CONTEXT *tdb, const char *outfile) int fd, saved_errno; TDB_CONTEXT *copy; + if (tdb->flags & TDB_INTERNAL) { + struct tdb_header *copydb; + + copy = talloc_zero(outfile, TDB_CONTEXT); + if (copy == NULL) { + errno = ENOMEM; + goto intfail; + } + memcpy(copy, tdb, sizeof(TDB_CONTEXT)); + + if (copy->name || copy->locked || copy->device || copy->inode) { + fprintf(stderr, "tdb_copy assumption(s) failed\n"); + goto intfail; + } + + copydb = talloc_zero_size(copy, copy->map_size); + if (copydb == NULL) { + errno = ENOMEM; + goto intfail; + } + memcpy(copydb, copy->map_ptr, copy->map_size); + copy->map_ptr = (char*) copydb; + + if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) + goto intfail; + + copy->next = tdbs; + tdbs = copy; + + return copy; +intfail: + talloc_free(copy); + return NULL; + } + fd = open(outfile, O_TRUNC|O_CREAT|O_WRONLY, 0640); if (fd < 0) return NULL; -- 1.7.7.6
--- tools/xenstore/xenstored_core.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index c1ee932..4b12cf2 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -63,7 +63,7 @@ static bool recovery = true; static bool remove_local = true; static int reopen_log_pipe[2]; static char *tracefile = NULL; -static TDB_CONTEXT *tdb_ctx; +static TDB_CONTEXT *tdb_ctx = NULL; static void corrupt(struct connection *conn, const char *fmt, ...); static void check_store(void); @@ -92,8 +92,9 @@ TDB_CONTEXT *tdb_context(struct connection *conn) bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb) { - if (rename(newname, xs_daemon_tdb()) != 0) - return false; + if (!(tdb_ctx->flags & TDB_INTERNAL)) + if (rename(newname, xs_daemon_tdb()) != 0) + return false; tdb_close(tdb_ctx); tdb_ctx = talloc_steal(talloc_autofree_context(), newtdb); return true; @@ -1410,7 +1411,7 @@ static void accept_connection(int sock, bool canwrite) } #endif -#define TDB_FLAGS 0 +static int tdb_flags; /* We create initial nodes manually. */ static void manual_node(const char *name, const char *child) @@ -1435,7 +1436,9 @@ static void setup_structure(void) { char *tdbname; tdbname = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb()); - tdb_ctx = tdb_open(tdbname, 0, TDB_FLAGS, O_RDWR, 0); + + if (!(tdb_flags & TDB_INTERNAL)) + tdb_ctx = tdb_open(tdbname, 0, tdb_flags, O_RDWR, 0); if (tdb_ctx) { /* XXX When we make xenstored able to restart, this will have @@ -1466,7 +1469,7 @@ static void setup_structure(void) talloc_free(tlocal); } else { - tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT, + tdb_ctx = tdb_open(tdbname, 7919, tdb_flags, O_RDWR|O_CREAT, 0640); if (!tdb_ctx) barf_perror("Could not create tdb file %s", tdbname); @@ -1783,6 +1786,7 @@ static void usage(void) " --transaction <nb> limit the number of transaction allowed per domain,\n" " --no-recovery to request that no recovery should be attempted when\n" " the store is corrupted (debug only),\n" +" --internal-db store database in memory, not on disk\n" " --preserve-local to request that /local is preserved on start-up,\n" " --verbose to request verbose execution.\n"); } @@ -1800,6 +1804,7 @@ static struct option options[] = { { "transaction", 1, NULL, ''t'' }, { "no-recovery", 0, NULL, ''R'' }, { "preserve-local", 0, NULL, ''L'' }, + { "internal-db", 0, NULL, ''I'' }, { "verbose", 0, NULL, ''V'' }, { "watch-nb", 1, NULL, ''W'' }, { NULL, 0, NULL, 0 } }; @@ -1853,6 +1858,9 @@ int main(int argc, char *argv[]) case ''T'': tracefile = optarg; break; + case ''I'': + tdb_flags = TDB_INTERNAL|TDB_NOLOCK; + break; case ''V'': verbose = true; break; -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 19/24] xenstored: support running in minios stubdom
A previous versions of this patch has been sent to xen-devel. See http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01655.html Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/xenstore/Makefile | 9 ++++- tools/xenstore/utils.h | 2 + tools/xenstore/xenstored_core.c | 74 +++++++++++++++++++++++------------- tools/xenstore/xenstored_domain.c | 11 +++++ 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 4facb62..be892fd 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -28,6 +28,10 @@ endif ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored +ifdef CONFIG_STUBDOM +CFLAGS += -DNO_SOCKETS=1 +endif + .PHONY: all all: $(ALL_TARGETS) @@ -45,10 +49,13 @@ xenstored_probes.o: xenstored_solaris.o CFLAGS += -DHAVE_DTRACE=1 endif - + xenstored: $(XENSTORED_OBJS) $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) +xenstored.a: $(XENSTORED_OBJS) + $(AR) cr $@ $^ + $(CLIENTS): xenstore ln -f xenstore $@ diff --git a/tools/xenstore/utils.h b/tools/xenstore/utils.h index f378343..2effd17 100644 --- a/tools/xenstore/utils.h +++ b/tools/xenstore/utils.h @@ -19,7 +19,9 @@ static inline bool strends(const char *a, const char *b) return streq(a + strlen(a) - strlen(b), b); } +#ifndef ARRAY_SIZE #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif void barf(const char *fmt, ...) __attribute__((noreturn)); void barf_perror(const char *fmt, ...) __attribute__((noreturn)); diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 4b12cf2..0b9d4f2 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -224,7 +224,6 @@ static void reopen_log(void) } } - static bool write_messages(struct connection *conn) { int ret; @@ -327,7 +326,8 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, set_fd(sock, inset, &max); if (ro_sock != -1) set_fd(ro_sock, inset, &max); - set_fd(reopen_log_pipe[0], inset, &max); + if (reopen_log_pipe[0] != -1) + set_fd(reopen_log_pipe[0], inset, &max); if (xce_handle != NULL) set_fd(xc_evtchn_fd(xce_handle), inset, &max); @@ -1664,6 +1664,19 @@ static void corrupt(struct connection *conn, const char *fmt, ...) } +#ifdef __MINIOS__ +static void write_pidfile(const char *pidfile) +{ +} + +static void daemonize(void) +{ +} + +static void finish_daemonize(void) +{ +} +#else static void write_pidfile(const char *pidfile) { char buf[100]; @@ -1711,6 +1724,19 @@ static void daemonize(void) umask(0); } +static void finish_daemonize(void) +{ + int devnull = open("/dev/null", O_RDWR); + if (devnull == -1) + barf_perror("Could not open /dev/null\n"); + dup2(devnull, STDIN_FILENO); + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + xprintf = trace; +} +#endif + #ifdef NO_SOCKETS static void init_sockets(int **psock, int **pro_sock) { @@ -1822,6 +1848,11 @@ int main(int argc, char *argv[]) int evtchn_fd = -1; struct timeval *timeout; +#ifdef __MINIOS__ + /* minios always uses internal DB */ + tdb_flags = TDB_INTERNAL|TDB_NOLOCK; +#endif + while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, NULL)) != -1) { switch (opt) { @@ -1874,20 +1905,10 @@ int main(int argc, char *argv[]) reopen_log(); - /* make sure xenstored directory exists */ - if (mkdir(xs_daemon_rundir(), 0755)) { - if (errno != EEXIST) { - perror("error: mkdir daemon rundir"); - exit(-1); - } - } - - if (mkdir(xs_daemon_rootdir(), 0755)) { - if (errno != EEXIST) { - perror("error: mkdir daemon rootdir"); - exit(-1); - } - } + /* make sure xenstored directories exist */ + /* Errors ignored here, will be reported when we open files */ + mkdir(xs_daemon_rundir(), 0755); + mkdir(xs_daemon_rootdir(), 0755); if (dofork) { openlog("xenstored", 0, LOG_DAEMON); @@ -1905,9 +1926,14 @@ int main(int argc, char *argv[]) init_sockets(&sock, &ro_sock); +#ifdef __MINIOS__ + reopen_log_pipe[0] = -1; + reopen_log_pipe[1] = -1; +#else if (pipe(reopen_log_pipe)) { barf_perror("pipe"); } +#endif /* Setup the database */ setup_structure(); @@ -1925,16 +1951,8 @@ int main(int argc, char *argv[]) } /* redirect to /dev/null now we''re ready to accept connections */ - if (dofork) { - int devnull = open("/dev/null", O_RDWR); - if (devnull == -1) - barf_perror("Could not open /dev/null\n"); - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - close(devnull); - xprintf = trace; - } + if (dofork) + finish_daemonize(); signal(SIGHUP, trigger_reopen_log); @@ -1944,8 +1962,10 @@ int main(int argc, char *argv[]) /* Get ready to listen to the tools. */ max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout); +#ifndef __MINIOS__ /* Tell the kernel we''re up and running. */ xenbus_notify_running(); +#endif /* Main loop. */ for (;;) { @@ -1957,7 +1977,7 @@ int main(int argc, char *argv[]) barf_perror("Select failed"); } - if (FD_ISSET(reopen_log_pipe[0], &inset)) { + if (reopen_log_pipe[0] != -1 && FD_ISSET(reopen_log_pipe[0], &inset)) { char c; if (read(reopen_log_pipe[0], &c, 1) != 1) barf_perror("read failed"); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index c521e52..4243f91 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -197,12 +197,16 @@ static int destroy_domain(void *_domain) } if (domain->interface) { +#ifdef __MINIOS__ + unmap_interface(domain->interface); +#else /* Domain 0 was mapped by dom0_init, so it must be unmapped using munmap() and not the grant unmap call. */ if (domain->domid == 0) munmap(domain->interface, getpagesize()); else unmap_interface(domain->interface); +#endif } fire_watches(NULL, "@releaseDomain", false); @@ -597,6 +601,12 @@ void restore_existing_connections(void) { } +#ifdef __MINIOS__ +static int dom0_init(void) +{ + return 0; +} +#else static int dom0_init(void) { evtchn_port_t port; @@ -620,6 +630,7 @@ static int dom0_init(void) return 0; } +#endif void domain_init(void) { -- 1.7.7.6
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- stubdom/Makefile | 29 ++++++++++++++++++++++++++--- stubdom/xenstore-minios.cfg | 9 +++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 stubdom/xenstore-minios.cfg diff --git a/stubdom/Makefile b/stubdom/Makefile index d4da2bb..5c02464 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -74,14 +74,14 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib -TARGETS=ioemu c caml grub +TARGETS=ioemu c caml grub xenstore CROSS_MAKE := $(MAKE) DESTDIR .PHONY: all all: build ifeq ($(STUBDOM_SUPPORTED),1) -build: genpath ioemu-stubdom c-stubdom pv-grub +build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom else build: genpath endif @@ -262,6 +262,11 @@ mk-headers-$(XEN_TARGET_ARCH): ioemu/linkfarm.stamp ln -sf $(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \ ln -sf $(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \ ln -sf $(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/Makefile . ) + mkdir -p xenstore + [ -h xenstore/Makefile ] || ( cd xenstore && \ + ln -sf $(XEN_ROOT)/tools/xenstore/*.c . && \ + ln -sf $(XEN_ROOT)/tools/xenstore/*.h . && \ + ln -sf $(XEN_ROOT)/tools/xenstore/Makefile . ) $(CROSS_MAKE) -C $(MINI_OS) links touch mk-headers-$(XEN_TARGET_ARCH) @@ -334,6 +339,14 @@ grub: grub-upstream $(CROSS_ROOT) mkdir -p grub-$(XEN_TARGET_ARCH) CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(CROSS_MAKE) -C $@ OBJ_DIR=$(CURDIR)/grub-$(XEN_TARGET_ARCH) +########## +# xenstore +########## + +.PHONY: xenstore +xenstore: $(CROSS_ROOT) + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(CROSS_MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip xenstored.a CONFIG_STUBDOM=y + ######## # minios ######## @@ -355,12 +368,16 @@ c-stubdom: mini-os-$(XEN_TARGET_ARCH)-c lwip-$(XEN_TARGET_ARCH) libxc c pv-grub: mini-os-$(XEN_TARGET_ARCH)-grub libxc grub DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/grub/minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub-$(XEN_TARGET_ARCH)/main.a +.PHONY: xenstore-stubdom +xenstore-stubdom: mini-os-$(XEN_TARGET_ARCH)-xenstore libxc xenstore + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/xenstore-minios.cfg" $(CROSS_MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS=$(CURDIR)/xenstore/xenstored.a + ######### # install ######### ifeq ($(STUBDOM_SUPPORTED),1) -install: genpath install-readme install-ioemu install-grub +install: genpath install-readme install-ioemu install-grub install-xenstore else install: genpath endif @@ -379,6 +396,10 @@ install-grub: pv-grub $(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)" $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz" +install-xenstore: xenstore-stubdom + $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot" + $(INSTALL_PROG) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz" + ####### # clean ####### @@ -390,12 +411,14 @@ clean: rm -fr mini-os-$(XEN_TARGET_ARCH)-c rm -fr mini-os-$(XEN_TARGET_ARCH)-caml rm -fr mini-os-$(XEN_TARGET_ARCH)-grub + rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstore $(CROSS_MAKE) -C caml clean $(CROSS_MAKE) -C c clean rm -fr grub-$(XEN_TARGET_ARCH) rm -f $(STUBDOMPATH) [ ! -d libxc-$(XEN_TARGET_ARCH) ] || $(CROSS_MAKE) -C libxc-$(XEN_TARGET_ARCH) clean -[ ! -d ioemu ] || $(CROSS_MAKE) -C ioemu clean + -[ ! -d xenstore ] || $(CROSS_MAKE) -C xenstore clean # clean the cross-compilation result .PHONY: crossclean diff --git a/stubdom/xenstore-minios.cfg b/stubdom/xenstore-minios.cfg new file mode 100644 index 0000000..ab7338f --- /dev/null +++ b/stubdom/xenstore-minios.cfg @@ -0,0 +1,9 @@ +CONFIG_BLKFRONT=n +CONFIG_NETFRONT=n +CONFIG_FBFRONT=n +CONFIG_KBDFRONT=n +CONFIG_CONSFRONT=n +CONFIG_XENBUS=n + +lwip=n +DEF_CPPFLAGS := $(filter-out -DHAVE_LWIP,$(DEF_CPPFLAGS)) -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 21/24] xenstored: add --event parameter for bootstrapping
When xenstored is run in a minios domain, it needs a bootstrap connection to dom0 so that additional domain introduce messages can be sent to it. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/xenstore/xenstored_core.c | 5 +++++ tools/xenstore/xenstored_core.h | 1 + tools/xenstore/xenstored_domain.c | 11 +++++++++++ 3 files changed, 17 insertions(+), 0 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 0b9d4f2..89b3422 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1822,6 +1822,7 @@ static struct option options[] = { { "no-domain-init", 0, NULL, ''D'' }, { "entry-nb", 1, NULL, ''E'' }, { "pid-file", 1, NULL, ''F'' }, + { "event", 1, NULL, ''e'' }, { "help", 0, NULL, ''H'' }, { "no-fork", 0, NULL, ''N'' }, { "output-pid", 0, NULL, ''P'' }, @@ -1836,6 +1837,7 @@ static struct option options[] = { { NULL, 0, NULL, 0 } }; extern void dump_conn(struct connection *conn); +int dom0_event = 0; int main(int argc, char *argv[]) { @@ -1898,6 +1900,9 @@ int main(int argc, char *argv[]) case ''W'': quota_nb_watch_per_domain = strtol(optarg, NULL, 10); break; + case ''e'': + dom0_event = strtol(optarg, NULL, 10); + break; } } if (optind != argc) diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index c487089..d3040ba 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -168,6 +168,7 @@ void trace(const char *fmt, ...); void dtrace_io(const struct connection *conn, const struct buffered_data *data, int out); extern int event_fd; +extern int dom0_event; /* Map the kernel''s xenstore page. */ void *xenbus_map(void); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 4243f91..f525d65 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -604,6 +604,17 @@ void restore_existing_connections(void) #ifdef __MINIOS__ static int dom0_init(void) { + struct domain *domain; + int domid = 0; + evtchn_port_t port = dom0_event; + + domain = new_domain(NULL, domid, port); + domain->interface = xc_gnttab_map_grant_ref(*xcg_handle, domid, + GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); + talloc_steal(domain->conn, domain); + + xc_evtchn_notify(xce_handle, domain->port); + return 0; } #else -- 1.7.7.6
Daniel De Graaf
2012-Jan-26 19:45 UTC
[PATCH 22/24] xenstored: use domain_is_unprivileged instead of checking conn->id
This centralizes all the permission checking for privileged domains in preparation for allowing domains other than dom0 to be privileged. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/xenstore/xenstored_core.c | 6 +++--- tools/xenstore/xenstored_domain.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 89b3422..f254947 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -462,7 +462,7 @@ static enum xs_perm_type perm_for_conn(struct connection *conn, mask &= ~XS_PERM_WRITE; /* Owners and tools get it all... */ - if (!conn->id || perms[0].id == conn->id + if (!domain_is_unprivileged(conn) || perms[0].id == conn->id || (conn->target && perms[0].id == conn->target->id)) return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask; @@ -800,11 +800,11 @@ static struct node *construct_node(struct connection *conn, const char *name) node->tdb = tdb_context(conn); node->name = talloc_strdup(node, name); - /* Inherit permissions, except domains own what they create */ + /* Inherit permissions, except unprivileged domains own what they create */ node->num_perms = parent->num_perms; node->perms = talloc_memdup(node, parent->perms, node->num_perms * sizeof(node->perms[0])); - if (conn && conn->id) + if (domain_is_unprivileged(conn)) node->perms[0].id = conn->id; /* No children, no data */ diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index f525d65..22fe126b 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -358,7 +358,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) return; } - if (conn->id != 0 || !conn->can_write) { + if (domain_is_unprivileged(conn) || !conn->can_write) { send_error(conn, EACCES); return; } @@ -422,7 +422,7 @@ void do_set_target(struct connection *conn, struct buffered_data *in) return; } - if (conn->id != 0 || !conn->can_write) { + if (domain_is_unprivileged(conn) || !conn->can_write) { send_error(conn, EACCES); return; } @@ -474,7 +474,7 @@ void do_release(struct connection *conn, const char *domid_str) return; } - if (conn->id != 0) { + if (domain_is_unprivileged(conn)) { send_error(conn, EACCES); return; } @@ -511,7 +511,7 @@ void do_resume(struct connection *conn, const char *domid_str) return; } - if (conn->id != 0) { + if (domain_is_unprivileged(conn)) { send_error(conn, EACCES); return; } -- 1.7.7.6
This parameter identifies an alternative service domain which has superuser access to the xenstore database, which is currently required to set up a new domain''s xenstore entries. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/xenstore/xenstored_core.c | 5 +++++ tools/xenstore/xenstored_core.h | 1 + tools/xenstore/xenstored_domain.c | 2 +- 3 files changed, 7 insertions(+), 1 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index f254947..2894f1b 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1825,6 +1825,7 @@ static struct option options[] = { { "event", 1, NULL, ''e'' }, { "help", 0, NULL, ''H'' }, { "no-fork", 0, NULL, ''N'' }, + { "priv-domid", 1, NULL, ''p'' }, { "output-pid", 0, NULL, ''P'' }, { "entry-size", 1, NULL, ''S'' }, { "trace-file", 1, NULL, ''T'' }, @@ -1838,6 +1839,7 @@ static struct option options[] = { extern void dump_conn(struct connection *conn); int dom0_event = 0; +int priv_domid = 0; int main(int argc, char *argv[]) { @@ -1903,6 +1905,9 @@ int main(int argc, char *argv[]) case ''e'': dom0_event = strtol(optarg, NULL, 10); break; + case ''p'': + priv_domid = strtol(optarg, NULL, 10); + break; } } if (optind != argc) diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index d3040ba..03e2e48 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -169,6 +169,7 @@ void dtrace_io(const struct connection *conn, const struct buffered_data *data, extern int event_fd; extern int dom0_event; +extern int priv_domid; /* Map the kernel''s xenstore page. */ void *xenbus_map(void); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 22fe126b..151e088 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -263,7 +263,7 @@ bool domain_can_read(struct connection *conn) bool domain_is_unprivileged(struct connection *conn) { - return (conn && conn->domain && conn->domain->domid != 0); + return (conn && conn->domain && conn->domain->domid != 0 && conn->domain->domid != priv_domid); } bool domain_can_write(struct connection *conn) -- 1.7.7.6
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- tools/include/xen-sys/Linux/xenbus_dev.h | 44 ++++++++++++++ tools/xenstore/Makefile | 9 ++- tools/xenstore/init-xenstore-domain.c | 94 ++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 tools/include/xen-sys/Linux/xenbus_dev.h create mode 100644 tools/xenstore/init-xenstore-domain.c diff --git a/tools/include/xen-sys/Linux/xenbus_dev.h b/tools/include/xen-sys/Linux/xenbus_dev.h new file mode 100644 index 0000000..bbee8c6 --- /dev/null +++ b/tools/include/xen-sys/Linux/xenbus_dev.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * evtchn.h + * + * Interface to /dev/xen/xenbus_backend. + * + * Copyright (c) 2011 Bastian Blank <waldi@debian.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __LINUX_XEN_XENBUS_DEV_H__ +#define __LINUX_XEN_XENBUS_DEV_H__ + +#include <linux/ioctl.h> + +#define IOCTL_XENBUS_BACKEND_EVTCHN \ + _IOC(_IOC_NONE, ''B'', 0, 0) + +#define IOCTL_XENBUS_BACKEND_SETUP \ + _IOC(_IOC_NONE, ''B'', 1, 0) + +#endif /* __LINUX_XEN_XENBUS_DEV_H__ */ diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index be892fd..2fce994 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -26,7 +26,7 @@ LIBXENSTORE := libxenstore.a xenstore xenstore-control: CFLAGS += -static endif -ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored +ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored init-xenstore-domain ifdef CONFIG_STUBDOM CFLAGS += -DNO_SOCKETS=1 @@ -50,6 +50,11 @@ xenstored_probes.o: xenstored_solaris.o CFLAGS += -DHAVE_DTRACE=1 endif +init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest) + +init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE) + $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS) + xenstored: $(XENSTORED_OBJS) $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) @@ -85,7 +90,7 @@ libxenstore.a: xs.o xs_lib.o clean: rm -f *.a *.o *.opic *.so* xenstored_probes.h rm -f xenstored xs_random xs_stress xs_crashme - rm -f xs_tdb_dump xenstore-control + rm -f xs_tdb_dump xenstore-control init-xenstore-domain rm -f xenstore $(CLIENTS) $(RM) $(DEPS) diff --git a/tools/xenstore/init-xenstore-domain.c b/tools/xenstore/init-xenstore-domain.c new file mode 100644 index 0000000..f6c31d0 --- /dev/null +++ b/tools/xenstore/init-xenstore-domain.c @@ -0,0 +1,94 @@ +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <xenctrl.h> +#include <xc_dom.h> +#include <xs.h> +#include <xen/sys/xenbus_dev.h> + +static uint32_t domid = -1; + +static int build(xc_interface *xch, char** argv) +{ + char cmdline[512]; + uint32_t ssid; + xen_domain_handle_t handle = { 0 }; + int rv; + int xs_fd = open("/dev/xen/xenbus_backend", O_RDWR); + struct xc_dom_image *dom; + int maxmem = atoi(argv[2]); + int limit_kb = (maxmem + 1)*1024; + + rv = xc_flask_context_to_sid(xch, argv[3], strlen(argv[3]), &ssid); + if (rv) return rv; + rv = xc_domain_create(xch, ssid, handle, 0, &domid); + if (rv) return rv; + rv = xc_domain_max_vcpus(xch, domid, 1); + if (rv) return rv; + rv = xc_domain_setmaxmem(xch, domid, limit_kb); + if (rv) return rv; + rv = xc_domain_set_memmap_limit(xch, domid, limit_kb); + if (rv) return rv; + + rv = ioctl(xs_fd, IOCTL_XENBUS_BACKEND_SETUP, domid); + if (rv < 0) return rv; + snprintf(cmdline, 512, "--event %d", rv); + + dom = xc_dom_allocate(xch, cmdline, NULL); + rv = xc_dom_kernel_file(dom, argv[1]); + if (rv) return rv; + rv = xc_dom_boot_xen_init(dom, xch, domid); + if (rv) return rv; + rv = xc_dom_parse_image(dom); + if (rv) return rv; + rv = xc_dom_mem_init(dom, maxmem); + if (rv) return rv; + rv = xc_dom_boot_mem_init(dom); + if (rv) return rv; + rv = xc_dom_build_image(dom); + if (rv) return rv; + rv = xc_dom_boot_image(dom); + if (rv) return rv; + + xc_dom_release(dom); + + rv = xc_domain_set_virq_handler(xch, domid, VIRQ_DOM_EXC); + if (rv) return rv; + rv = xc_domain_unpause(xch, domid); + if (rv) return rv; + + return 0; +} + +int main(int argc, char** argv) +{ + xc_interface *xch; + struct xs_handle *xsh; + char buf[16]; + int rv; + + if (argc != 4) { + printf("Use: %s <xenstore-kernel> <memory_mb> <flask-label>\n", argv[0]); + return 2; + } + + xch = xc_interface_open(NULL, NULL, 0); + if (!xch) return 1; + + rv = build(xch, argv); + + xc_interface_close(xch); + + if (rv) return 1; + + xsh = xs_open(0); + rv = snprintf(buf, 16, "%d", domid); + xs_write(xsh, XBT_NULL, "/tool/xenstored/domid", buf, rv); + xs_daemon_close(xsh); + + return 0; +} -- 1.7.7.6
Ian Campbell
2012-Jan-27 09:54 UTC
Re: [PATCH 05/24] xen: Preserve reserved grant entries when switching versions
It would be worth CCing the relevant maintainers for each patch in the series. e.g. Keir in this case. On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote:> In order for the toolstack to use reserved grant table entries, the > grant table for a guest must be initialized prior to the guest''s boot. > When the guest switches grant table versions (necessary if the guest is > using v2 grant tables, or on kexec if switching grant versions), these > initial grants will be cleared. Instead of clearing them, preserve > the grants across the type change. > > Attempting to preserve v2-only features such as sub-page grants will > produce a warning and invalidate the resulting v1 grant entry. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> > --- > xen/common/grant_table.c | 48 +++++++++++++++++++++++++++++++++---- > xen/include/public/grant_table.h | 7 +++++ > 2 files changed, 49 insertions(+), 6 deletions(-) > > diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c > index 0c55fd1..6f24a94 100644 > --- a/xen/common/grant_table.c > +++ b/xen/common/grant_table.c > @@ -2111,6 +2111,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) > struct domain *d = current->domain; > struct grant_table *gt = d->grant_table; > struct active_grant_entry *act; > + grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES]; > long res; > int i; > > @@ -2131,7 +2132,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) > /* (You need to change the version number for e.g. kexec.) */ > if ( gt->gt_version != 0 ) > { > - for ( i = 0; i < nr_grant_entries(gt); i++ ) > + for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ )The comment just prior says: /* Make sure that the grant table isn''t currently in use when we change the version number. */ I think this needs updating to note that we do allow reserved entries to be active during the switch over and we will correctly preserve flags/status/mapped-ness etc.> { > act = &active_entry(gt, i); > if ( act->pin != 0 ) > @@ -2156,15 +2157,50 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) > goto out_unlock; > } > > + /* Preserve the first 8 entries (toolstack reserved grants) */ > + if (gt->gt_version == 1)Xen coding style has extra spaces just inside the braces (and again below a few more times).> + { > + memcpy(reserved_entries, gt->shared_v1[0], sizeof(reserved_entries));Shouldn''t that be either "gt->shared_v1" or ">->shared_v1[0]" ?> + } > + else if (gt->gt_version == 2) > + { > + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES && i < nr_grant_entries(gt); i++ ) > + { > + reserved_entries[i].flags = shared_entry_v2(gt, i).hdr.flags; > + reserved_entries[i].domid = shared_entry_v2(gt, i).hdr.domid; > + reserved_entries[i].frame = shared_entry_v2(gt, i).full_page.frame; > + reserved_entries[i].flags |= status_entry(gt, i); > + if ((reserved_entries[i].flags & GTF_type_mask) > GTF_permit_access)In effect this only allows GTF_permit_access or GTF_invalid, which is good. It would be more obvious/explicit to do if ((shared_entry_v2(gt, i).hdr.flags & GTF_type_mask) != GTF_invalid && (shared_entry_v2(gt, i).hdr.flags & GTF_type_mask) != GTF_permit_access) memset-whole-entry and continue; at the top or even a switch().> + { > + gdprintk(XENLOG_INFO, "d%d: bad flags %x in grant %d when switching grant version\n", > + d->domain_id, reserved_entries[i].flags, i); > + reserved_entries[i].flags = GTF_invalid; > + } > + } > + } > + > if ( op.version < 2 && gt->gt_version == 2 ) > gnttab_unpopulate_status_frames(d, gt); > > - if ( op.version != gt->gt_version ) > + /* Make sure there''s no crud left over in the table from the > + old version. */ > + for ( i = 0; i < nr_grant_frames(gt); i++ ) > + memset(gt->shared_raw[i], 0, PAGE_SIZE); > + > + /* Restore the first 8 entries (toolstack reserved grants) */ > + if (gt->gt_version != 0 && op.version == 1) > { > - /* Make sure there''s no crud left over in the table from the > - old version. */ > - for ( i = 0; i < nr_grant_frames(gt); i++ ) > - memset(gt->shared_raw[i], 0, PAGE_SIZE); > + memcpy(gt->shared_v1[0], reserved_entries, sizeof(reserved_entries)); > + } > + else if (gt->gt_version != 0 && op.version == 2) > + { > + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ ) > + { > + status_entry(gt, i) = reserved_entries[i].flags & (GTF_reading|GTF_writing); > + shared_entry_v2(gt, i).hdr.flags = reserved_entries[i].flags & ~(GTF_reading|GTF_writing);> + shared_entry_v2(gt, i).hdr.domid = reserved_entries[i].domid; > + shared_entry_v2(gt, i).full_page.frame = reserved_entries[i].frame; > + } > } > > gt->gt_version = op.version; > diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h > index 54d9551..292d724 100644 > --- a/xen/include/public/grant_table.h > +++ b/xen/include/public/grant_table.h > @@ -117,6 +117,13 @@ struct grant_entry_v1 { > }; > typedef struct grant_entry_v1 grant_entry_v1_t; > > +/* The first few grant table entries will be preserved across grant table > + * version changes and may be pre-populated at domain creation by tools. > + */ > +#define GNTTAB_NR_RESERVED_ENTRIES 8 > +#define GNTTAB_RESERVED_CONSOLE 0 > +#define GNTTAB_RESERVED_XENSTORE 1 > + > /* > * Type of grant entry. > * GTF_invalid: This grant entry grants no privileges.
Ian Campbell
2012-Jan-27 10:00 UTC
Re: [PATCH 07/24] lib{xc, xl}: Seed grant tables with xenstore and console grants
On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote:> From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > > This patch claims one reserved grant entry for the console and another > for the xenstore. It modifies the builder to fill in the grant table > entries for the console and the xenstore. > > Previous versions of this patch have been sent to xen-devel. See > http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html > http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01491.html > > Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> > Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>If you use domid_t and xen_pfn_t where appropriate (includes mfn, gmfn etc) then: Acked-by: Ian Campbell <ian.campbell@citrix.com> Also moving the scratch pfn #define into a header (may as well be xc_dom.h until/unless somewhere move appropriate comes up) still seems like a good idea. Ian.
Ian Campbell
2012-Jan-27 10:04 UTC
Re: [PATCH 10/24] mini-os: create app-specific configuration
On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote:> Instead of using CONFIG_QEMU and CONFIG_GRUB to enable or disable minios > code, create CONFIG_ items for features and use application-specific > configuration files to enable or disable the features. > > The configuration flags are currently added to the compiler command > line; as the number of flags grows this may need to move to a header. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com>> diff --git a/stubdom/c/minios.cfg b/stubdom/c/minios.cfg > new file mode 100644 > index 0000000..e69de29 > diff --git a/stubdom/caml/minios.cfg b/stubdom/caml/minios.cfg > new file mode 100644 > index 0000000..e69de29These are new empty files? That''s ok -- just wanted to check there wasn''t some patch weirdness happening. Ian.
Ian Campbell
2012-Jan-27 10:05 UTC
Re: [PATCH 11/24] mini-os: Move test functions into test.c
On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote:> While useful, these test functions should not be compiled into every > mini-os instance that we compile. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>On the assumption that this is pure code motion and minimal changes to support the new location I didn''t look closely but: Acked-by: Ian Campbell <ian.campbell@citrix.com> Ian.
Ian Campbell
2012-Jan-27 10:12 UTC
Re: [PATCH 12/24] mini-os: make frontends and xenbus optional
On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote:> This adds compile-time logic to disable certain frontends in mini-os: > - pcifront is disabled by default, enabled for ioemu > - blkfront, netfront, fbfront, kbdfront, consfront are enabled by default > - xenbus is required for any frontend, and is enabled by default > > If all frontends and xenbus are disabled, mini-os will run without > needing to communicate with xenstore, making it suitable to run the > xenstore daemon. The console frontend is not required for the initial > console, only consoles opened via openpt or ptmx. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com>
Ian Campbell
2012-Jan-27 10:17 UTC
Re: [PATCH 15/24] xenstored: refactor socket setup code
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com> Ian.
Ian Campbell
2012-Jan-27 10:20 UTC
Re: [PATCH 16/24] xenstored: add NO_SOCKETS compilation option
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> From: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > Add option for compiling xenstored without unix sockets to support > running on mini-OS > > Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> > Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com> The lack of error return/handling from accept_connection seems odd to me but that was there already. Ian.
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote: You forgot your S-o-b. Acked-by: Ian Campbell <ian.campbell@citrix.com>> --- > tools/xenstore/xenstored_core.c | 20 ++++++++++++++------ > 1 files changed, 14 insertions(+), 6 deletions(-) >
Ian Campbell
2012-Jan-27 10:34 UTC
Re: [PATCH 19/24] xenstored: support running in minios stubdom
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> A previous versions of this patch has been sent to xen-devel. See > http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01655.html > > Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> > Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com>> --- > tools/xenstore/Makefile | 9 ++++- > tools/xenstore/utils.h | 2 + > tools/xenstore/xenstored_core.c | 74 +++++++++++++++++++++++------------- > tools/xenstore/xenstored_domain.c | 11 +++++ > 4 files changed, 68 insertions(+), 28 deletions(-)
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> diff --git a/stubdom/xenstore-minios.cfg b/stubdom/xenstore-minios.cfg > new file mode 100644 > index 0000000..ab7338f > --- /dev/null > +++ b/stubdom/xenstore-minios.cfg > @@ -0,0 +1,9 @@ > +CONFIG_BLKFRONT=n > +CONFIG_NETFRONT=n > +CONFIG_FBFRONT=n > +CONFIG_KBDFRONT=n > +CONFIG_CONSFRONT=n > +CONFIG_XENBUS=n > + > +lwip=n > +DEF_CPPFLAGS := $(filter-out -DHAVE_LWIP,$(DEF_CPPFLAGS))This suggests that we should have CONFIG_LWIP. Otherwise: Acked-by: Ian Campbell <ian.campbell@citrix.com> Ian.
Ian Campbell
2012-Jan-27 10:37 UTC
Re: [PATCH 22/24] xenstored: use domain_is_unprivileged instead of checking conn->id
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> This centralizes all the permission checking for privileged domains in > preparation for allowing domains other than dom0 to be privileged. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>I still can''t get my head round the double negatives etc but your explanation last time round convinced me that you have so: Acked-by: Ian Campbell <ian.campbell@citrix.com>
Ian Campbell
2012-Jan-27 10:38 UTC
Re: [PATCH 23/24] xenstored: add --priv-domid parameter
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> This parameter identifies an alternative service domain which has > superuser access to the xenstore database, which is currently required > to set up a new domain''s xenstore entries. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>Acked-by: Ian Campbell <ian.campbell@citrix.com>> --- > tools/xenstore/xenstored_core.c | 5 +++++ > tools/xenstore/xenstored_core.h | 1 + > tools/xenstore/xenstored_domain.c | 2 +- > 3 files changed, 7 insertions(+), 1 deletions(-) > > diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c > index f254947..2894f1b 100644 > --- a/tools/xenstore/xenstored_core.c > +++ b/tools/xenstore/xenstored_core.c > @@ -1825,6 +1825,7 @@ static struct option options[] = { > { "event", 1, NULL, ''e'' }, > { "help", 0, NULL, ''H'' }, > { "no-fork", 0, NULL, ''N'' }, > + { "priv-domid", 1, NULL, ''p'' }, > { "output-pid", 0, NULL, ''P'' }, > { "entry-size", 1, NULL, ''S'' }, > { "trace-file", 1, NULL, ''T'' }, > @@ -1838,6 +1839,7 @@ static struct option options[] = { > > extern void dump_conn(struct connection *conn); > int dom0_event = 0; > +int priv_domid = 0; > > int main(int argc, char *argv[]) > { > @@ -1903,6 +1905,9 @@ int main(int argc, char *argv[]) > case ''e'': > dom0_event = strtol(optarg, NULL, 10); > break; > + case ''p'': > + priv_domid = strtol(optarg, NULL, 10); > + break; > } > } > if (optind != argc) > diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h > index d3040ba..03e2e48 100644 > --- a/tools/xenstore/xenstored_core.h > +++ b/tools/xenstore/xenstored_core.h > @@ -169,6 +169,7 @@ void dtrace_io(const struct connection *conn, const struct buffered_data *data, > > extern int event_fd; > extern int dom0_event; > +extern int priv_domid; > > /* Map the kernel''s xenstore page. */ > void *xenbus_map(void); > diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c > index 22fe126b..151e088 100644 > --- a/tools/xenstore/xenstored_domain.c > +++ b/tools/xenstore/xenstored_domain.c > @@ -263,7 +263,7 @@ bool domain_can_read(struct connection *conn) > > bool domain_is_unprivileged(struct connection *conn) > { > - return (conn && conn->domain && conn->domain->domid != 0); > + return (conn && conn->domain && conn->domain->domid != 0 && conn->domain->domid != priv_domid); > } > > bool domain_can_write(struct connection *conn)
Stefano Stabellini
2012-Jan-27 11:22 UTC
Re: [PATCH 19/24] xenstored: support running in minios stubdom
On Thu, 26 Jan 2012, Daniel De Graaf wrote:> A previous versions of this patch has been sent to xen-devel. See > http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01655.html > > Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> > Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>The patch series is definitely going in the right direction.> + > .PHONY: all > all: $(ALL_TARGETS) > > @@ -45,10 +49,13 @@ xenstored_probes.o: xenstored_solaris.o > > CFLAGS += -DHAVE_DTRACE=1 > endif > - > + > xenstored: $(XENSTORED_OBJS) > $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) > > +xenstored.a: $(XENSTORED_OBJS) > + $(AR) cr $@ $^ > + > $(CLIENTS): xenstore > ln -f xenstore $@ > > diff --git a/tools/xenstore/utils.h b/tools/xenstore/utils.h > index f378343..2effd17 100644 > --- a/tools/xenstore/utils.h > +++ b/tools/xenstore/utils.h > @@ -19,7 +19,9 @@ static inline bool strends(const char *a, const char *b) > return streq(a + strlen(a) - strlen(b), b); > } > > +#ifndef ARRAY_SIZE > #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) > +#endif > > void barf(const char *fmt, ...) __attribute__((noreturn)); > void barf_perror(const char *fmt, ...) __attribute__((noreturn)); > diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c > index 4b12cf2..0b9d4f2 100644 > --- a/tools/xenstore/xenstored_core.c > +++ b/tools/xenstore/xenstored_core.c > @@ -224,7 +224,6 @@ static void reopen_log(void) > } > } > > - > static bool write_messages(struct connection *conn) > { > int ret; > @@ -327,7 +326,8 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, > set_fd(sock, inset, &max); > if (ro_sock != -1) > set_fd(ro_sock, inset, &max); > - set_fd(reopen_log_pipe[0], inset, &max); > + if (reopen_log_pipe[0] != -1) > + set_fd(reopen_log_pipe[0], inset, &max); > > if (xce_handle != NULL) > set_fd(xc_evtchn_fd(xce_handle), inset, &max); > @@ -1664,6 +1664,19 @@ static void corrupt(struct connection *conn, const char *fmt, ...) > } > > > +#ifdef __MINIOS__ > +static void write_pidfile(const char *pidfile) > +{ > +} > + > +static void daemonize(void) > +{ > +} > + > +static void finish_daemonize(void) > +{ > +} > +#else > static void write_pidfile(const char *pidfile) > { > char buf[100]; > @@ -1711,6 +1724,19 @@ static void daemonize(void) > umask(0); > } > > +static void finish_daemonize(void) > +{ > + int devnull = open("/dev/null", O_RDWR); > + if (devnull == -1) > + barf_perror("Could not open /dev/null\n"); > + dup2(devnull, STDIN_FILENO); > + dup2(devnull, STDOUT_FILENO); > + dup2(devnull, STDERR_FILENO); > + close(devnull); > + xprintf = trace; > +} > +#endif > + > #ifdef NO_SOCKETS > static void init_sockets(int **psock, int **pro_sock) > {At this point we could have the MiniOS version of write_pidfile, daemonize, finish_daemonize in tools/xenstore/xenstored_minios.c and the Linux/NetBSD version of them in tools/xenstore/xenstored_linux.c.> --- > tools/xenstore/Makefile | 9 ++++- > tools/xenstore/utils.h | 2 + > tools/xenstore/xenstored_core.c | 74 +++++++++++++++++++++++------------- > tools/xenstore/xenstored_domain.c | 11 +++++ > 4 files changed, 68 insertions(+), 28 deletions(-) > > diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile > index 4facb62..be892fd 100644 > --- a/tools/xenstore/Makefile > +++ b/tools/xenstore/Makefile > @@ -28,6 +28,10 @@ endif > > ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored > > +ifdef CONFIG_STUBDOM > +CFLAGS += -DNO_SOCKETS=1 > +endif> @@ -1822,6 +1848,11 @@ int main(int argc, char *argv[]) > int evtchn_fd = -1; > struct timeval *timeout; > > +#ifdef __MINIOS__ > + /* minios always uses internal DB */ > + tdb_flags = TDB_INTERNAL|TDB_NOLOCK; > +#endifcan you use the "internal-db" command line option?> while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, > NULL)) != -1) { > switch (opt) { > @@ -1874,20 +1905,10 @@ int main(int argc, char *argv[]) > > reopen_log(); > > - /* make sure xenstored directory exists */ > - if (mkdir(xs_daemon_rundir(), 0755)) { > - if (errno != EEXIST) { > - perror("error: mkdir daemon rundir"); > - exit(-1); > - } > - } > - > - if (mkdir(xs_daemon_rootdir(), 0755)) { > - if (errno != EEXIST) { > - perror("error: mkdir daemon rootdir"); > - exit(-1); > - } > - } > + /* make sure xenstored directories exist */ > + /* Errors ignored here, will be reported when we open files */ > + mkdir(xs_daemon_rundir(), 0755); > + mkdir(xs_daemon_rootdir(), 0755); > > if (dofork) { > openlog("xenstored", 0, LOG_DAEMON); > @@ -1905,9 +1926,14 @@ int main(int argc, char *argv[]) > > init_sockets(&sock, &ro_sock); > > +#ifdef __MINIOS__ > + reopen_log_pipe[0] = -1; > + reopen_log_pipe[1] = -1; > +#else > if (pipe(reopen_log_pipe)) { > barf_perror("pipe"); > } > +#endifmaybe we could have open/read/write_log_pipe functions?> /* Setup the database */ > setup_structure(); > @@ -1925,16 +1951,8 @@ int main(int argc, char *argv[]) > } > > /* redirect to /dev/null now we''re ready to accept connections */ > - if (dofork) { > - int devnull = open("/dev/null", O_RDWR); > - if (devnull == -1) > - barf_perror("Could not open /dev/null\n"); > - dup2(devnull, STDIN_FILENO); > - dup2(devnull, STDOUT_FILENO); > - dup2(devnull, STDERR_FILENO); > - close(devnull); > - xprintf = trace; > - } > + if (dofork) > + finish_daemonize(); > > signal(SIGHUP, trigger_reopen_log); > > @@ -1944,8 +1962,10 @@ int main(int argc, char *argv[]) > /* Get ready to listen to the tools. */ > max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout); > > +#ifndef __MINIOS__ > /* Tell the kernel we''re up and running. */ > xenbus_notify_running(); > +#endif > > /* Main loop. */ > for (;;) { > @@ -1957,7 +1977,7 @@ int main(int argc, char *argv[]) > barf_perror("Select failed"); > } > > - if (FD_ISSET(reopen_log_pipe[0], &inset)) { > + if (reopen_log_pipe[0] != -1 && FD_ISSET(reopen_log_pipe[0], &inset)) { > char c; > if (read(reopen_log_pipe[0], &c, 1) != 1) > barf_perror("read failed"); > diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c > index c521e52..4243f91 100644 > --- a/tools/xenstore/xenstored_domain.c > +++ b/tools/xenstore/xenstored_domain.c > @@ -197,12 +197,16 @@ static int destroy_domain(void *_domain) > } > > if (domain->interface) { > +#ifdef __MINIOS__ > + unmap_interface(domain->interface); > +#else > /* Domain 0 was mapped by dom0_init, so it must be unmapped > using munmap() and not the grant unmap call. */ > if (domain->domid == 0) > munmap(domain->interface, getpagesize()); > else > unmap_interface(domain->interface); > +#endif > } > > fire_watches(NULL, "@releaseDomain", false); > @@ -597,6 +601,12 @@ void restore_existing_connections(void) > { > } > > +#ifdef __MINIOS__ > +static int dom0_init(void) > +{ > + return 0; > +} > +#else > static int dom0_init(void) > { > evtchn_port_t port; > @@ -620,6 +630,7 @@ static int dom0_init(void) > > return 0; > } > +#endifanother candidate to be moved to xenstored_minios/linux
Ian Campbell
2012-Jan-27 11:49 UTC
Re: [PATCH 19/24] xenstored: support running in minios stubdom
On Fri, 2012-01-27 at 11:22 +0000, Stefano Stabellini wrote:> > > #ifdef NO_SOCKETS > > static void init_sockets(int **psock, int **pro_sock) > > { > > At this point we could have the MiniOS version of write_pidfile, > daemonize, finish_daemonize in tools/xenstore/xenstored_minios.c and > the Linux/NetBSD version of them in tools/xenstore/xenstored_linux.c.xenstored_linux would be a terribly misleading name. Better xenstored_posix or something like that. Ian.
Ian Campbell
2012-Jan-27 13:06 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> The symbol _LINUX_LIST_H collides with other header files.Hrm mini-os is supposed to have been BSD licensed since 19712:7a215fae6f1f and that symbol name is *rather* suspicious. The thread associated with that commit[0] suggests that everything GPL had been rewritten but I suspect that due to the lack of GPL header this file was missed. This effectively means that any work combined with mini-os was GPL rather than BSD as might reasonably have been expected. I believe everything in-tree which we link with mini-os (the stubdom/ tree) is GPL or GPL-compatible but this has laid rather a nasty trap for anyone else using mini-os and I think we should fix it ASAP. Below is a patch which switches to using the same BSD sys/queue.h list macros as we use in libxl. Presumably you came across another file which used _LINUX_LIST_H which clashed? Out of interest what was it? Ian. 8<------------------------------------------------------------------------ [0] http://lists.xen.org/archives/html/xen-devel/2009-06/msg00123.html # HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327669492 0 # Node ID 72f001fd2bc43d18a63c1db6202d830b42b53d95 # Parent b78b11c15aa818f81cb77324938c6293edeed63d mini-os: use BSD sys/queue.h instead of Linux list.h The latter is GPL which makes the whole of mini-os GPL rather than BSD as intended. In tree users are all GPL or GPL-compatible but we should fix this so that mini-os is BSD. Do so by using the same BSD sys/queue.h as we use in libxl. Tested with the builtin mini-os test app and qemu stubdomain, both of which appear to still function as expected. Move tools/libxl/external and the associated sed script to tools/include/xen-external to allow more sensible access from mini-os. Also add s/NULL/0/ in the sed script due to NULL not always being defined in stubdom code when mini-os/wait.h is included. As well as the obvious ABI changes there are a few API updates associated with the change: - struct rw_semaphore.wait_list is unused - remove_waiter needs to take the wait_queue_head The latter requires a qemu update which I will post separately. Please apply first and update QEMU_TAG as appropriate. I sprinkled some extra-emacs local variables around the files I edited which didn''t have them. I think this should be backported to the stable branches since external users of mini-os may have been mislead into thinking they could safely link mini-os against GPL-incompatible code. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -62,6 +62,7 @@ ^docs/xen-api/xenapi-datamodel-graph.eps$ ^docs/xen-api/xenapi.out$ ^extras/mini-os/arch/ia64/gen_off.s$ +^extras/mini-os/include/list\.h$ ^extras/mini-os/include/mini-os$ ^extras/mini-os/include/ia64/mini-os$ ^extras/mini-os/include/ia64/offsets.h$ diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -52,8 +52,12 @@ ifneq ($(ARCH_LINKS),) $(arch_links) endif +include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue.h + perl $^ --prefix=minios >$@.new + $(call move-if-changed,$@.new,$@) + .PHONY: links -links: $(ARCH_LINKS) +links: include/list.h $(ARCH_LINKS) [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen [ -e include/mini-os ] || ln -sf . include/mini-os [ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os @@ -97,7 +101,7 @@ ifneq ($(APP_OBJS),) APP_O=$(OBJ_DIR)/$(TARGET)_app.o endif -$(OBJ_DIR)/$(TARGET): links $(OBJS) $(APP_O) arch_lib +$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@ @@ -112,6 +116,7 @@ clean: arch_clean for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \ rm -f $$dir/*.o; \ done + rm -f include/list.h rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz find . $(OBJ_DIR) -type l | xargs rm -f $(RM) $(OBJ_DIR)/lwip.a $(LWO) diff --git a/extras/mini-os/blkfront.c b/extras/mini-os/blkfront.c --- a/extras/mini-os/blkfront.c +++ b/extras/mini-os/blkfront.c @@ -323,7 +323,7 @@ static void blkfront_wait_slot(struct bl schedule(); local_irq_save(flags); } - remove_waiter(w); + remove_waiter(w, blkfront_queue); local_irq_restore(flags); } } @@ -414,7 +414,7 @@ void blkfront_io(struct blkfront_aiocb * schedule(); local_irq_save(flags); } - remove_waiter(w); + remove_waiter(w, blkfront_queue); local_irq_restore(flags); } @@ -470,7 +470,7 @@ void blkfront_sync(struct blkfront_dev * schedule(); local_irq_save(flags); } - remove_waiter(w); + remove_waiter(w, blkfront_queue); local_irq_restore(flags); } diff --git a/extras/mini-os/fbfront.c b/extras/mini-os/fbfront.c --- a/extras/mini-os/fbfront.c +++ b/extras/mini-os/fbfront.c @@ -569,7 +569,7 @@ static void fbfront_out_event(struct fbf add_waiter(w, fbfront_queue); while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN) schedule(); - remove_waiter(w); + remove_waiter(w, fbfront_queue); prod = page->out_prod; mb(); /* ensure ring space available */ diff --git a/extras/mini-os/include/list.h b/extras/mini-os/include/list.h deleted file mode 100644 --- a/extras/mini-os/include/list.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct minios_list_head { - struct minios_list_head *next, *prev; -}; - -#define MINIOS_LIST_HEAD_INIT(name) { &(name), &(name) } - -#define MINIOS_LIST_HEAD(name) \ - struct minios_list_head name = MINIOS_LIST_HEAD_INIT(name) - -#define MINIOS_INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -#define minios_list_top(head, type, member) \ -({ \ - struct minios_list_head *_head = (head); \ - minios_list_empty(_head) ? NULL : minios_list_entry(_head->next, type, member); \ -}) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __minios_list_add(struct minios_list_head * new, - struct minios_list_head * prev, - struct minios_list_head * next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * minios_list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static __inline__ void minios_list_add(struct minios_list_head *new, struct minios_list_head *head) -{ - __minios_list_add(new, head, head->next); -} - -/** - * minios_list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static __inline__ void minios_list_add_tail(struct minios_list_head *new, struct minios_list_head *head) -{ - __minios_list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __minios_list_del(struct minios_list_head * prev, - struct minios_list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * minios_list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: minios_list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static __inline__ void minios_list_del(struct minios_list_head *entry) -{ - __minios_list_del(entry->prev, entry->next); -} - -/** - * minios_list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static __inline__ void minios_list_del_init(struct minios_list_head *entry) -{ - __minios_list_del(entry->prev, entry->next); - MINIOS_INIT_LIST_HEAD(entry); -} - -/** - * minios_list_empty - tests whether a list is empty - * @head: the list to test. - */ -static __inline__ int minios_list_empty(struct minios_list_head *head) -{ - return head->next == head; -} - -/** - * minios_list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static __inline__ void minios_list_splice(struct minios_list_head *list, struct minios_list_head *head) -{ - struct minios_list_head *first = list->next; - - if (first != list) { - struct minios_list_head *last = list->prev; - struct minios_list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * minios_list_entry - get the struct for this entry - * @ptr: the &struct minios_list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the minios_list_struct within the struct. - */ -#define minios_list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * minios_list_for_each - iterate over a list - * @pos: the &struct minios_list_head to use as a loop counter. - * @head: the head for your list. - */ -#define minios_list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * minios_list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct minios_list_head to use as a loop counter. - * @n: another &struct minios_list_head to use as temporary storage - * @head: the head for your list. - */ -#define minios_list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * minios_list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the minios_list_struct within the struct. - */ -#define minios_list_for_each_entry(pos, head, member) \ - for (pos = minios_list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = minios_list_entry(pos->member.next, typeof(*pos), member)) - -/** - * minios_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the minios_list_struct within the struct. - */ -#define minios_list_for_each_entry_safe(pos, n, head, member) \ - for (pos = minios_list_entry((head)->next, typeof(*pos), member), \ - n = minios_list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = minios_list_entry(n->member.next, typeof(*n), member)) -#endif /* _LINUX_LIST_H */ - diff --git a/extras/mini-os/include/sched.h b/extras/mini-os/include/sched.h --- a/extras/mini-os/include/sched.h +++ b/extras/mini-os/include/sched.h @@ -19,7 +19,7 @@ struct thread #else /* !defined(__ia64__) */ thread_regs_t regs; #endif /* !defined(__ia64__) */ - struct minios_list_head thread_list; + MINIOS_TAILQ_ENTRY(struct thread) thread_list; uint32_t flags; s_time_t wakeup_time; #ifdef HAVE_LIBC diff --git a/extras/mini-os/include/semaphore.h b/extras/mini-os/include/semaphore.h --- a/extras/mini-os/include/semaphore.h +++ b/extras/mini-os/include/semaphore.h @@ -21,7 +21,6 @@ struct semaphore struct rw_semaphore { signed long count; spinlock_t wait_lock; - struct minios_list_head wait_list; int debug; }; diff --git a/extras/mini-os/include/wait.h b/extras/mini-os/include/wait.h --- a/extras/mini-os/include/wait.h +++ b/extras/mini-os/include/wait.h @@ -5,47 +5,47 @@ #include <mini-os/os.h> #include <mini-os/waittypes.h> -#define DEFINE_WAIT(name) \ -struct wait_queue name = { \ - .thread = get_current(), \ - .thread_list = MINIOS_LIST_HEAD_INIT((name).thread_list), \ +#define DEFINE_WAIT(name) \ +struct wait_queue name = { \ + .thread = get_current(), \ + .waiting = 0, \ } static inline void init_waitqueue_head(struct wait_queue_head *h) { - MINIOS_INIT_LIST_HEAD(&h->thread_list); + MINIOS_STAILQ_INIT(h); } static inline void init_waitqueue_entry(struct wait_queue *q, struct thread *thread) { q->thread = thread; - MINIOS_INIT_LIST_HEAD(&q->thread_list); + q->waiting = 0; } - static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue *q) { - if (minios_list_empty(&q->thread_list)) - minios_list_add(&q->thread_list, &h->thread_list); + if (!q->waiting) { + MINIOS_STAILQ_INSERT_HEAD(h, q, thread_list); + q->waiting = 1; + } } -static inline void remove_wait_queue(struct wait_queue *q) +static inline void remove_wait_queue(struct wait_queue_head *h, struct wait_queue *q) { - minios_list_del(&q->thread_list); + if (q->waiting) { + MINIOS_STAILQ_REMOVE(h, q, struct wait_queue, thread_list); + q->waiting = 0; + } } static inline void wake_up(struct wait_queue_head *head) { unsigned long flags; - struct minios_list_head *tmp, *next; + struct wait_queue *curr, *tmp; local_irq_save(flags); - minios_list_for_each_safe(tmp, next, &head->thread_list) - { - struct wait_queue *curr; - curr = minios_list_entry(tmp, struct wait_queue, thread_list); + MINIOS_STAILQ_FOREACH_SAFE(curr, head, thread_list, tmp) wake(curr->thread); - } local_irq_restore(flags); } @@ -57,11 +57,11 @@ static inline void wake_up(struct wait_q local_irq_restore(flags); \ } while (0) -#define remove_waiter(w) do { \ - unsigned long flags; \ - local_irq_save(flags); \ - remove_wait_queue(&w); \ - local_irq_restore(flags); \ +#define remove_waiter(w, wq) do { \ + unsigned long flags; \ + local_irq_save(flags); \ + remove_wait_queue(&wq, &w); \ + local_irq_restore(flags); \ } while (0) #define wait_event_deadline(wq, condition, deadline) do { \ @@ -84,7 +84,7 @@ static inline void wake_up(struct wait_q local_irq_save(flags); \ /* need to wake up */ \ wake(get_current()); \ - remove_wait_queue(&__wait); \ + remove_wait_queue(&wq, &__wait); \ local_irq_restore(flags); \ } while(0) @@ -93,3 +93,13 @@ static inline void wake_up(struct wait_q #endif /* __WAIT_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/extras/mini-os/include/waittypes.h b/extras/mini-os/include/waittypes.h --- a/extras/mini-os/include/waittypes.h +++ b/extras/mini-os/include/waittypes.h @@ -6,21 +6,27 @@ struct thread; struct wait_queue { + int waiting; struct thread *thread; - struct minios_list_head thread_list; + MINIOS_STAILQ_ENTRY(struct wait_queue) thread_list; }; -struct wait_queue_head -{ - /* TODO - lock required? */ - struct minios_list_head thread_list; -}; +/* TODO - lock required? */ +MINIOS_STAILQ_HEAD(wait_queue_head, struct wait_queue); #define DECLARE_WAIT_QUEUE_HEAD(name) \ - struct wait_queue_head name = \ - { .thread_list = { &(name).thread_list, &(name).thread_list} } + struct wait_queue_head name = MINIOS_STAILQ_HEAD_INITIALIZER(name) -#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ - .thread_list = { &(name).thread_list, &(name).thread_list } } +#define __WAIT_QUEUE_HEAD_INITIALIZER(name) MINIOS_STAILQ_HEAD_INITIALIZER(name) #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c --- a/extras/mini-os/lib/sys.c +++ b/extras/mini-os/lib/sys.c @@ -234,7 +234,7 @@ int read(int fd, void *buf, size_t nbyte break; schedule(); } - remove_waiter(w); + remove_waiter(w, console_queue); return ret; } #ifdef HAVE_LWIP @@ -705,12 +705,12 @@ int select(int nfds, fd_set *readfds, fd fd_set myread, mywrite, myexcept; struct thread *thread = get_current(); s_time_t start = NOW(), stop; - DEFINE_WAIT(w1); - DEFINE_WAIT(w2); - DEFINE_WAIT(w3); - DEFINE_WAIT(w4); - DEFINE_WAIT(w5); - DEFINE_WAIT(w6); + DEFINE_WAIT(netfront_w); + DEFINE_WAIT(event_w); + DEFINE_WAIT(blkfront_w); + DEFINE_WAIT(xenbus_watch_w); + DEFINE_WAIT(kbdfront_w); + DEFINE_WAIT(console_w); assert(thread == main_thread); @@ -727,12 +727,12 @@ int select(int nfds, fd_set *readfds, fd /* Tell people we''re going to sleep before looking at what they are * saying, hence letting them wake us if events happen between here and * schedule() */ - add_waiter(w1, netfront_queue); - add_waiter(w2, event_queue); - add_waiter(w3, blkfront_queue); - add_waiter(w4, xenbus_watch_queue); - add_waiter(w5, kbdfront_queue); - add_waiter(w6, console_queue); + add_waiter(netfront_w, netfront_queue); + add_waiter(event_w, event_queue); + add_waiter(blkfront_w, blkfront_queue); + add_waiter(xenbus_watch_w, xenbus_watch_queue); + add_waiter(kbdfront_w, kbdfront_queue); + add_waiter(console_w, console_queue); if (readfds) myread = *readfds; @@ -814,12 +814,12 @@ int select(int nfds, fd_set *readfds, fd ret = -1; out: - remove_waiter(w1); - remove_waiter(w2); - remove_waiter(w3); - remove_waiter(w4); - remove_waiter(w5); - remove_waiter(w6); + remove_waiter(netfront_w, netfront_queue); + remove_waiter(event_w, event_queue); + remove_waiter(blkfront_w, blkfront_queue); + remove_waiter(xenbus_watch_w, xenbus_watch_queue); + remove_waiter(kbdfront_w, kbdfront_queue); + remove_waiter(console_w, console_queue); return ret; } diff --git a/extras/mini-os/lib/xmalloc.c b/extras/mini-os/lib/xmalloc.c --- a/extras/mini-os/lib/xmalloc.c +++ b/extras/mini-os/lib/xmalloc.c @@ -44,16 +44,18 @@ #include <mini-os/xmalloc.h> #ifndef HAVE_LIBC -static MINIOS_LIST_HEAD(freelist); /* static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED; */ struct xmalloc_hdr { /* Total including this hdr, unused padding and second hdr. */ size_t size; - struct minios_list_head freelist; + MINIOS_TAILQ_ENTRY(struct xmalloc_hdr) freelist; } __cacheline_aligned; +static MINIOS_TAILQ_HEAD(,struct xmalloc_hdr) freelist + MINIOS_TAILQ_HEAD_INITIALIZER(freelist); + /* Unused padding data between the two hdrs. */ struct xmalloc_pad @@ -82,7 +84,7 @@ static void maybe_split(struct xmalloc_h extra = (struct xmalloc_hdr *)((unsigned long)hdr + size); extra->size = leftover; /* spin_lock_irqsave(&freelist_lock, flags); */ - minios_list_add(&extra->freelist, &freelist); + MINIOS_TAILQ_INSERT_HEAD(&freelist, extra, freelist); /* spin_unlock_irqrestore(&freelist_lock, flags); */ } else @@ -91,8 +93,6 @@ static void maybe_split(struct xmalloc_h } hdr->size = size; - /* Debugging aid. */ - hdr->freelist.next = hdr->freelist.prev = NULL; } static struct xmalloc_hdr *xmalloc_new_page(size_t size) @@ -128,8 +128,6 @@ static void *xmalloc_whole_pages(size_t return NULL; hdr->size = (1UL << (pageorder + PAGE_SHIFT)); - /* Debugging aid. */ - hdr->freelist.next = hdr->freelist.prev = NULL; ret = (char*)hdr + hdr_size; pad = (struct xmalloc_pad *) ret - 1; @@ -155,14 +153,14 @@ void *_xmalloc(size_t size, size_t align /* Search free list. */ /* spin_lock_irqsave(&freelist_lock, flags); */ - minios_list_for_each_entry_safe( i, tmp, &freelist, freelist ) + MINIOS_TAILQ_FOREACH_SAFE(i, &freelist, freelist, tmp) { data_begin = align_up((uintptr_t)i + hdr_size, align); if ( data_begin + size > (uintptr_t)i + i->size ) continue; - minios_list_del(&i->freelist); + MINIOS_TAILQ_REMOVE(&freelist, i, freelist); /* spin_unlock_irqrestore(&freelist_lock, flags); */ uintptr_t size_before = (data_begin - hdr_size) - (uintptr_t)i; @@ -173,7 +171,7 @@ void *_xmalloc(size_t size, size_t align new_i->size = i->size - size_before; i->size = size_before; /* spin_lock_irqsave(&freelist_lock, flags); */ - minios_list_add(&i->freelist, &freelist); + MINIOS_TAILQ_INSERT_HEAD(&freelist, i, freelist); /* spin_unlock_irqrestore(&freelist_lock, flags); */ i = new_i; } @@ -224,16 +222,9 @@ void xfree(const void *p) *(int*)0=0; } - /* Not previously freed. */ - if(hdr->freelist.next || hdr->freelist.prev) - { - printk("Should not be previously freed\n"); - *(int*)0=0; - } - /* Merge with other free block, or put in list. */ /* spin_lock_irqsave(&freelist_lock, flags); */ - minios_list_for_each_entry_safe( i, tmp, &freelist, freelist ) + MINIOS_TAILQ_FOREACH_SAFE(i, &freelist, freelist, tmp) { unsigned long _i = (unsigned long)i; unsigned long _hdr = (unsigned long)hdr; @@ -245,7 +236,7 @@ void xfree(const void *p) /* We follow this block? Swallow it. */ if ( (_i + i->size) == _hdr ) { - minios_list_del(&i->freelist); + MINIOS_TAILQ_REMOVE(&freelist, i, freelist); i->size += hdr->size; hdr = i; } @@ -253,7 +244,7 @@ void xfree(const void *p) /* We precede this block? Swallow it. */ if ( (_hdr + hdr->size) == _i ) { - minios_list_del(&i->freelist); + MINIOS_TAILQ_REMOVE(&freelist, i, freelist); hdr->size += i->size; } } @@ -270,7 +261,7 @@ void xfree(const void *p) } else { - minios_list_add(&hdr->freelist, &freelist); + MINIOS_TAILQ_INSERT_HEAD(&freelist, hdr, freelist); } /* spin_unlock_irqrestore(&freelist_lock, flags); */ @@ -306,3 +297,13 @@ void *_realloc(void *ptr, size_t size) return new; } #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/extras/mini-os/sched.c b/extras/mini-os/sched.c --- a/extras/mini-os/sched.c +++ b/extras/mini-os/sched.c @@ -54,19 +54,20 @@ #define DEBUG(_f, _a...) ((void)0) #endif +MINIOS_TAILQ_HEAD(thread_list, struct thread); + struct thread *idle_thread = NULL; -MINIOS_LIST_HEAD(exited_threads); +static struct thread_list exited_threads = MINIOS_TAILQ_HEAD_INITIALIZER(exited_threads); +static struct thread_list thread_list = MINIOS_TAILQ_HEAD_INITIALIZER(thread_list); static int threads_started; struct thread *main_thread; void inline print_runqueue(void) { - struct minios_list_head *it; struct thread *th; - minios_list_for_each(it, &idle_thread->thread_list) + MINIOS_TAILQ_FOREACH(th, &thread_list, thread_list) { - th = minios_list_entry(it, struct thread, thread_list); printk(" Thread \"%s\", runnable=%d\n", th->name, is_runnable(th)); } printk("\n"); @@ -74,8 +75,7 @@ void inline print_runqueue(void) void schedule(void) { - struct thread *prev, *next, *thread; - struct minios_list_head *iterator, *next_iterator; + struct thread *prev, *next, *thread, *tmp; unsigned long flags; prev = current; @@ -96,10 +96,9 @@ void schedule(void) time when the next timeout expires, else use 10 seconds. */ s_time_t now = NOW(); s_time_t min_wakeup_time = now + SECONDS(10); - next = NULL; - minios_list_for_each_safe(iterator, next_iterator, &idle_thread->thread_list) + next = NULL; + MINIOS_TAILQ_FOREACH_SAFE(thread, &thread_list, thread_list, tmp) { - thread = minios_list_entry(iterator, struct thread, thread_list); if (!is_runnable(thread) && thread->wakeup_time != 0LL) { if (thread->wakeup_time <= now) @@ -111,8 +110,8 @@ void schedule(void) { next = thread; /* Put this thread on the end of the list */ - minios_list_del(&thread->thread_list); - minios_list_add_tail(&thread->thread_list, &idle_thread->thread_list); + MINIOS_TAILQ_REMOVE(&thread_list, thread, thread_list); + MINIOS_TAILQ_INSERT_TAIL(&thread_list, thread, thread_list); break; } } @@ -128,12 +127,11 @@ void schedule(void) inturrupted at the return instruction. And therefore at safe point. */ if(prev != next) switch_threads(prev, next); - minios_list_for_each_safe(iterator, next_iterator, &exited_threads) + MINIOS_TAILQ_FOREACH_SAFE(thread, &exited_threads, thread_list, tmp) { - thread = minios_list_entry(iterator, struct thread, thread_list); if(thread != prev) { - minios_list_del(&thread->thread_list); + MINIOS_TAILQ_REMOVE(&exited_threads, thread, thread_list); free_pages(thread->stack, STACK_SIZE_PAGE_ORDER); xfree(thread); } @@ -154,13 +152,7 @@ struct thread* create_thread(char *name, #endif set_runnable(thread); local_irq_save(flags); - if(idle_thread != NULL) { - minios_list_add_tail(&thread->thread_list, &idle_thread->thread_list); - } else if(function != idle_thread_fn) - { - printk("BUG: Not allowed to create thread before initialising scheduler.\n"); - BUG(); - } + MINIOS_TAILQ_INSERT_TAIL(&thread_list, thread, thread_list); local_irq_restore(flags); return thread; } @@ -208,10 +200,10 @@ void exit_thread(void) printk("Thread \"%s\" exited.\n", thread->name); local_irq_save(flags); /* Remove from the thread list */ - minios_list_del(&thread->thread_list); + MINIOS_TAILQ_REMOVE(&thread_list, thread, thread_list); clear_runnable(thread); /* Put onto exited list */ - minios_list_add(&thread->thread_list, &exited_threads); + MINIOS_TAILQ_INSERT_HEAD(&exited_threads, thread, thread_list); local_irq_restore(flags); /* Schedule will free the resources */ while(1) @@ -296,6 +288,14 @@ void init_sched(void) _REENT_INIT_PTR((&callback_reent)) #endif idle_thread = create_thread("Idle", idle_thread_fn, NULL); - MINIOS_INIT_LIST_HEAD(&idle_thread->thread_list); } +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c --- a/extras/mini-os/xenbus/xenbus.c +++ b/extras/mini-os/xenbus/xenbus.c @@ -85,7 +85,7 @@ char **xenbus_wait_for_watch_return(xenb add_waiter(w, xenbus_watch_queue); schedule(); } - remove_waiter(w); + remove_waiter(w, xenbus_watch_queue); *queue = event->next; return &event->path; } @@ -441,7 +441,7 @@ xenbus_msg_reply(int type, xb_write(type, id, trans, io, nr_reqs); schedule(); - remove_waiter(w); + remove_waiter(w, req_info[id].waitq); wake(current); rep = req_info[id].reply; diff --git a/tools/libxl/external/README b/tools/include/xen-external/README rename from tools/libxl/external/README rename to tools/include/xen-external/README --- a/tools/libxl/external/README +++ b/tools/include/xen-external/README @@ -1,5 +1,5 @@ -WARNING - DO NOT EDIT THINGS IN THIS DIRECTORY (apart from this README) ------------------------------------------------------------------------ +WARNING - DO NOT EDIT THINGS IN THIS DIRECTORY +---------------------------------------------- These files were obtained elsewhere and should only be updated by copying new versions from the source location, as documented below: @@ -12,3 +12,13 @@ bsd-queue.3 svn co -r 221843 svn://svn.freebsd.org/base/head/sys/sys/ svn co -r 221843 svn://svn.freebsd.org/base/head/share/man/man3 svn cat -r 221843 http://svn.freebsd.org/base/head/COPYRIGHT >tools/libxl/external/bsd-COPYRIGHT + +Exceptions: + +README + + This file + +bsd-sys-queue-h-seddery + + Script to transform the above into a new namespace. diff --git a/tools/libxl/external/bsd-COPYRIGHT b/tools/include/xen-external/bsd-COPYRIGHT rename from tools/libxl/external/bsd-COPYRIGHT rename to tools/include/xen-external/bsd-COPYRIGHT diff --git a/tools/libxl/external/bsd-queue.3 b/tools/include/xen-external/bsd-queue.3 rename from tools/libxl/external/bsd-queue.3 rename to tools/include/xen-external/bsd-queue.3 diff --git a/tools/libxl/bsd-sys-queue-h-seddery b/tools/include/xen-external/bsd-sys-queue-h-seddery rename from tools/libxl/bsd-sys-queue-h-seddery rename to tools/include/xen-external/bsd-sys-queue-h-seddery --- a/tools/libxl/bsd-sys-queue-h-seddery +++ b/tools/include/xen-external/bsd-sys-queue-h-seddery @@ -68,3 +68,5 @@ s/\b( s/\b struct \s+ type \b/type/xg; s,^\#include.*sys/cdefs.*,/* $& */,xg; + +s/\b( NULL )/0/xg; diff --git a/tools/libxl/external/bsd-sys-queue.h b/tools/include/xen-external/bsd-sys-queue.h rename from tools/libxl/external/bsd-sys-queue.h rename to tools/include/xen-external/bsd-sys-queue.h diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -93,8 +93,8 @@ _libxl_paths.h: genpath rm -f $@.tmp $(call move-if-changed,$@.2.tmp,$@) -_libxl_list.h: bsd-sys-queue-h-seddery external/bsd-sys-queue.h - perl ./$^ --prefix=libxl >$@.new +_libxl_list.h: $(XEN_INCLUDE)/xen-external/bsd-sys-queue-h-seddery $(XEN_INCLUDE)/xen-external/bsd-sys-queue.h + perl $^ --prefix=libxl >$@.new $(call move-if-changed,$@.new,$@) libxl_paths.c: _libxl_paths.h
Ian Campbell
2012-Jan-27 13:09 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
On Fri, 2012-01-27 at 13:06 +0000, Ian Campbell wrote:> > As well as the obvious ABI changes there are a few API updates > associated with the change: > > - struct rw_semaphore.wait_list is unused > - remove_waiter needs to take the wait_queue_head > > The latter requires a qemu update which I will post separately. Please > apply first and update QEMU_TAG as appropriate.8<---------------------------------------------------------------------- From ab35cca68024f077ca5dbd8d099605e2df830b22 Mon Sep 17 00:00:00 2001 From: Ian Campbell <ian.campbell@citrix.com> Date: Fri, 27 Jan 2012 12:54:57 +0000 Subject: [PATCH] block-vbd: update to new mini-os wait queue API Signed-off-by: Ian Campbell <ian.campbell@citrix.com> --- block-vbd.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block-vbd.c b/block-vbd.c index 56794f6..71f1731 100644 --- a/block-vbd.c +++ b/block-vbd.c @@ -144,7 +144,7 @@ void qemu_aio_wait(void) break; schedule(); } - remove_waiter(w); + remove_waiter(w, blkfront_queue); } static void vbd_do_aio(struct blkfront_aiocb *aiocbp, int ret) { -- 1.7.2.5
Daniel De Graaf
2012-Jan-27 15:12 UTC
Re: [PATCH 05/24] xen: Preserve reserved grant entries when switching versions
On 01/27/2012 04:54 AM, Ian Campbell wrote:> It would be worth CCing the relevant maintainers for each patch in the > series. e.g. Keir in this case.OK, will do that for v6.> On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote: >> In order for the toolstack to use reserved grant table entries, the >> grant table for a guest must be initialized prior to the guest''s boot. >> When the guest switches grant table versions (necessary if the guest is >> using v2 grant tables, or on kexec if switching grant versions), these >> initial grants will be cleared. Instead of clearing them, preserve >> the grants across the type change. >> >> Attempting to preserve v2-only features such as sub-page grants will >> produce a warning and invalidate the resulting v1 grant entry. >> >> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> >> --- >> xen/common/grant_table.c | 48 +++++++++++++++++++++++++++++++++---- >> xen/include/public/grant_table.h | 7 +++++ >> 2 files changed, 49 insertions(+), 6 deletions(-) >> >> diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c >> index 0c55fd1..6f24a94 100644 >> --- a/xen/common/grant_table.c >> +++ b/xen/common/grant_table.c >> @@ -2111,6 +2111,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) >> struct domain *d = current->domain; >> struct grant_table *gt = d->grant_table; >> struct active_grant_entry *act; >> + grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES]; >> long res; >> int i; >> >> @@ -2131,7 +2132,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) >> /* (You need to change the version number for e.g. kexec.) */ >> if ( gt->gt_version != 0 ) >> { >> - for ( i = 0; i < nr_grant_entries(gt); i++ ) >> + for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ ) > > The comment just prior says: > /* Make sure that the grant table isn''t currently in use when we > change the version number. */ > I think this needs updating to note that we do allow reserved entries to > be active during the switch over and we will correctly preserve > flags/status/mapped-ness etc.Right.>> { >> act = &active_entry(gt, i); >> if ( act->pin != 0 ) >> @@ -2156,15 +2157,50 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) >> goto out_unlock; >> } >> >> + /* Preserve the first 8 entries (toolstack reserved grants) */ >> + if (gt->gt_version == 1) > > Xen coding style has extra spaces just inside the braces (and again > below a few more times). > >> + { >> + memcpy(reserved_entries, gt->shared_v1[0], sizeof(reserved_entries)); > > Shouldn''t that be either "gt->shared_v1" or ">->shared_v1[0]" ? >No, [0] means this is copying from the first page; the first entry would be gt->shared_v1[0][0]. &shared_entry_v1(gt, 0) may be clearer here; I''ll use that.>> + } >> + else if (gt->gt_version == 2) >> + { >> + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES && i < nr_grant_entries(gt); i++ ) >> + { >> + reserved_entries[i].flags = shared_entry_v2(gt, i).hdr.flags; >> + reserved_entries[i].domid = shared_entry_v2(gt, i).hdr.domid; >> + reserved_entries[i].frame = shared_entry_v2(gt, i).full_page.frame; >> + reserved_entries[i].flags |= status_entry(gt, i); >> + if ((reserved_entries[i].flags & GTF_type_mask) > GTF_permit_access) > > In effect this only allows GTF_permit_access or GTF_invalid, which is > good. It would be more obvious/explicit to do > if ((shared_entry_v2(gt, i).hdr.flags & GTF_type_mask) != GTF_invalid && > (shared_entry_v2(gt, i).hdr.flags & GTF_type_mask) != GTF_permit_access) > memset-whole-entry and continue; > at the top or even a switch().In that case I think it would be clearer to only populate the entry if GTF_permit_access and clear it otherwise (warning if not already GTF_invalid).>> + { >> + gdprintk(XENLOG_INFO, "d%d: bad flags %x in grant %d when switching grant version\n", >> + d->domain_id, reserved_entries[i].flags, i); >> + reserved_entries[i].flags = GTF_invalid; >> + } >> + } >> + } >> + >> if ( op.version < 2 && gt->gt_version == 2 ) >> gnttab_unpopulate_status_frames(d, gt); >> >> - if ( op.version != gt->gt_version ) >> + /* Make sure there''s no crud left over in the table from the >> + old version. */ >> + for ( i = 0; i < nr_grant_frames(gt); i++ ) >> + memset(gt->shared_raw[i], 0, PAGE_SIZE); >> + >> + /* Restore the first 8 entries (toolstack reserved grants) */ >> + if (gt->gt_version != 0 && op.version == 1) >> { >> - /* Make sure there''s no crud left over in the table from the >> - old version. */ >> - for ( i = 0; i < nr_grant_frames(gt); i++ ) >> - memset(gt->shared_raw[i], 0, PAGE_SIZE); >> + memcpy(gt->shared_v1[0], reserved_entries, sizeof(reserved_entries)); >> + } >> + else if (gt->gt_version != 0 && op.version == 2) >> + { >> + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ ) >> + { >> + status_entry(gt, i) = reserved_entries[i].flags & (GTF_reading|GTF_writing); >> + shared_entry_v2(gt, i).hdr.flags = reserved_entries[i].flags & ~(GTF_reading|GTF_writing); >> + shared_entry_v2(gt, i).hdr.domid = reserved_entries[i].domid; >> + shared_entry_v2(gt, i).full_page.frame = reserved_entries[i].frame; >> + } >> } >> >> gt->gt_version = op.version; >> diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h >> index 54d9551..292d724 100644 >> --- a/xen/include/public/grant_table.h >> +++ b/xen/include/public/grant_table.h >> @@ -117,6 +117,13 @@ struct grant_entry_v1 { >> }; >> typedef struct grant_entry_v1 grant_entry_v1_t; >> >> +/* The first few grant table entries will be preserved across grant table >> + * version changes and may be pre-populated at domain creation by tools. >> + */ >> +#define GNTTAB_NR_RESERVED_ENTRIES 8 >> +#define GNTTAB_RESERVED_CONSOLE 0 >> +#define GNTTAB_RESERVED_XENSTORE 1 >> + >> /* >> * Type of grant entry. >> * GTF_invalid: This grant entry grants no privileges. >
Daniel De Graaf
2012-Jan-27 15:26 UTC
Re: [PATCH 10/24] mini-os: create app-specific configuration
On 01/27/2012 05:04 AM, Ian Campbell wrote:> On Thu, 2012-01-26 at 19:44 +0000, Daniel De Graaf wrote: >> Instead of using CONFIG_QEMU and CONFIG_GRUB to enable or disable minios >> code, create CONFIG_ items for features and use application-specific >> configuration files to enable or disable the features. >> >> The configuration flags are currently added to the compiler command >> line; as the number of flags grows this may need to move to a header. >> >> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> > > Acked-by: Ian Campbell <ian.campbell@citrix.com> > >> diff --git a/stubdom/c/minios.cfg b/stubdom/c/minios.cfg >> new file mode 100644 >> index 0000000..e69de29 >> diff --git a/stubdom/caml/minios.cfg b/stubdom/caml/minios.cfg >> new file mode 100644 >> index 0000000..e69de29 > > These are new empty files? That''s ok -- just wanted to check there > wasn''t some patch weirdness happening. > > Ian. > >Yes; the C and CAML stub domains just use the defaults.
Daniel De Graaf
2012-Jan-27 15:49 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
On 01/27/2012 08:06 AM, Ian Campbell wrote:> On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote: >> The symbol _LINUX_LIST_H collides with other header files. > > Hrm mini-os is supposed to have been BSD licensed since > 19712:7a215fae6f1f and that symbol name is *rather* suspicious. > > The thread associated with that commit[0] suggests that everything GPL > had been rewritten but I suspect that due to the lack of GPL header this > file was missed. > > This effectively means that any work combined with mini-os was GPL > rather than BSD as might reasonably have been expected. I believe > everything in-tree which we link with mini-os (the stubdom/ tree) is GPL > or GPL-compatible but this has laid rather a nasty trap for anyone else > using mini-os and I think we should fix it ASAP. Below is a patch which > switches to using the same BSD sys/queue.h list macros as we use in > libxl.I''m assuming you are going to push this patch in prior to my series, so I''ll try to rebase on top of it. Currently, the Makefile changes seem to be broken: make[3]: *** No rule to make target `/home/daniel/git/xen/tools/libxl/../../tools/include/xen-external/bsd-sys-queue-h-seddery'', needed by `_libxl_list.h''. Stop.> > Presumably you came across another file which used _LINUX_LIST_H which > clashed? Out of interest what was it? > > Ian.This symbol is used as the include guard in tools/xenstore/list.h.
Ian Campbell
2012-Jan-27 15:53 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
On Fri, 2012-01-27 at 15:49 +0000, Daniel De Graaf wrote:> On 01/27/2012 08:06 AM, Ian Campbell wrote: > > On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote: > >> The symbol _LINUX_LIST_H collides with other header files. > > > > Hrm mini-os is supposed to have been BSD licensed since > > 19712:7a215fae6f1f and that symbol name is *rather* suspicious. > > > > The thread associated with that commit[0] suggests that everything GPL > > had been rewritten but I suspect that due to the lack of GPL header this > > file was missed. > > > > This effectively means that any work combined with mini-os was GPL > > rather than BSD as might reasonably have been expected. I believe > > everything in-tree which we link with mini-os (the stubdom/ tree) is GPL > > or GPL-compatible but this has laid rather a nasty trap for anyone else > > using mini-os and I think we should fix it ASAP. Below is a patch which > > switches to using the same BSD sys/queue.h list macros as we use in > > libxl. > > I''m assuming you are going to push this patch in prior to my series, so I''ll > try to rebase on top of it. Currently, the Makefile changes seem to be broken: > > make[3]: *** No rule to make target `/home/daniel/git/xen/tools/libxl/../../tools/include/xen-external/bsd-sys-queue-h-seddery'', needed by `_libxl_list.h''. Stop.Did you use a version of patch which handles renames? Does tools/include/xen-external/... etc exist after you applied the patch?> > Presumably you came across another file which used _LINUX_LIST_H which > > clashed? Out of interest what was it? > > > > Ian. > > This symbol is used as the include guard in tools/xenstore/list.h.That thing is everywhere... At least xenstore is (L)GPL... Ian.
Daniel De Graaf
2012-Jan-27 16:11 UTC
Re: [PATCH 19/24] xenstored: support running in minios stubdom
On 01/27/2012 06:22 AM, Stefano Stabellini wrote:> On Thu, 26 Jan 2012, Daniel De Graaf wrote: >> A previous versions of this patch has been sent to xen-devel. See >> http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01655.html >> >> Signed-off-by: Diego Ongaro <diego.ongaro@citrix.com> >> Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com> >> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> > > The patch series is definitely going in the right direction. > > >> + >> .PHONY: all >> all: $(ALL_TARGETS) >> >> @@ -45,10 +49,13 @@ xenstored_probes.o: xenstored_solaris.o >> >> CFLAGS += -DHAVE_DTRACE=1 >> endif >> - >> + >> xenstored: $(XENSTORED_OBJS) >> $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) >> >> +xenstored.a: $(XENSTORED_OBJS) >> + $(AR) cr $@ $^ >> + >> $(CLIENTS): xenstore >> ln -f xenstore $@ >> >> diff --git a/tools/xenstore/utils.h b/tools/xenstore/utils.h >> index f378343..2effd17 100644 >> --- a/tools/xenstore/utils.h >> +++ b/tools/xenstore/utils.h >> @@ -19,7 +19,9 @@ static inline bool strends(const char *a, const char *b) >> return streq(a + strlen(a) - strlen(b), b); >> } >> >> +#ifndef ARRAY_SIZE >> #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) >> +#endif >> >> void barf(const char *fmt, ...) __attribute__((noreturn)); >> void barf_perror(const char *fmt, ...) __attribute__((noreturn)); >> diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c >> index 4b12cf2..0b9d4f2 100644 >> --- a/tools/xenstore/xenstored_core.c >> +++ b/tools/xenstore/xenstored_core.c >> @@ -224,7 +224,6 @@ static void reopen_log(void) >> } >> } >> >> - >> static bool write_messages(struct connection *conn) >> { >> int ret; >> @@ -327,7 +326,8 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, >> set_fd(sock, inset, &max); >> if (ro_sock != -1) >> set_fd(ro_sock, inset, &max); >> - set_fd(reopen_log_pipe[0], inset, &max); >> + if (reopen_log_pipe[0] != -1) >> + set_fd(reopen_log_pipe[0], inset, &max); >> >> if (xce_handle != NULL) >> set_fd(xc_evtchn_fd(xce_handle), inset, &max); >> @@ -1664,6 +1664,19 @@ static void corrupt(struct connection *conn, const char *fmt, ...) >> } >> >> >> +#ifdef __MINIOS__ >> +static void write_pidfile(const char *pidfile) >> +{ >> +} >> + >> +static void daemonize(void) >> +{ >> +} >> + >> +static void finish_daemonize(void) >> +{ >> +} >> +#else >> static void write_pidfile(const char *pidfile) >> { >> char buf[100]; >> @@ -1711,6 +1724,19 @@ static void daemonize(void) >> umask(0); >> } >> >> +static void finish_daemonize(void) >> +{ >> + int devnull = open("/dev/null", O_RDWR); >> + if (devnull == -1) >> + barf_perror("Could not open /dev/null\n"); >> + dup2(devnull, STDIN_FILENO); >> + dup2(devnull, STDOUT_FILENO); >> + dup2(devnull, STDERR_FILENO); >> + close(devnull); >> + xprintf = trace; >> +} >> +#endif >> + >> #ifdef NO_SOCKETS >> static void init_sockets(int **psock, int **pro_sock) >> { > > At this point we could have the MiniOS version of write_pidfile, > daemonize, finish_daemonize in tools/xenstore/xenstored_minios.c and the > Linux/NetBSD version of them in tools/xenstore/xenstored_linux.c. >Are you suggesting this for just these functions, or all functions that are different on minios? Since we already have xenstored_{linux,netbsd,solaris}.c, should the POSIX versions be duplicated or placed in a common POSIX file (as Ian suggested)?> >> --- >> tools/xenstore/Makefile | 9 ++++- >> tools/xenstore/utils.h | 2 + >> tools/xenstore/xenstored_core.c | 74 +++++++++++++++++++++++------------- >> tools/xenstore/xenstored_domain.c | 11 +++++ >> 4 files changed, 68 insertions(+), 28 deletions(-) >> >> diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile >> index 4facb62..be892fd 100644 >> --- a/tools/xenstore/Makefile >> +++ b/tools/xenstore/Makefile >> @@ -28,6 +28,10 @@ endif >> >> ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored >> >> +ifdef CONFIG_STUBDOM >> +CFLAGS += -DNO_SOCKETS=1 >> +endif > >> @@ -1822,6 +1848,11 @@ int main(int argc, char *argv[]) >> int evtchn_fd = -1; >> struct timeval *timeout; >> >> +#ifdef __MINIOS__ >> + /* minios always uses internal DB */ >> + tdb_flags = TDB_INTERNAL|TDB_NOLOCK; >> +#endif > > can you use the "internal-db" command line option? >Yes, but that begins to clutter up the xenstore stub domain''s command line with mandatory options (which seems self-contradictory).> >> while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, >> NULL)) != -1) { >> switch (opt) { >> @@ -1874,20 +1905,10 @@ int main(int argc, char *argv[]) >> >> reopen_log(); >> >> - /* make sure xenstored directory exists */ >> - if (mkdir(xs_daemon_rundir(), 0755)) { >> - if (errno != EEXIST) { >> - perror("error: mkdir daemon rundir"); >> - exit(-1); >> - } >> - } >> - >> - if (mkdir(xs_daemon_rootdir(), 0755)) { >> - if (errno != EEXIST) { >> - perror("error: mkdir daemon rootdir"); >> - exit(-1); >> - } >> - } >> + /* make sure xenstored directories exist */ >> + /* Errors ignored here, will be reported when we open files */ >> + mkdir(xs_daemon_rundir(), 0755); >> + mkdir(xs_daemon_rootdir(), 0755); >> >> if (dofork) { >> openlog("xenstored", 0, LOG_DAEMON); >> @@ -1905,9 +1926,14 @@ int main(int argc, char *argv[]) >> >> init_sockets(&sock, &ro_sock); >> >> +#ifdef __MINIOS__ >> + reopen_log_pipe[0] = -1; >> + reopen_log_pipe[1] = -1; >> +#else >> if (pipe(reopen_log_pipe)) { >> barf_perror("pipe"); >> } >> +#endif > > maybe we could have open/read/write_log_pipe functions?That would be useless here, since the pipe is only used to receive signals (which minios can''t do) in order to reopen a log file that minios doesn''t open.> >> /* Setup the database */ >> setup_structure(); >> @@ -1925,16 +1951,8 @@ int main(int argc, char *argv[]) >> } >> >> /* redirect to /dev/null now we''re ready to accept connections */ >> - if (dofork) { >> - int devnull = open("/dev/null", O_RDWR); >> - if (devnull == -1) >> - barf_perror("Could not open /dev/null\n"); >> - dup2(devnull, STDIN_FILENO); >> - dup2(devnull, STDOUT_FILENO); >> - dup2(devnull, STDERR_FILENO); >> - close(devnull); >> - xprintf = trace; >> - } >> + if (dofork) >> + finish_daemonize(); >> >> signal(SIGHUP, trigger_reopen_log); >> >> @@ -1944,8 +1962,10 @@ int main(int argc, char *argv[]) >> /* Get ready to listen to the tools. */ >> max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout); >> >> +#ifndef __MINIOS__ >> /* Tell the kernel we''re up and running. */ >> xenbus_notify_running(); >> +#endif >> >> /* Main loop. */ >> for (;;) { >> @@ -1957,7 +1977,7 @@ int main(int argc, char *argv[]) >> barf_perror("Select failed"); >> } >> >> - if (FD_ISSET(reopen_log_pipe[0], &inset)) { >> + if (reopen_log_pipe[0] != -1 && FD_ISSET(reopen_log_pipe[0], &inset)) { >> char c; >> if (read(reopen_log_pipe[0], &c, 1) != 1) >> barf_perror("read failed"); >> diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c >> index c521e52..4243f91 100644 >> --- a/tools/xenstore/xenstored_domain.c >> +++ b/tools/xenstore/xenstored_domain.c >> @@ -197,12 +197,16 @@ static int destroy_domain(void *_domain) >> } >> >> if (domain->interface) { >> +#ifdef __MINIOS__ >> + unmap_interface(domain->interface); >> +#else >> /* Domain 0 was mapped by dom0_init, so it must be unmapped >> using munmap() and not the grant unmap call. */ >> if (domain->domid == 0) >> munmap(domain->interface, getpagesize()); >> else >> unmap_interface(domain->interface); >> +#endif >> } >> >> fire_watches(NULL, "@releaseDomain", false); >> @@ -597,6 +601,12 @@ void restore_existing_connections(void) >> { >> } >> >> +#ifdef __MINIOS__ >> +static int dom0_init(void) >> +{ >> + return 0; >> +} >> +#else >> static int dom0_init(void) >> { >> evtchn_port_t port; >> @@ -620,6 +630,7 @@ static int dom0_init(void) >> >> return 0; >> } >> +#endif > > another candidate to be moved to xenstored_minios/linux >
Stefano Stabellini
2012-Jan-27 16:40 UTC
Re: [PATCH 19/24] xenstored: support running in minios stubdom
On Fri, 27 Jan 2012, Daniel De Graaf wrote:> >> @@ -1664,6 +1664,19 @@ static void corrupt(struct connection *conn, const char *fmt, ...) > >> } > >> > >> > >> +#ifdef __MINIOS__ > >> +static void write_pidfile(const char *pidfile) > >> +{ > >> +} > >> + > >> +static void daemonize(void) > >> +{ > >> +} > >> + > >> +static void finish_daemonize(void) > >> +{ > >> +} > >> +#else > >> static void write_pidfile(const char *pidfile) > >> { > >> char buf[100]; > >> @@ -1711,6 +1724,19 @@ static void daemonize(void) > >> umask(0); > >> } > >> > >> +static void finish_daemonize(void) > >> +{ > >> + int devnull = open("/dev/null", O_RDWR); > >> + if (devnull == -1) > >> + barf_perror("Could not open /dev/null\n"); > >> + dup2(devnull, STDIN_FILENO); > >> + dup2(devnull, STDOUT_FILENO); > >> + dup2(devnull, STDERR_FILENO); > >> + close(devnull); > >> + xprintf = trace; > >> +} > >> +#endif > >> + > >> #ifdef NO_SOCKETS > >> static void init_sockets(int **psock, int **pro_sock) > >> { > > > > At this point we could have the MiniOS version of write_pidfile, > > daemonize, finish_daemonize in tools/xenstore/xenstored_minios.c and the > > Linux/NetBSD version of them in tools/xenstore/xenstored_linux.c. > > > > Are you suggesting this for just these functions, or all functions that are > different on minios?All the functions that are different on minios and these three in particular.> Since we already have xenstored_{linux,netbsd,solaris}.c, should the POSIX > versions be duplicated or placed in a common POSIX file (as Ian suggested)?Better not duplicating code when possible, so I support Ian''s idea.> >> --- > >> tools/xenstore/Makefile | 9 ++++- > >> tools/xenstore/utils.h | 2 + > >> tools/xenstore/xenstored_core.c | 74 +++++++++++++++++++++++------------- > >> tools/xenstore/xenstored_domain.c | 11 +++++ > >> 4 files changed, 68 insertions(+), 28 deletions(-) > >> > >> diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile > >> index 4facb62..be892fd 100644 > >> --- a/tools/xenstore/Makefile > >> +++ b/tools/xenstore/Makefile > >> @@ -28,6 +28,10 @@ endif > >> > >> ALL_TARGETS = libxenstore.so libxenstore.a clients xs_tdb_dump xenstored > >> > >> +ifdef CONFIG_STUBDOM > >> +CFLAGS += -DNO_SOCKETS=1 > >> +endif > > > >> @@ -1822,6 +1848,11 @@ int main(int argc, char *argv[]) > >> int evtchn_fd = -1; > >> struct timeval *timeout; > >> > >> +#ifdef __MINIOS__ > >> + /* minios always uses internal DB */ > >> + tdb_flags = TDB_INTERNAL|TDB_NOLOCK; > >> +#endif > > > > can you use the "internal-db" command line option? > > > > Yes, but that begins to clutter up the xenstore stub domain''s command line > with mandatory options (which seems self-contradictory).I can see your point, but they are not mandatory per se: it is possible to have a fully working POSIX open/read/write interface implementation on top of Minios one day. For example the files could reside entirely in memory, a bit like tmpfs.> >> while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, > >> NULL)) != -1) { > >> switch (opt) { > >> @@ -1874,20 +1905,10 @@ int main(int argc, char *argv[]) > >> > >> reopen_log(); > >> > >> - /* make sure xenstored directory exists */ > >> - if (mkdir(xs_daemon_rundir(), 0755)) { > >> - if (errno != EEXIST) { > >> - perror("error: mkdir daemon rundir"); > >> - exit(-1); > >> - } > >> - } > >> - > >> - if (mkdir(xs_daemon_rootdir(), 0755)) { > >> - if (errno != EEXIST) { > >> - perror("error: mkdir daemon rootdir"); > >> - exit(-1); > >> - } > >> - } > >> + /* make sure xenstored directories exist */ > >> + /* Errors ignored here, will be reported when we open files */ > >> + mkdir(xs_daemon_rundir(), 0755); > >> + mkdir(xs_daemon_rootdir(), 0755); > >> > >> if (dofork) { > >> openlog("xenstored", 0, LOG_DAEMON); > >> @@ -1905,9 +1926,14 @@ int main(int argc, char *argv[]) > >> > >> init_sockets(&sock, &ro_sock); > >> > >> +#ifdef __MINIOS__ > >> + reopen_log_pipe[0] = -1; > >> + reopen_log_pipe[1] = -1; > >> +#else > >> if (pipe(reopen_log_pipe)) { > >> barf_perror("pipe"); > >> } > >> +#endif > > > > maybe we could have open/read/write_log_pipe functions? > > That would be useless here, since the pipe is only used to receive signals > (which minios can''t do) in order to reopen a log file that minios doesn''t open.In that case Minios'' implementaton would just be empty.
Keir Fraser
2012-Jan-28 13:52 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
On 27/01/2012 13:06, "Ian Campbell" <Ian.Campbell@citrix.com> wrote> On Thu, 2012-01-26 at 19:45 +0000, Daniel De Graaf wrote:> mini-os: use BSD sys/queue.h instead of Linux list.h >...> As well as the obvious ABI changes there are a few API updates > associated with the change: > > - struct rw_semaphore.wait_list is unused > - remove_waiter needs to take the wait_queue_head > > The latter requires a qemu update which I will post separately. Please > apply first and update QEMU_TAG as appropriate. > > I sprinkled some extra-emacs local variables around the files I edited > which didn''t have them. > > I think this should be backported to the stable branches since > external users of mini-os may have been mislead into thinking they > could safely link mini-os against GPL-incompatible code. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>Acked-by: Keir Fraser <keir@xen.org> Best applied by Ian Jackson, as it needs synchronising with a change in the linked qemu repo. -- Keir
Ian Jackson
2012-Jan-31 16:38 UTC
Re: [PATCH 13/24] mini-os: fix list.h include guard name
Ian Campbell writes ("Re: [Xen-devel] [PATCH 13/24] mini-os: fix list.h include guard name"):> mini-os: use BSD sys/queue.h instead of Linux list.hThanks, I have applied this one (with the related qemu patch and tag update). Ian.