[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.