WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Catch up to xen-unstable.hg tip, Xen patchbot -unstable <=