[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Catch up to xen-unstable.hg tip
# HG changeset patch # User djm@xxxxxxxxxxxxxxx # Node ID c1a7ed266c7ee01b31f4908e6283539d014e5e54 # Parent 95f14bb8d22004bc11eb5bf61348c93c93f3c08e # Parent 215d8b2f3d94e3ad623cd219d4371cd04a84fb70 Catch up to xen-unstable.hg tip diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Sat Jul 9 13:54:10 2005 @@ -126,8 +126,8 @@ /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ extern int bind_virq_to_irq(int virq); extern void unbind_virq_from_irq(int virq); -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); +extern int bind_ipi_to_irq(int ipi); +extern void unbind_ipi_from_irq(int ipi); extern int bind_evtchn_to_irq(int evtchn); extern void unbind_evtchn_from_irq(int evtchn); diff -r 95f14bb8d220 -r c1a7ed266c7e Makefile --- a/Makefile Thu Jul 7 17:12:52 2005 +++ b/Makefile Sat Jul 9 13:54:10 2005 @@ -177,10 +177,10 @@ # Legacy targets for compatibility linux24: - $(MAKE) 'KERNELS=linux-2.4*' dist + $(MAKE) 'KERNELS=linux-2.4*' kernels linux26: - $(MAKE) 'KERNELS=linux-2.6*' dist + $(MAKE) 'KERNELS=linux-2.6*' kernels netbsd20: $(MAKE) netbsd-2.0-xenU-build diff -r 95f14bb8d220 -r c1a7ed266c7e xen/include/public/acm.h --- a/xen/include/public/acm.h Thu Jul 7 17:12:52 2005 +++ b/xen/include/public/acm.h Sat Jul 9 13:54:10 2005 @@ -1,157 +1,0 @@ -/**************************************************************** - * acm.h - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@xxxxxxxxxxxxxx> - * - * Contributors: - * Stefan Berger <stefanb@xxxxxxxxxxxxxx> - * added network byte order support for binary policies - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype general access control module header file. - * here are all definitions that are shared between - * xen-core, guest-kernels, and applications. - * - * todo: move from static policy choice to compile option. - */ - -#ifndef _XEN_PUBLIC_ACM_H -#define _XEN_PUBLIC_ACM_H - -#include "xen.h" -#include "sched_ctl.h" - -/* if ACM_DEBUG defined, all hooks should - * print a short trace message (comment it out - * when not in testing mode ) - */ -/* #define ACM_DEBUG */ - -#ifdef ACM_DEBUG -# define printkd(fmt, args...) printk(fmt,## args) -#else -# define printkd(fmt, args...) -#endif - -/* default ssid reference value if not supplied */ -#define ACM_DEFAULT_SSID 0x0 -#define ACM_DEFAULT_LOCAL_SSID 0x0 - -/* Internal ACM ERROR types */ -#define ACM_OK 0 -#define ACM_UNDEF -1 -#define ACM_INIT_SSID_ERROR -2 -#define ACM_INIT_SOID_ERROR -3 -#define ACM_ERROR -4 - -/* External ACCESS DECISIONS */ -#define ACM_ACCESS_PERMITTED 0 -#define ACM_ACCESS_DENIED -111 -#define ACM_NULL_POINTER_ERROR -200 - -#define ACM_MAX_POLICY 3 - -#define ACM_NULL_POLICY 0 -#define ACM_CHINESE_WALL_POLICY 1 -#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2 -#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3 - -/* policy: */ -#define ACM_POLICY_NAME(X) \ - (X == ACM_NULL_POLICY) ? "NULL policy" : \ - (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \ - (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT policy" : \ - (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \ - "UNDEFINED policy" - -/* defines a ssid reference used by xen */ -typedef u32 ssidref_t; - -/* -------security policy relevant type definitions-------- */ - -/* type identifier; compares to "equal" or "not equal" */ -typedef u16 domaintype_t; - -/* CHINESE WALL POLICY DATA STRUCTURES - * - * current accumulated conflict type set: - * When a domain is started and has a type that is in - * a conflict set, the conflicting types are incremented in - * the aggregate set. When a domain is destroyed, the - * conflicting types to its type are decremented. - * If a domain has multiple types, this procedure works over - * all those types. - * - * conflict_aggregate_set[i] holds the number of - * running domains that have a conflict with type i. - * - * running_types[i] holds the number of running domains - * that include type i in their ssidref-referenced type set - * - * conflict_sets[i][j] is "0" if type j has no conflict - * with type i and is "1" otherwise. - */ -/* high-16 = version, low-16 = check magic */ -#define ACM_MAGIC 0x0001debc - -/* each offset in bytes from start of the struct they - * the are part of */ -/* each buffer consists of all policy information for - * the respective policy given in the policy code - */ -struct acm_policy_buffer { - u32 magic; - u32 policyversion; - u32 len; - u16 primary_policy_code; - u16 primary_buffer_offset; - u16 secondary_policy_code; - u16 secondary_buffer_offset; -}; - -struct acm_chwall_policy_buffer { - u16 policy_code; - u16 chwall_max_types; - u16 chwall_max_ssidrefs; - u16 chwall_max_conflictsets; - u16 chwall_ssid_offset; - u16 chwall_conflict_sets_offset; - u16 chwall_running_types_offset; - u16 chwall_conflict_aggregate_offset; -}; - -struct acm_ste_policy_buffer { - u16 policy_code; - u16 ste_max_types; - u16 ste_max_ssidrefs; - u16 ste_ssid_offset; -}; - -struct acm_stats_buffer { - u32 magic; - u32 policyversion; - u32 len; - u16 primary_policy_code; - u16 primary_stats_offset; - u16 secondary_policy_code; - u16 secondary_stats_offset; -}; - -struct acm_ste_stats_buffer { - u32 ec_eval_count; - u32 gt_eval_count; - u32 ec_denied_count; - u32 gt_denied_count; - u32 ec_cachehit_count; - u32 gt_cachehit_count; -}; - - -#endif diff -r 95f14bb8d220 -r c1a7ed266c7e xen/common/event_channel.c --- a/xen/common/event_channel.c Thu Jul 7 17:12:52 2005 +++ b/xen/common/event_channel.c Sat Jul 9 13:54:10 2005 @@ -283,10 +283,7 @@ { struct evtchn *chn; struct domain *d = current->domain; - int port, ipi_vcpu = bind->ipi_vcpu; - - if ( (ipi_vcpu >= MAX_VIRT_CPUS) || (d->vcpu[ipi_vcpu] == NULL) ) - return -EINVAL; + int port; spin_lock(&d->evtchn_lock); @@ -294,7 +291,7 @@ { chn = evtchn_from_port(d, port); chn->state = ECS_IPI; - chn->notify_vcpu_id = ipi_vcpu; + chn->notify_vcpu_id = current->vcpu_id; } spin_unlock(&d->evtchn_lock); @@ -325,7 +322,7 @@ chn = evtchn_from_port(d, port); d->pirq_to_evtchn[pirq] = port; - rc = pirq_guest_bind(d->vcpu[chn->notify_vcpu_id], pirq, + rc = pirq_guest_bind(d->vcpu[0], pirq, !!(bind->flags & BIND_PIRQ__WILL_SHARE)); if ( rc != 0 ) { @@ -437,7 +434,9 @@ BUG(); } - chn1->state = ECS_FREE; + /* Reset binding to vcpu0 when the channel is freed. */ + chn1->state = ECS_FREE; + chn1->notify_vcpu_id = 0; out: if ( d2 != NULL ) @@ -566,12 +565,13 @@ status->u.virq = chn->u.virq; break; case ECS_IPI: - status->status = EVTCHNSTAT_ipi; - status->u.ipi_vcpu = chn->notify_vcpu_id; + status->status = EVTCHNSTAT_ipi; break; default: BUG(); } + + status->vcpu = chn->notify_vcpu_id; out: spin_unlock(&d->evtchn_lock); @@ -579,24 +579,41 @@ return rc; } -static long evtchn_rebind(evtchn_rebind_t *bind) +static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind) { struct domain *d = current->domain; int port = bind->port; int vcpu = bind->vcpu; struct evtchn *chn; - long rc = 0; + long rc = 0; + + if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) { + printf("vcpu %d bad.\n", vcpu); + return -EINVAL; + } spin_lock(&d->evtchn_lock); if ( !port_is_valid(d, port) ) { + printf("port %d bad.\n", port); rc = -EINVAL; goto out; } chn = evtchn_from_port(d, port); - chn->notify_vcpu_id = vcpu; + switch ( chn->state ) + { + case ECS_UNBOUND: + case ECS_INTERDOMAIN: + case ECS_PIRQ: + chn->notify_vcpu_id = vcpu; + break; + default: + printf("evtchn type %d can't be rebound.\n", chn->state); + rc = -EINVAL; + break; + } out: spin_unlock(&d->evtchn_lock); @@ -660,10 +677,8 @@ rc = -EFAULT; break; - case EVTCHNOP_rebind: - rc = evtchn_rebind(&op.u.rebind); - if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) ) - rc = -EFAULT; + case EVTCHNOP_bind_vcpu: + rc = evtchn_bind_vcpu(&op.u.bind_vcpu); break; default: diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/arch/xen/i386/kernel/irq.c --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/irq.c Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/irq.c Sat Jul 9 13:54:10 2005 @@ -274,7 +274,7 @@ } if (irq_desc[irq].handler->set_affinity) irq_desc[irq].handler->set_affinity(irq, mask); - else if (irq_desc[irq].action && !(warned++)) + else if (irq_desc[irq].action) printk("Cannot set affinity for irq %i\n", irq); } diff -r 95f14bb8d220 -r c1a7ed266c7e tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Thu Jul 7 17:12:52 2005 +++ b/tools/libxc/xc_domain.c Sat Jul 9 13:54:10 2005 @@ -123,6 +123,33 @@ if( !nr_doms ) return rc; return nr_doms; +} + +int xc_domain_getinfolist(int xc_handle, + u32 first_domain, + unsigned int max_domains, + xc_domaininfo_t *info) +{ + int ret = 0; + dom0_op_t op; + + if(mlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0) + return -1; + + op.cmd = DOM0_GETDOMAININFOLIST; + op.u.getdomaininfolist.first_domain = first_domain; + op.u.getdomaininfolist.max_domains = max_domains; + op.u.getdomaininfolist.buffer = info; + + if(xc_dom0_op(xc_handle, &op) < 0) + ret = -1; + else + ret = op.u.getdomaininfolist.num_domains; + + if(munlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0) + ret = -1; + + return ret; } int xc_domain_get_vcpu_context(int xc_handle, diff -r 95f14bb8d220 -r c1a7ed266c7e tools/libxc/xc.h --- a/tools/libxc/xc.h Thu Jul 7 17:12:52 2005 +++ b/tools/libxc/xc.h Sat Jul 9 13:54:10 2005 @@ -192,6 +192,24 @@ xc_dominfo_t *info); /** + * This function will return information about one or more domains, using a + * single hypercall. The domain information will be stored into the supplied + * array of xc_domaininfo_t structures. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm first_domain the first domain to enumerate information from. + * Domains are currently enumerate in order of creation. + * @parm max_domains the number of elements in info + * @parm info an array of max_doms size that will contain the information for + * the enumerated domains. + * @return the number of domains enumerated or -1 on error + */ +int xc_domain_getinfolist(int xc_handle, + u32 first_domain, + unsigned int max_domains, + xc_domaininfo_t *info); + +/** * This function returns information about one domain. This information is * more detailed than the information from xc_domain_getinfo(). * diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Sat Jul 9 13:54:10 2005 @@ -86,7 +86,7 @@ cpu_evtchn_mask[cpu][idx] & \ ~(sh)->evtchn_mask[idx]) -static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) { clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]); set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]); @@ -99,8 +99,9 @@ ((sh)->evtchn_pending[idx] & \ ~(sh)->evtchn_mask[idx]) -#define bind_evtchn_to_cpu(chn,cpu) ((void)0) - +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ +} #endif /* Upcall to generic IRQ layer. */ @@ -228,6 +229,13 @@ if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind virtual IRQ %d\n", virq); + /* This is a slight hack. Interdomain ports can be allocated + directly by userspace, and at that point they get bound by + Xen to vcpu 0. We therefore need to make sure that if we + get an event on an event channel we don't know about vcpu 0 + handles it. Binding channels to vcpu 0 when closing them + achieves this. */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; per_cpu(virq_to_irq, cpu)[virq] = -1; @@ -236,17 +244,17 @@ spin_unlock(&irq_mapping_update_lock); } -int bind_ipi_on_cpu_to_irq(int cpu, int ipi) +int bind_ipi_on_cpu_to_irq(int ipi) { evtchn_op_t op; int evtchn, irq; + int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 ) { - op.cmd = EVTCHNOP_bind_ipi; - op.u.bind_ipi.ipi_vcpu = cpu; + op.cmd = EVTCHNOP_bind_ipi; if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu); evtchn = op.u.bind_ipi.port; @@ -271,41 +279,10 @@ return irq; } -void rebind_evtchn_from_ipi(int cpu, int newcpu, int ipi) -{ - evtchn_op_t op; - int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; - - spin_lock(&irq_mapping_update_lock); - - op.cmd = EVTCHNOP_rebind; - op.u.rebind.port = evtchn; - op.u.rebind.vcpu = newcpu; - if ( HYPERVISOR_event_channel_op(&op) != 0 ) - printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu); - - spin_unlock(&irq_mapping_update_lock); -} - -void rebind_evtchn_from_irq(int cpu, int newcpu, int irq) -{ - evtchn_op_t op; - int evtchn = irq_to_evtchn[irq]; - - spin_lock(&irq_mapping_update_lock); - - op.cmd = EVTCHNOP_rebind; - op.u.rebind.port = evtchn; - op.u.rebind.vcpu = newcpu; - if ( HYPERVISOR_event_channel_op(&op) != 0 ) - printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu); - - spin_unlock(&irq_mapping_update_lock); -} - -void unbind_ipi_on_cpu_from_irq(int cpu, int ipi) -{ - evtchn_op_t op; +void unbind_ipi_from_irq(int ipi) +{ + evtchn_op_t op; + int cpu = smp_processor_id(); int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; int irq = irq_to_evtchn[evtchn]; @@ -319,6 +296,8 @@ if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind virtual IPI %d on cpu %d\n", ipi, cpu); + /* See comments in unbind_virq_from_irq */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; per_cpu(ipi_to_evtchn, cpu)[ipi] = 0; @@ -362,6 +341,59 @@ spin_unlock(&irq_mapping_update_lock); } +static void do_nothing_function(void *ign) +{ +} + +/* Rebind an evtchn so that it gets delivered to a specific cpu */ +static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu) +{ + evtchn_op_t op; + int evtchn; + + spin_lock(&irq_mapping_update_lock); + evtchn = irq_to_evtchn[irq]; + if (!VALID_EVTCHN(evtchn)) { + spin_unlock(&irq_mapping_update_lock); + return; + } + + /* Tell Xen to send future instances of this interrupt to the + other vcpu */ + op.cmd = EVTCHNOP_bind_vcpu; + op.u.bind_vcpu.port = evtchn; + op.u.bind_vcpu.vcpu = tcpu; + + /* If this fails, it usually just indicates that we're dealing + with a virq or IPI channel, which don't actually need to be + rebound. Ignore it, but don't do the xenlinux-level rebind + in that case. */ + if (HYPERVISOR_event_channel_op(&op) >= 0) + bind_evtchn_to_cpu(evtchn, tcpu); + + spin_unlock(&irq_mapping_update_lock); + + /* Now send the new target processor a NOP IPI. When this + returns, it will check for any pending interrupts, and so + service any that got delivered to the wrong processor by + mistake. */ + /* XXX: The only time this is called with interrupts disabled is + from the hotplug/hotunplug path. In that case, all cpus are + stopped with interrupts disabled, and the missed interrupts + will be picked up when they start again. This is kind of a + hack. + */ + if (!irqs_disabled()) { + smp_call_function(do_nothing_function, NULL, 0, 0); + } +} + + +static void set_affinity_irq(unsigned irq, cpumask_t dest) +{ + unsigned tcpu = first_cpu(dest); + rebind_irq_to_cpu(irq, tcpu); +} /* * Interface to generic handling in irq.c @@ -424,7 +456,7 @@ disable_dynirq, ack_dynirq, end_dynirq, - NULL + set_affinity_irq }; static inline void pirq_unmask_notify(int pirq) @@ -473,6 +505,7 @@ pirq_query_unmask(irq_to_pirq(irq)); + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = irq; irq_to_evtchn[irq] = evtchn; @@ -498,6 +531,7 @@ if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind physical IRQ %d\n", irq); + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; } @@ -548,7 +582,7 @@ disable_pirq, ack_pirq, end_pirq, - NULL + set_affinity_irq }; void irq_suspend(void) @@ -597,6 +631,7 @@ evtchn = op.u.bind_virq.port; /* Record the new mapping. */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = irq; irq_to_evtchn[irq] = evtchn; diff -r 95f14bb8d220 -r c1a7ed266c7e xen/include/public/io/domain_controller.h --- a/xen/include/public/io/domain_controller.h Thu Jul 7 17:12:52 2005 +++ b/xen/include/public/io/domain_controller.h Sat Jul 9 13:54:10 2005 @@ -577,11 +577,12 @@ } usbif_fe_interface_connect_t; /* - * CMSG_BLKIF_FE_INTERFACE_DISCONNECT: + * CMSG_USBIF_FE_INTERFACE_DISCONNECT: * If successful, the domain controller will acknowledge with a * STATUS_DISCONNECTED message. */ typedef struct usbif_fe_interface_disconnect { + int dummy; /* make struct non-empty */ } usbif_fe_interface_disconnect_t; diff -r 95f14bb8d220 -r c1a7ed266c7e xen/include/public/dom0_ops.h --- a/xen/include/public/dom0_ops.h Thu Jul 7 17:12:52 2005 +++ b/xen/include/public/dom0_ops.h Sat Jul 9 13:54:10 2005 @@ -19,7 +19,7 @@ * This makes sure that old versions of dom0 tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define DOM0_INTERFACE_VERSION 0xAAAA100C +#define DOM0_INTERFACE_VERSION 0xAAAA100E /************************************************************************/ @@ -356,6 +356,16 @@ vcpu_guest_context_t *ctxt; /* NB. IN/OUT variable. */ u64 cpu_time; } dom0_getvcpucontext_t; + +#define DOM0_GETDOMAININFOLIST 38 +typedef struct { + /* IN variables. */ + domid_t first_domain; + memory_t max_domains; + dom0_getdomaininfo_t *buffer; + /* OUT variables. */ + memory_t num_domains; +} dom0_getdomaininfolist_t; typedef struct { u32 cmd; @@ -389,6 +399,7 @@ dom0_microcode_t microcode; dom0_ioport_permission_t ioport_permission; dom0_getvcpucontext_t getvcpucontext; + dom0_getdomaininfolist_t getdomaininfolist; } u; } dom0_op_t; diff -r 95f14bb8d220 -r c1a7ed266c7e xen/common/dom0_ops.c --- a/xen/common/dom0_ops.c Thu Jul 7 17:12:52 2005 +++ b/xen/common/dom0_ops.c Sat Jul 9 13:54:10 2005 @@ -88,6 +88,60 @@ return err; } +static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) +{ + struct vcpu *v; + u64 cpu_time = 0; + int vcpu_count = 0; + int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED; + + info->domain = d->domain_id; + + memset(&info->vcpu_to_cpu, -1, sizeof(info->vcpu_to_cpu)); + memset(&info->cpumap, 0, sizeof(info->cpumap)); + + /* + * - domain is marked as paused or blocked only if all its vcpus + * are paused or blocked + * - domain is marked as running if any of its vcpus is running + * - only map vcpus that aren't down. Note, at some point we may + * wish to demux the -1 value to indicate down vs. not-ever-booted + * + */ + for_each_vcpu ( d, v ) { + /* only map vcpus that are up */ + if ( !(test_bit(_VCPUF_down, &v->vcpu_flags)) ) + info->vcpu_to_cpu[v->vcpu_id] = v->processor; + info->cpumap[v->vcpu_id] = v->cpumap; + if ( !(v->vcpu_flags & VCPUF_ctrl_pause) ) + flags &= ~DOMFLAGS_PAUSED; + if ( !(v->vcpu_flags & VCPUF_blocked) ) + flags &= ~DOMFLAGS_BLOCKED; + if ( v->vcpu_flags & VCPUF_running ) + flags |= DOMFLAGS_RUNNING; + if ( v->cpu_time > cpu_time ) + cpu_time += v->cpu_time; + vcpu_count++; + } + + info->cpu_time = cpu_time; + info->n_vcpu = vcpu_count; + + info->flags = flags | + ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | + ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | + d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; + + if (d->ssid != NULL) + info->ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref; + else + info->ssidref = ACM_DEFAULT_SSID; + + info->tot_pages = d->tot_pages; + info->max_pages = d->max_pages; + info->shared_info_frame = __pa(d->shared_info) >> PAGE_SHIFT; +} + long do_dom0_op(dom0_op_t *u_dom0_op) { long ret = 0; @@ -306,10 +360,6 @@ case DOM0_GETDOMAININFO: { struct domain *d; - struct vcpu *v; - u64 cpu_time = 0; - int vcpu_count = 0; - int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED; read_lock(&domlist_lock); @@ -328,59 +378,59 @@ read_unlock(&domlist_lock); - op->u.getdomaininfo.domain = d->domain_id; - - memset(&op->u.getdomaininfo.vcpu_to_cpu, -1, - sizeof(op->u.getdomaininfo.vcpu_to_cpu)); - memset(&op->u.getdomaininfo.cpumap, 0, - sizeof(op->u.getdomaininfo.cpumap)); - - /* - * - domain is marked as paused or blocked only if all its vcpus - * are paused or blocked - * - domain is marked as running if any of its vcpus is running - * - only map vcpus that aren't down. Note, at some point we may - * wish to demux the -1 value to indicate down vs. not-ever-booted - * - */ - for_each_vcpu ( d, v ) { - /* only map vcpus that are up */ - if ( !(test_bit(_VCPUF_down, &v->vcpu_flags)) ) - op->u.getdomaininfo.vcpu_to_cpu[v->vcpu_id] = v->processor; - op->u.getdomaininfo.cpumap[v->vcpu_id] = v->cpumap; - if ( !(v->vcpu_flags & VCPUF_ctrl_pause) ) - flags &= ~DOMFLAGS_PAUSED; - if ( !(v->vcpu_flags & VCPUF_blocked) ) - flags &= ~DOMFLAGS_BLOCKED; - if ( v->vcpu_flags & VCPUF_running ) - flags |= DOMFLAGS_RUNNING; - if ( v->cpu_time > cpu_time ) - cpu_time += v->cpu_time; - vcpu_count++; - } - - op->u.getdomaininfo.cpu_time = cpu_time; - op->u.getdomaininfo.n_vcpu = vcpu_count; - - op->u.getdomaininfo.flags = flags | - ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | - ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | - d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; - - if (d->ssid != NULL) - op->u.getdomaininfo.ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref; - else - op->u.getdomaininfo.ssidref = ACM_DEFAULT_SSID; - - op->u.getdomaininfo.tot_pages = d->tot_pages; - op->u.getdomaininfo.max_pages = d->max_pages; - op->u.getdomaininfo.shared_info_frame = - __pa(d->shared_info) >> PAGE_SHIFT; + getdomaininfo(d, &op->u.getdomaininfo); if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) ret = -EINVAL; put_domain(d); + } + break; + + case DOM0_GETDOMAININFOLIST: + { + struct domain *d; + dom0_getdomaininfo_t info; + dom0_getdomaininfo_t *buffer = op->u.getdomaininfolist.buffer; + u32 num_domains = 0; + + read_lock(&domlist_lock); + + for_each_domain ( d ) + { + if ( d->domain_id < op->u.getdomaininfolist.first_domain ) + continue; + if ( num_domains == op->u.getdomaininfolist.max_domains ) + break; + if ( (d == NULL) || !get_domain(d) ) + { + ret = -ESRCH; + break; + } + + getdomaininfo(d, &info); + + put_domain(d); + + if ( copy_to_user(buffer, &info, sizeof(dom0_getdomaininfo_t)) ) + { + ret = -EINVAL; + break; + } + + buffer++; + num_domains++; + } + + read_unlock(&domlist_lock); + + if ( ret != 0 ) + break; + + op->u.getdomaininfolist.num_domains = num_domains; + + if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) + ret = -EINVAL; } break; diff -r 95f14bb8d220 -r c1a7ed266c7e xen/include/acm/acm_core.h --- a/xen/include/acm/acm_core.h Thu Jul 7 17:12:52 2005 +++ b/xen/include/acm/acm_core.h Sat Jul 9 13:54:10 2005 @@ -20,6 +20,7 @@ #include <xen/spinlock.h> #include <public/acm.h> +#include <xen/acm_policy.h> #include <public/policy_ops.h> /* Xen-internal representation of the binary policy */ diff -r 95f14bb8d220 -r c1a7ed266c7e xen/include/public/event_channel.h --- a/xen/include/public/event_channel.h Thu Jul 7 17:12:52 2005 +++ b/xen/include/public/event_channel.h Sat Jul 9 13:54:10 2005 @@ -89,8 +89,6 @@ */ #define EVTCHNOP_bind_ipi 7 typedef struct evtchn_bind_ipi { - /* IN parameters. */ - u32 ipi_vcpu; /* OUT parameters. */ u32 port; } evtchn_bind_ipi_t; @@ -144,6 +142,7 @@ #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ u32 status; + u32 vcpu; /* VCPU to which this channel is bound. */ union { struct { domid_t dom; @@ -154,16 +153,25 @@ } interdomain; /* EVTCHNSTAT_interdomain */ u32 pirq; /* EVTCHNSTAT_pirq */ u32 virq; /* EVTCHNSTAT_virq */ - u32 ipi_vcpu; /* EVTCHNSTAT_ipi */ } u; } evtchn_status_t; -#define EVTCHNOP_rebind 8 -typedef struct { +/* + * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an + * event is pending. + * NOTES: + * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised + * the binding. This binding cannot be changed. + * 2. All other channels notify vcpu0 by default. This default is set when + * the channel is allocated (a port that is freed and subsequently reused + * has its binding reset to vcpu0). + */ +#define EVTCHNOP_bind_vcpu 8 +typedef struct evtchn_bind_vcpu { /* IN parameters. */ - u32 port; /* 0 */ - u32 vcpu; /* 4 */ -} evtchn_rebind_t; /* 8 bytes */ + u32 port; + u32 vcpu; +} evtchn_bind_vcpu_t; typedef struct evtchn_op { u32 cmd; /* EVTCHNOP_* */ @@ -176,7 +184,7 @@ evtchn_close_t close; evtchn_send_t send; evtchn_status_t status; - evtchn_rebind_t rebind; + evtchn_bind_vcpu_t bind_vcpu; } u; } evtchn_op_t; diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Sat Jul 9 13:54:10 2005 @@ -128,8 +128,8 @@ /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ extern int bind_virq_to_irq(int virq); extern void unbind_virq_from_irq(int virq); -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); +extern int bind_ipi_to_irq(int ipi); +extern void unbind_ipi_from_irq(int ipi); extern int bind_evtchn_to_irq(int evtchn); extern void unbind_evtchn_from_irq(int evtchn); diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Sat Jul 9 13:54:10 2005 @@ -1312,7 +1312,7 @@ /* hotplug down/up funtion pointer and target vcpu */ struct vcpu_hotplug_handler_t { - void (*fn)(); + void (*fn)(int vcpu); u32 vcpu; }; static struct vcpu_hotplug_handler_t vcpu_hotplug_handler; @@ -1333,11 +1333,8 @@ while (!cpu_online(cpu)) cpu_relax(); - /* re-route bound IRQs 0 to cpu */ - rebind_evtchn_from_irq(0, cpu, per_cpu(resched_irq, cpu)); - rebind_evtchn_from_irq(0, cpu, per_cpu(callfunc_irq, cpu)); - fixup_irqs(cpu_online_map); + /* counter the disable in fixup_irqs() */ local_irq_enable(); return 0; @@ -1359,17 +1356,8 @@ if (cpu == 0) return -EBUSY; - /* Allow any queued timer interrupts to get serviced */ - local_irq_enable(); - mdelay(1); - local_irq_disable(); - cpu_clear(cpu, map); fixup_irqs(map); - - /* re-route IRQs from dead vcpu to another */ - rebind_evtchn_from_irq(cpu, 0, per_cpu(resched_irq, cpu)); - rebind_evtchn_from_irq(cpu, 0, per_cpu(callfunc_irq, cpu)); /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); @@ -1533,13 +1521,13 @@ int cpu = smp_processor_id(); per_cpu(resched_irq, cpu) = - bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR); + bind_ipi_on_cpu_to_irq(RESCHEDULE_VECTOR); sprintf(resched_name[cpu], "resched%d", cpu); BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, SA_INTERRUPT, resched_name[cpu], NULL)); per_cpu(callfunc_irq, cpu) = - bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR); + bind_ipi_on_cpu_to_irq(CALL_FUNCTION_VECTOR); sprintf(callfunc_name[cpu], "callfunc%d", cpu); BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), smp_call_function_interrupt, diff -r 95f14bb8d220 -r c1a7ed266c7e linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c Thu Jul 7 17:12:52 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c Sat Jul 9 13:54:10 2005 @@ -491,6 +491,8 @@ * pick up its end of the event channel from */ evtchn_op_t op; + extern void bind_evtchn_to_cpu(unsigned port, unsigned cpu); + op.cmd = EVTCHNOP_bind_interdomain; op.u.bind_interdomain.dom1 = DOMID_SELF; op.u.bind_interdomain.dom2 = DOMID_SELF; @@ -500,6 +502,7 @@ BUG(); xen_start_info.domain_controller_evtchn = op.u.bind_interdomain.port1; initdom_ctrlif_domcontroller_port = op.u.bind_interdomain.port2; + bind_evtchn_to_cpu(op.u.bind_interdomain.port1, 0); } /* Sync up with shared indexes. */ diff -r 95f14bb8d220 -r c1a7ed266c7e xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Thu Jul 7 17:12:52 2005 +++ b/xen/arch/x86/traps.c Sat Jul 9 13:54:10 2005 @@ -94,6 +94,9 @@ DECLARE_TRAP_HANDLER(spurious_interrupt_bug); DECLARE_TRAP_HANDLER(machine_check); +long do_set_debugreg(int reg, unsigned long value); +unsigned long do_get_debugreg(int reg); + static int debug_stack_lines = 20; integer_param("debug_stack_lines", debug_stack_lines); @@ -568,8 +571,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) { struct vcpu *v = current; - unsigned long *reg, eip = regs->eip; - u8 opcode, modrm_reg = 0, rep_prefix = 0; + unsigned long *reg, eip = regs->eip, res; + u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0; unsigned int port, i, op_bytes = 4, data; /* Legacy prefixes. */ @@ -604,7 +607,9 @@ if ( (opcode & 0xf0) == 0x40 ) { modrm_reg = (opcode & 4) << 1; /* REX.R */ - /* REX.W, REX.B and REX.X do not need to be decoded. */ + modrm_rm = (opcode & 1) << 3; /* REX.B */ + + /* REX.W and REX.X do not need to be decoded. */ opcode = insn_fetch(u8, 1, eip); } #endif @@ -782,11 +787,10 @@ case 0x20: /* MOV CR?,<reg> */ opcode = insn_fetch(u8, 1, eip); - if ( (opcode & 0xc0) != 0xc0 ) - goto fail; - modrm_reg |= opcode & 7; - reg = decode_register(modrm_reg, regs, 0); - switch ( (opcode >> 3) & 7 ) + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + switch ( modrm_reg ) { case 0: /* Read CR0 */ *reg = v->arch.guest_context.ctrlreg[0]; @@ -805,13 +809,22 @@ } break; + case 0x21: /* MOV DR?,<reg> */ + opcode = insn_fetch(u8, 1, eip); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 ) + goto fail; + *reg = res; + break; + case 0x22: /* MOV <reg>,CR? */ opcode = insn_fetch(u8, 1, eip); - if ( (opcode & 0xc0) != 0xc0 ) - goto fail; - modrm_reg |= opcode & 7; - reg = decode_register(modrm_reg, regs, 0); - switch ( (opcode >> 3) & 7 ) + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + switch ( modrm_reg ) { case 0: /* Write CR0 */ (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS)); @@ -826,6 +839,15 @@ (void)new_guest_cr3(*reg); UNLOCK_BIGLOCK(v->domain); break; + + case 0x23: /* MOV <reg>,DR? */ + opcode = insn_fetch(u8, 1, eip); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + if ( do_set_debugreg(modrm_reg, *reg) != 0 ) + goto fail; + break; default: goto fail; diff -r 95f14bb8d220 -r c1a7ed266c7e tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Jul 7 17:12:52 2005 +++ b/tools/python/xen/lowlevel/xc/xc.c Sat Jul 9 13:54:10 2005 @@ -688,7 +688,7 @@ if ( xc_physinfo(xc->xc_handle, &info) != 0 ) return PyErr_SetFromErrno(xc_error); - return Py_BuildValue("{s:i,s:i,s:l,s:l,s:l}", + return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i}", "threads_per_core", info.threads_per_core, "cores_per_socket", info.cores_per_socket, "sockets_per_node", info.sockets_per_node, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |