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] [xen-unstable] Merge

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge
From: Xen patchbot-unstable <patchbot@xxxxxxx>
Date: Thu, 16 Jun 2011 11:12:38 +0100
Delivery-date: Thu, 16 Jun 2011 03:30:09 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxx>
# Date 1307350197 -3600
# Node ID 68947fbeaa76728a14b800132ca3e000dbb519fd
# Parent  840e161428246f0173cb41c2409a0b9481b4a457
# Parent  0c0884fd8b494932a4b707e339cbe1b881d09103
Merge
---


diff -r 840e16142824 -r 68947fbeaa76 
tools/firmware/hvmloader/32bitbios_support.c
--- a/tools/firmware/hvmloader/32bitbios_support.c      Thu Jun 02 13:16:52 
2011 +0100
+++ b/tools/firmware/hvmloader/32bitbios_support.c      Mon Jun 06 09:49:57 
2011 +0100
@@ -67,7 +67,7 @@
      */
     reloc_size = reloc_off;
     printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
-    highbiosarea = mem_alloc(reloc_size, 0);
+    highbiosarea = mem_alloc(reloc_size, 1024);
     BUG_ON(highbiosarea == NULL);
     printf("  Relocating to 0x%x-0x%x ... ",
            (uint32_t)&highbiosarea[0],
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Mon Jun 06 09:49:57 2011 +0100
@@ -98,11 +98,6 @@
 };
 
 /*
- * The maximum number of entrys in RSDT or XSDT.
- */
-#define ACPI_MAX_NUM_TABLES 5
-
-/*
  * Root System Description Table (RSDT).
  */
 struct acpi_20_rsdt {
@@ -383,7 +378,6 @@
 #pragma pack ()
 
 void acpi_build_tables(unsigned int physical);
-extern uint32_t madt_csum_addr, madt_lapic0_addr;
 
 #endif /* _ACPI_2_0_H_ */
 
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/build.c     Mon Jun 06 09:49:57 2011 +0100
@@ -25,9 +25,6 @@
 #define align16(sz)        (((sz) + 15) & ~15)
 #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
 
-/* MADT parameters for filling in bios_info structure for DSDT. */
-uint32_t madt_csum_addr, madt_lapic0_addr;
-
 extern struct acpi_20_rsdp Rsdp;
 extern struct acpi_20_rsdt Rsdt;
 extern struct acpi_20_xsdt Xsdt;
@@ -35,6 +32,21 @@
 extern struct acpi_20_facs Facs;
 
 /*
+ * Located at ACPI_INFO_PHYSICAL_ADDRESS.
+ *
+ * This must match the Field("BIOS"....) definition in the DSDT.
+ */
+struct acpi_info {
+    uint8_t  com1_present:1;    /* 0[0] - System has COM1? */
+    uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
+    uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
+    uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
+    uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
+    uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
+    uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
+};
+
+/*
  * Alternative DSDTs we get linked against. A cover-all DSDT for up to the
  * implementation-defined maximum number of VCPUs, and an alternative for use
  * when a guest can only have up to 15 VCPUs.
@@ -68,12 +80,21 @@
     return (inb(0x88) == 0x1F);
 }
 
-static int construct_madt(struct acpi_20_madt *madt)
+static struct acpi_20_madt *construct_madt(struct acpi_info *info)
 {
+    struct acpi_20_madt           *madt;
     struct acpi_20_madt_intsrcovr *intsrcovr;
     struct acpi_20_madt_ioapic    *io_apic;
     struct acpi_20_madt_lapic     *lapic;
-    int i, offset = 0;
+    int i, sz;
+
+    sz  = sizeof(struct acpi_20_madt);
+    sz += sizeof(struct acpi_20_madt_intsrcovr) * 16;
+    sz += sizeof(struct acpi_20_madt_ioapic);
+    sz += sizeof(struct acpi_20_madt_lapic) * nr_processor_objects;
+
+    madt = mem_alloc(sz, 16);
+    if (!madt) return NULL;
 
     memset(madt, 0, sizeof(*madt));
     madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;
@@ -85,7 +106,6 @@
     madt->header.creator_revision = ACPI_CREATOR_REVISION;
     madt->lapic_addr = LAPIC_BASE_ADDRESS;
     madt->flags      = ACPI_PCAT_COMPAT;
-    offset += sizeof(*madt);
 
     intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
     for ( i = 0; i < 16; i++ )
@@ -113,7 +133,6 @@
             continue;
         }
 
-        offset += sizeof(*intsrcovr);
         intsrcovr++;
     }
 
@@ -123,10 +142,9 @@
     io_apic->length      = sizeof(*io_apic);
     io_apic->ioapic_id   = IOAPIC_ID;
     io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;
-    offset += sizeof(*io_apic);
 
     lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
-    madt_lapic0_addr = (uint32_t)lapic;
+    info->madt_lapic0_addr = (uint32_t)lapic;
     for ( i = 0; i < nr_processor_objects; i++ )
     {
         memset(lapic, 0, sizeof(*lapic));
@@ -138,20 +156,23 @@
         lapic->flags = ((i < hvm_info->nr_vcpus) &&
                         test_bit(i, hvm_info->vcpu_online)
                         ? ACPI_LOCAL_APIC_ENABLED : 0);
-        offset += sizeof(*lapic);
         lapic++;
     }
 
-    madt->header.length = offset;
-    set_checksum(madt, offsetof(struct acpi_header, checksum), offset);
-    madt_csum_addr = (uint32_t)&madt->header.checksum;
+    madt->header.length = (unsigned char *)lapic - (unsigned char *)madt;
+    set_checksum(madt, offsetof(struct acpi_header, checksum),
+                 madt->header.length);
+    info->madt_csum_addr = (uint32_t)&madt->header.checksum;
 
-    return align16(offset);
+    return madt;
 }
 
-static int construct_hpet(struct acpi_20_hpet *hpet)
+static struct acpi_20_hpet *construct_hpet(void)
 {
-    int offset;
+    struct acpi_20_hpet *hpet;
+
+    hpet = mem_alloc(sizeof(*hpet), 16);
+    if (!hpet) return NULL;
 
     memset(hpet, 0, sizeof(*hpet));
     hpet->header.signature    = ACPI_2_0_HPET_SIGNATURE;
@@ -163,20 +184,21 @@
     hpet->header.creator_revision = ACPI_CREATOR_REVISION;
     hpet->timer_block_id      = 0x8086a201;
     hpet->addr.address        = ACPI_HPET_ADDRESS;
-    offset = sizeof(*hpet);
 
-    hpet->header.length = offset;
-    set_checksum(hpet, offsetof(struct acpi_header, checksum), offset);
-
-    return offset;
+    hpet->header.length = sizeof(*hpet);
+    set_checksum(hpet, offsetof(struct acpi_header, checksum),
+                 hpet->header.length = sizeof(*hpet));
+    return hpet;
 }
 
-static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
+static int construct_secondary_tables(unsigned long *table_ptrs,
+                                      struct acpi_info *info)
 {
-    int offset = 0, nr_tables = 0;
+    int nr_tables = 0;
     struct acpi_20_madt *madt;
     struct acpi_20_hpet *hpet;
     struct acpi_20_tcpa *tcpa;
+    unsigned char *ssdt;
     static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
     uint16_t *tis_hdr;
     void *lasa;
@@ -184,22 +206,23 @@
     /* MADT. */
     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
     {
-        madt = (struct acpi_20_madt *)&buf[offset];
-        offset += construct_madt(madt);
+        madt = construct_madt(info);
+        if (!madt) return -1;
         table_ptrs[nr_tables++] = (unsigned long)madt;
     }
 
     /* HPET. Always included in DSDT, so always include it here too. */
     /* (And it's unconditionally required by Windows SVVP tests.) */
-    hpet = (struct acpi_20_hpet *)&buf[offset];
-    offset += construct_hpet(hpet);
+    hpet = construct_hpet();
+    if (!hpet) return -1;
     table_ptrs[nr_tables++] = (unsigned long)hpet;
 
-    if ( battery_port_exists() ) 
+    if ( battery_port_exists() )
     {
-        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-        memcpy(&buf[offset], ssdt_pm, sizeof(ssdt_pm));
-        offset += align16(sizeof(ssdt_pm));
+        ssdt = mem_alloc(sizeof(ssdt_pm), 16);
+        if (!ssdt) return -1;
+        memcpy(ssdt, ssdt_pm, sizeof(ssdt_pm));
+        table_ptrs[nr_tables++] = (unsigned long)ssdt;
     }
 
     /* TPM TCPA and SSDT. */
@@ -208,13 +231,14 @@
          (tis_hdr[1] == tis_signature[1]) &&
          (tis_hdr[2] == tis_signature[2]) )
     {
-        memcpy(&buf[offset], ssdt_tpm, sizeof(ssdt_tpm));
-        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-        offset += align16(sizeof(ssdt_tpm));
+        ssdt = mem_alloc(sizeof(ssdt_tpm), 16);
+        if (!ssdt) return -1;
+        memcpy(ssdt, ssdt_tpm, sizeof(ssdt_tpm));
+        table_ptrs[nr_tables++] = (unsigned long)ssdt;
 
-        tcpa = (struct acpi_20_tcpa *)&buf[offset];
+        tcpa = mem_alloc(sizeof(struct acpi_20_tcpa), 16);
+        if (!tcpa) return -1;
         memset(tcpa, 0, sizeof(*tcpa));
-        offset += align16(sizeof(*tcpa));
         table_ptrs[nr_tables++] = (unsigned long)tcpa;
 
         tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;
@@ -225,7 +249,7 @@
         tcpa->header.oem_revision = ACPI_OEM_REVISION;
         tcpa->header.creator_id   = ACPI_CREATOR_ID;
         tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
-        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 0)) != NULL )
+        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 16)) != NULL )
         {
             tcpa->lasa = virt_to_phys(lasa);
             tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;
@@ -237,13 +261,12 @@
     }
 
     table_ptrs[nr_tables] = 0;
-    return align16(offset);
+    return nr_tables;
 }
 
-static void __acpi_build_tables(unsigned int physical,
-                                uint8_t *buf,
-                                int *low_sz, int *high_sz)
+void acpi_build_tables(unsigned int physical)
 {
+    struct acpi_info *acpi_info = (struct acpi_info 
*)ACPI_INFO_PHYSICAL_ADDRESS;
     struct acpi_20_rsdp *rsdp;
     struct acpi_20_rsdt *rsdt;
     struct acpi_20_xsdt *xsdt;
@@ -252,27 +275,28 @@
     struct acpi_20_facs *facs;
     unsigned char       *dsdt;
     unsigned long        secondary_tables[16];
-    int                  offset = 0, i;
+    int                  nr_secondaries, i;
 
     /*
      * Fill in high-memory data structures, starting at @buf.
      */
 
-    facs = (struct acpi_20_facs *)&buf[offset];
+    facs = mem_alloc(sizeof(struct acpi_20_facs), 16);
+    if (!facs) goto oom;
     memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
-    offset += align16(sizeof(struct acpi_20_facs));
 
-    dsdt = (unsigned char *)&buf[offset];
     if ( hvm_info->nr_vcpus <= 15 )
     {
+        dsdt = mem_alloc(dsdt_15cpu_len, 16);
+        if (!dsdt) goto oom;
         memcpy(dsdt, &dsdt_15cpu, dsdt_15cpu_len);
-        offset += align16(dsdt_15cpu_len);
         nr_processor_objects = 15;
     }
     else
     {
+        dsdt = mem_alloc(dsdt_anycpu_len, 16);
+        if (!dsdt) goto oom;
         memcpy(dsdt, &dsdt_anycpu, dsdt_anycpu_len);
-        offset += align16(dsdt_anycpu_len);
         nr_processor_objects = HVM_MAX_VCPUS;
     }
 
@@ -284,9 +308,9 @@
      * compatible revision 1 FADT that is linked with the RSDT. Refer to:
      *     http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
      */
-    fadt_10 = (struct acpi_10_fadt *)&buf[offset];
+    fadt_10 = mem_alloc(sizeof(struct acpi_10_fadt), 16);
+    if (!fadt_10) goto oom;
     memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
-    offset += align16(sizeof(struct acpi_10_fadt));
     fadt_10->header.length = sizeof(struct acpi_10_fadt);
     fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
     fadt_10->dsdt          = (unsigned long)dsdt;
@@ -295,9 +319,9 @@
                  offsetof(struct acpi_header, checksum),
                  sizeof(struct acpi_10_fadt));
 
-    fadt = (struct acpi_20_fadt *)&buf[offset];
+    fadt = mem_alloc(sizeof(struct acpi_20_fadt), 16);
+    if (!fadt) goto oom;
     memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
-    offset += align16(sizeof(struct acpi_20_fadt));
     fadt->dsdt   = (unsigned long)dsdt;
     fadt->x_dsdt = (unsigned long)dsdt;
     fadt->firmware_ctrl   = (unsigned long)facs;
@@ -306,42 +330,42 @@
                  offsetof(struct acpi_header, checksum),
                  sizeof(struct acpi_20_fadt));
 
-    offset += construct_secondary_tables(&buf[offset], secondary_tables);
+    nr_secondaries = construct_secondary_tables(secondary_tables, acpi_info);
+    if ( nr_secondaries < 0 )
+        goto oom;
 
-    xsdt = (struct acpi_20_xsdt *)&buf[offset];
+    xsdt = mem_alloc(sizeof(struct acpi_20_xsdt)+
+                     sizeof(uint64_t)*nr_secondaries,
+                     16);
+    if (!xsdt) goto oom;
     memcpy(xsdt, &Xsdt, sizeof(struct acpi_header));
     xsdt->entry[0] = (unsigned long)fadt;
     for ( i = 0; secondary_tables[i]; i++ )
         xsdt->entry[i+1] = secondary_tables[i];
     xsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint64_t);
-    offset += align16(xsdt->header.length);
     set_checksum(xsdt,
                  offsetof(struct acpi_header, checksum),
                  xsdt->header.length);
 
-    rsdt = (struct acpi_20_rsdt *)&buf[offset];
+    rsdt = mem_alloc(sizeof(struct acpi_20_rsdt)+
+                     sizeof(uint32_t)*nr_secondaries,
+                     16);
+    if (!rsdt) goto oom;
     memcpy(rsdt, &Rsdt, sizeof(struct acpi_header));
     rsdt->entry[0] = (unsigned long)fadt_10;
     for ( i = 0; secondary_tables[i]; i++ )
         rsdt->entry[i+1] = secondary_tables[i];
     rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t);
-    offset += align16(rsdt->header.length);
     set_checksum(rsdt,
                  offsetof(struct acpi_header, checksum),
                  rsdt->header.length);
 
-    *high_sz = offset;
-
     /*
-     * Fill in low-memory data structures: bios_info_table and RSDP.
+     * Fill in low-memory data structures: acpi_info and RSDP.
      */
-    buf = (uint8_t *)physical;
-    offset = 0;
-
-    rsdp = (struct acpi_20_rsdp *)&buf[offset];
+    rsdp = (struct acpi_20_rsdp *)physical;
 
     memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
-    offset += align16(sizeof(struct acpi_20_rsdp));
     rsdp->rsdt_address = (unsigned long)rsdt;
     rsdp->xsdt_address = (unsigned long)xsdt;
     set_checksum(rsdp,
@@ -351,27 +375,19 @@
                  offsetof(struct acpi_20_rsdp, extended_checksum),
                  sizeof(struct acpi_20_rsdp));
 
-    *low_sz = offset;
-}
+    memset(acpi_info, 0, sizeof(*acpi_info));
+    acpi_info->com1_present = uart_exists(0x3f8);
+    acpi_info->com2_present = uart_exists(0x2f8);
+    acpi_info->lpt1_present = lpt_exists(0x378);
+    acpi_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
+    acpi_info->pci_min = pci_mem_start;
+    acpi_info->pci_len = pci_mem_end - pci_mem_start;
 
-void acpi_build_tables(unsigned int physical)
-{
-    int high_sz, low_sz;
-    uint8_t *buf;
+    return;
 
-    /* Find out size of high-memory ACPI data area. */
-    buf = (uint8_t *)&_end;
-    __acpi_build_tables(physical, buf, &low_sz, &high_sz);
-    memset(buf, 0, high_sz);
+oom:
+    printf("unable to build ACPI tables: out of memory\n");
 
-    /* Allocate data area and set up ACPI tables there. */
-    buf = mem_alloc(high_sz, 0);
-    __acpi_build_tables(physical, buf, &low_sz, &high_sz);
-
-    printf(" - Lo data: %08x-%08x\n"
-           " - Hi data: %08lx-%08lx\n",
-           physical, physical + low_sz - 1,
-           (unsigned long)buf, (unsigned long)buf + high_sz - 1);
 }
 
 /*
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl    Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl    Mon Jun 06 09:49:57 2011 +0100
@@ -61,8 +61,8 @@
 
     Scope (\_SB)
     {
-       /* BIOS_INFO_PHYSICAL_ADDRESS == 0xEA000 */
-       OperationRegion(BIOS, SystemMemory, 0xEA000, 24)
+       /* ACPI_INFO_PHYSICAL_ADDRESS == 0x9F000 */
+       OperationRegion(BIOS, SystemMemory, 0x9F000, 24)
        Field(BIOS, ByteAcc, NoLock, Preserve) {
            UAR1, 1,
            UAR2, 1,
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/config.h Mon Jun 06 09:49:57 2011 +0100
@@ -62,6 +62,7 @@
 /* Memory map. */
 #define SCRATCH_PHYSICAL_ADDRESS      0x00010000
 #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+#define ACPI_INFO_PHYSICAL_ADDRESS    0x0009F000
 #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
 #define HVMLOADER_PHYSICAL_ADDRESS    0x00100000
 
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/rombios.c
--- a/tools/firmware/hvmloader/rombios.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/rombios.c        Mon Jun 06 09:49:57 2011 +0100
@@ -67,36 +67,21 @@
 
 static void rombios_setup_bios_info(void)
 {
-    struct bios_info *bios_info;
+    struct rombios_info *info;
 
-    bios_info = (struct bios_info *)BIOS_INFO_PHYSICAL_ADDRESS;
-    memset(bios_info, 0, sizeof(*bios_info));
-    bios_info->com1_present = uart_exists(0x3f8);
-    bios_info->com2_present = uart_exists(0x2f8);
-    bios_info->lpt1_present = lpt_exists(0x378);
-    bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
-    bios_info->madt_csum_addr = madt_csum_addr;
-    bios_info->madt_lapic0_addr = madt_lapic0_addr;
+    info = (struct rombios_info *)BIOS_INFO_PHYSICAL_ADDRESS;
+    memset(info, 0, sizeof(*info));
 }
 
 static void rombios_relocate(void)
 {
     uint32_t bioshigh;
-    struct bios_info *bios_info;
+    struct rombios_info *info;
 
     bioshigh = rombios_highbios_setup();
 
-    bios_info = (struct bios_info *)BIOS_INFO_PHYSICAL_ADDRESS;
-    bios_info->bios32_entry = bioshigh;
-}
-
-static void rombios_finish_bios_info(void)
-{
-    struct bios_info *bios_info;
-
-    bios_info = (struct bios_info *)BIOS_INFO_PHYSICAL_ADDRESS;
-    bios_info->pci_min = pci_mem_start;
-    bios_info->pci_len = pci_mem_end - pci_mem_start;
+    info = (struct rombios_info *)BIOS_INFO_PHYSICAL_ADDRESS;
+    info->bios32_entry = bioshigh;
 }
 
 /*
@@ -177,7 +162,7 @@
     .optionrom_end = OPTIONROM_PHYSICAL_END,
 
     .bios_info_setup = rombios_setup_bios_info,
-    .bios_info_finish = rombios_finish_bios_info,
+    .bios_info_finish = NULL,
 
     .bios_relocate = rombios_relocate,
 
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/hvmloader/util.c   Mon Jun 06 09:49:57 2011 +0100
@@ -312,9 +312,9 @@
     xen_pfn_t mfn;
     uint32_t s, e;
 
-    /* Align to at least one kilobyte. */
-    if ( align < 1024 )
-        align = 1024;
+    /* Align to at least 16 bytes. */
+    if ( align < 16 )
+        align = 16;
 
     s = (reserve + align) & ~(align - 1);
     e = s + size - 1;
@@ -366,9 +366,9 @@
 {
     uint32_t s, e;
 
-    /* Align to at least one kilobyte. */
-    if ( align < 1024 )
-        align = 1024;
+    /* Align to at least 16 bytes. */
+    if ( align < 16 )
+        align = 16;
 
     s = (scratch_start + align - 1) & ~(align - 1);
     e = s + size - 1;
diff -r 840e16142824 -r 68947fbeaa76 tools/firmware/rombios/config.h
--- a/tools/firmware/rombios/config.h   Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/firmware/rombios/config.h   Mon Jun 06 09:49:57 2011 +0100
@@ -27,17 +27,10 @@
 #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
 
 /* Located at BIOS_INFO_PHYSICAL_ADDRESS. */
-struct bios_info {
-    uint8_t  com1_present:1;    /* 0[0] - System has COM1? */
-    uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
-    uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
-    uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
-    uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
-    uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
-    uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
-    uint32_t bios32_entry;      /* 20   - Entry point for 32-bit BIOS */
+struct rombios_info {
+    uint32_t bios32_entry;      /* 0   - Entry point for 32-bit BIOS */
 };
-#define BIOSINFO_OFF_bios32_entry 20
+#define BIOSINFO_OFF_bios32_entry 0
 
 #endif
 
diff -r 840e16142824 -r 68947fbeaa76 tools/hotplug/Linux/xen-hotplug-common.sh
--- a/tools/hotplug/Linux/xen-hotplug-common.sh Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/hotplug/Linux/xen-hotplug-common.sh Mon Jun 06 09:49:57 2011 +0100
@@ -106,7 +106,7 @@
 #
 call_hooks() {
   for f in /etc/xen/scripts/${1}-${2}.d/*.hook; do
-    [ -x "$f" ] && . "$f"
+    if [ -x "$f" ]; then . "$f"; fi
   done
 }
 
diff -r 840e16142824 -r 68947fbeaa76 tools/libxc/xc_cpufeature.h
--- a/tools/libxc/xc_cpufeature.h       Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxc/xc_cpufeature.h       Mon Jun 06 09:49:57 2011 +0100
@@ -17,128 +17,112 @@
 #ifndef __LIBXC_CPUFEATURE_H
 #define __LIBXC_CPUFEATURE_H
 
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
-#define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME                (0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE         (0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE        (0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC                (0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR                (0*32+ 5) /* Model-Specific Registers, 
RDMSR, WRMSR */
-#define X86_FEATURE_PAE                (0*32+ 6) /* Physical Address 
Extensions */
-#define X86_FEATURE_MCE                (0*32+ 7) /* Machine Check Architecture 
*/
-#define X86_FEATURE_CX8                (0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC       (0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP                (0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR       (0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE                (0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA                (0*32+14) /* Machine Check Architecture 
*/
-#define X86_FEATURE_CMOV       (0*32+15) /* CMOV instruction (FCMOVCC and 
FCOMI too if FPU present) */
-#define X86_FEATURE_PAT                (0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36      (0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN         (0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH     (0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS         (0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI       (0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX                (0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR       (0*32+24) /* FXSAVE and FXRSTOR instructions 
(fast save and restore */
-                                         /* of FPU context), and CR4.OSFXSR 
available */
-#define X86_FEATURE_XMM                (0*32+25) /* Streaming SIMD Extensions 
*/
-#define X86_FEATURE_XMM2       (0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP  (0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT         (0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC                (0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64       (0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE                (0*32+31) /* Pending Break Enable */
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx) */
+#define X86_FEATURE_FPU          0 /* Onboard FPU */
+#define X86_FEATURE_VME          1 /* Virtual Mode Extensions */
+#define X86_FEATURE_DE           2 /* Debugging Extensions */
+#define X86_FEATURE_PSE          3 /* Page Size Extensions */
+#define X86_FEATURE_TSC          4 /* Time Stamp Counter */
+#define X86_FEATURE_MSR          5 /* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE          6 /* Physical Address Extensions */
+#define X86_FEATURE_MCE          7 /* Machine Check Architecture */
+#define X86_FEATURE_CX8          8 /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC         9 /* Onboard APIC */
+#define X86_FEATURE_SEP         11 /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR        12 /* Memory Type Range Registers */
+#define X86_FEATURE_PGE         13 /* Page Global Enable */
+#define X86_FEATURE_MCA         14 /* Machine Check Architecture */
+#define X86_FEATURE_CMOV        15 /* CMOV instruction */
+#define X86_FEATURE_PAT         16 /* Page Attribute Table */
+#define X86_FEATURE_PSE36       17 /* 36-bit PSEs */
+#define X86_FEATURE_PN          18 /* Processor serial number */
+#define X86_FEATURE_CLFLSH      19 /* Supports the CLFLUSH instruction */
+#define X86_FEATURE_DS          21 /* Debug Store */
+#define X86_FEATURE_ACPI        22 /* ACPI via MSR */
+#define X86_FEATURE_MMX         23 /* Multimedia Extensions */
+#define X86_FEATURE_FXSR        24 /* FXSAVE and FXRSTOR instructions */
+#define X86_FEATURE_XMM         25 /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2        26 /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP   27 /* CPU self snoop */
+#define X86_FEATURE_HT          28 /* Hyper-Threading */
+#define X86_FEATURE_ACC         29 /* Automatic clock control */
+#define X86_FEATURE_IA64        30 /* IA-64 processor */
+#define X86_FEATURE_PBE         31 /* Pending Break Enable */
 
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* AMD-defined CPU features, CPUID level 0x80000001 */
 /* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP         (1*32+19) /* MP Capable. */
-#define X86_FEATURE_NX         (1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FFXSR       (1*32+25) /* FFXSR instruction optimizations */
-#define X86_FEATURE_PAGE1GB    (1*32+26) /* 1Gb large page support */
-#define X86_FEATURE_RDTSCP     (1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW      (1*32+31) /* 3DNow! */
+#define X86_FEATURE_SYSCALL     11 /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP          19 /* MP Capable. */
+#define X86_FEATURE_NX          20 /* Execute Disable */
+#define X86_FEATURE_MMXEXT      22 /* AMD MMX extensions */
+#define X86_FEATURE_FFXSR       25 /* FFXSR instruction optimizations */
+#define X86_FEATURE_PAGE1GB     26 /* 1Gb large page support */
+#define X86_FEATURE_RDTSCP      27 /* RDTSCP */
+#define X86_FEATURE_LM          29 /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT    30 /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW       31 /* 3DNow! */
 
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY   (2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN    (2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI       (2*32+ 3) /* LongRun table interface */
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx) */
+#define X86_FEATURE_XMM3         0 /* Streaming SIMD Extensions-3 */
+#define X86_FEATURE_PCLMULQDQ    1 /* Carry-less multiplication */
+#define X86_FEATURE_DTES64       2 /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT        3 /* Monitor/Mwait support */
+#define X86_FEATURE_DSCPL        4 /* CPL Qualified Debug Store */
+#define X86_FEATURE_VMXE         5 /* Virtual Machine Extensions */
+#define X86_FEATURE_SMXE         6 /* Safer Mode Extensions */
+#define X86_FEATURE_EST          7 /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2          8 /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3        9 /* Supplemental Streaming SIMD Exts-3 */
+#define X86_FEATURE_CID         10 /* Context ID */
+#define X86_FEATURE_CX16        13 /* CMPXCHG16B */
+#define X86_FEATURE_XTPR        14 /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM        15 /* Perf/Debug Capability MSR */
+#define X86_FEATURE_DCA         18 /* Direct Cache Access */
+#define X86_FEATURE_SSE4_1      19 /* Streaming SIMD Extensions 4.1 */
+#define X86_FEATURE_SSE4_2      20 /* Streaming SIMD Extensions 4.2 */
+#define X86_FEATURE_X2APIC      21 /* x2APIC */
+#define X86_FEATURE_POPCNT      23 /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE 24 /* "tdt" TSC Deadline Timer */
+#define X86_FEATURE_AES         25 /* AES acceleration instructions */
+#define X86_FEATURE_XSAVE       26 /* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_AVX         28 /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C        29 /* Half-precision convert instruction */
+#define X86_FEATURE_HYPERVISOR  31 /* Running under some hypervisor */
 
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX      (3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR    (3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR  (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR        (3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* cpu types for specific tunings: */
-#define X86_FEATURE_K8         (3*32+ 4) /* Opteron, Athlon64 */
-#define X86_FEATURE_K7         (3*32+ 5) /* Athlon */
-#define X86_FEATURE_P3         (3*32+ 6) /* P3 */
-#define X86_FEATURE_P4         (3*32+ 7) /* P4 */
-#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001 */
+#define X86_FEATURE_XSTORE       2 /* on-CPU RNG present (xstore insn) */
+#define X86_FEATURE_XSTORE_EN    3 /* on-CPU RNG enabled */
+#define X86_FEATURE_XCRYPT       6 /* on-CPU crypto (xcrypt insn) */
+#define X86_FEATURE_XCRYPT_EN    7 /* on-CPU crypto enabled */
+#define X86_FEATURE_ACE2         8 /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN      9 /* ACE v2 enabled */
+#define X86_FEATURE_PHE         10 /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN      11 /* PHE enabled */
+#define X86_FEATURE_PMM         12 /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN      13 /* PMM enabled */
 
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_PCLMULQDQ  (4*32+ 1) /* Carry-less multiplication */
-#define X86_FEATURE_DTES64     (4*32+ 2) /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT      (4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL      (4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_VMXE       (4*32+ 5) /* Virtual Machine Extensions */
-#define X86_FEATURE_SMXE       (4*32+ 6) /* Safer Mode Extensions */
-#define X86_FEATURE_EST                (4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2                (4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3      (4*32+ 9) /* Supplemental Streaming SIMD 
Extensions-3 */
-#define X86_FEATURE_CID                (4*32+10) /* Context ID */
-#define X86_FEATURE_CX16        (4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR       (4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM       (4*32+15) /* Perf/Debug Capability MSR */
-#define X86_FEATURE_DCA                (4*32+18) /* Direct Cache Access */
-#define X86_FEATURE_SSE4_1     (4*32+19) /* Streaming SIMD Extensions 4.1 */
-#define X86_FEATURE_SSE4_2     (4*32+20) /* Streaming SIMD Extensions 4.2 */
-#define X86_FEATURE_X2APIC      (4*32+21) /* x2APIC */
-#define X86_FEATURE_POPCNT     (4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE (4*32+24) /* "tdt" TSC Deadline Timer */
-#define X86_FEATURE_AES                (4*32+25) /* AES acceleration 
instructions */
-#define X86_FEATURE_XSAVE      (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_AVX                (4*32+28) /* Advanced Vector Extensions 
*/
-#define X86_FEATURE_F16C       (4*32+29) /* Half-precision convert instruction 
*/
-#define X86_FEATURE_HYPERVISOR (4*32+31) /* Running under some hypervisor */
+/* More extended AMD flags: CPUID level 0x80000001, ecx */
+#define X86_FEATURE_LAHF_LM      0 /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY   1 /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM          2 /* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC      3 /* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY   4 /* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM          5 /* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A        6 /* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE  7 /* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH 8 /* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW         9 /* OS Visible Workaround */
+#define X86_FEATURE_IBS         10 /* Instruction Based Sampling */
+#define X86_FEATURE_XOP         11 /* extended AVX instructions */
+#define X86_FEATURE_SKINIT      12 /* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT         13 /* Watchdog timer */
+#define X86_FEATURE_LWP         15 /* Light Weight Profiling */
+#define X86_FEATURE_FMA4        16 /* 4 operands MAC instructions */
+#define X86_FEATURE_NODEID_MSR  19 /* NodeId MSR */
+#define X86_FEATURE_TBM         21 /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT     22 /* topology extensions CPUID leafs */
 
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE     (5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN  (5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT     (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN  (5*32+ 7) /* on-CPU crypto enabled */
-#define X86_FEATURE_ACE2       (5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN    (5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE                (5*32+ 10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN     (5*32+ 11) /* PHE enabled */
-#define X86_FEATURE_PMM                (5*32+ 12) /* PadLock Montgomery 
Multiplier */
-#define X86_FEATURE_PMM_EN     (5*32+ 13) /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM     (6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY  (6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM         (6*32+ 2) /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC     (6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY  (6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM         (6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A       (6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE (6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW        (6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS         (6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP         (6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT      (6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT         (6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP         (6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4        (6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_NODEID_MSR  (6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM         (6*32+21) /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT     (6*32+22) /* topology extensions CPUID leafs */
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
+#define X86_FEATURE_FSGSBASE     0 /* {RD,WR}{FS,GS}BASE instructions */
 
 #endif /* __LIBXC_CPUFEATURE_H */
diff -r 840e16142824 -r 68947fbeaa76 tools/libxc/xc_cpuid_x86.c
--- a/tools/libxc/xc_cpuid_x86.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxc/xc_cpuid_x86.c        Mon Jun 06 09:49:57 2011 +0100
@@ -25,9 +25,9 @@
 #include "xc_cpufeature.h"
 #include <xen/hvm/params.h>
 
-#define bitmaskof(idx)      (1u << ((idx) & 31))
-#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31)))
-#define set_bit(idx, dst)   ((dst) |= (1u << ((idx) & 31)))
+#define bitmaskof(idx)      (1u << (idx))
+#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx)))
+#define set_bit(idx, dst)   ((dst) |= (1u << (idx)))
 
 #define DEF_MAX_BASE 0x0000000du
 #define DEF_MAX_INTELEXT  0x80000008u
@@ -466,6 +466,14 @@
         set_bit(X86_FEATURE_HYPERVISOR, regs[2]);
         break;
 
+    case 7:
+        if ( input[1] == 0 )
+            regs[1] &= bitmaskof(X86_FEATURE_FSGSBASE);
+        else
+            regs[1] = 0;
+        regs[0] = regs[2] = regs[3] = 0;
+        break;
+
     case 0x0000000d:
         xc_cpuid_config_xsave(xch, domid, xfeature_mask, input, regs);
         break;
@@ -612,7 +620,7 @@
             input[0] = 0x80000000u;
 
         input[1] = XEN_CPUID_INPUT_UNUSED;
-        if ( (input[0] == 4) || (input[0] == 0xd) )
+        if ( (input[0] == 4) || (input[0] == 7) || (input[0] == 0xd) )
             input[1] = 0;
 
         if ( (input[0] & 0x80000000u) && (input[0] > ext_max) )
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/Makefile
--- a/tools/libxl/Makefile      Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/Makefile      Mon Jun 06 09:49:57 2011 +0100
@@ -35,7 +35,7 @@
 LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
                        libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
                        libxl_internal.o libxl_utils.o libxl_uuid.o 
$(LIBXL_OBJS-y)
-LIBXL_OBJS += _libxl_types.o
+LIBXL_OBJS += _libxl_types.o libxl_flask.o
 
 $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) 
$(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
 
@@ -69,7 +69,7 @@
 
 _libxl_paths.h: genpath
        sed -e "s/\([^=]*\)=\(.*\)/#define \1 \2/g" $@.tmp >$@.2.tmp
-       if ! cmp $@.2.tmp $@; then mv -f $@.2.tmp $@; fi
+       if ! cmp -s $@.2.tmp $@; then mv -f $@.2.tmp $@; fi
 
 libxl_paths.c: _libxl_paths.h
 
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl.c       Mon Jun 06 09:49:57 2011 +0100
@@ -38,8 +38,6 @@
 
 #define PAGE_TO_MEMKB(pages) ((pages) * 4)
 #define BACKEND_STRING_SIZE 5
-#define STRINGIFY(x) #x
-#define TOSTRING(x) STRINGIFY(x)
 
 int libxl_ctx_alloc(libxl_ctx **pctx, int version, xentoollog_logger * lg)
 {
@@ -87,6 +85,7 @@
 
 int libxl_ctx_free(libxl_ctx *ctx)
 {
+    if (!ctx) return 0;
     if (ctx->xch) xc_interface_close(ctx->xch);
     libxl_version_info_destroy(&ctx->version_info);
     if (ctx->xsh) xs_daemon_close(ctx->xsh); 
@@ -342,6 +341,7 @@
 {
     memcpy(&(xlinfo->uuid), xcinfo->handle, sizeof(xen_domain_handle_t));
     xlinfo->domid = xcinfo->domain;
+    xlinfo->ssidref = xcinfo->ssidref;
 
     xlinfo->dying    = !!(xcinfo->flags&XEN_DOMINF_dying);
     xlinfo->shutdown = !!(xcinfo->flags&XEN_DOMINF_shutdown);
@@ -707,7 +707,7 @@
     disk->format = LIBXL_DISK_FORMAT_EMPTY;
     /* this value is returned to the user: do not free right away */
     disk->vdev = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "%s/dev", 
backend), NULL);
-    disk->unpluggable = 1;
+    disk->removable = 1;
     disk->readwrite = 0;
     disk->is_cdrom = 1;
 
@@ -970,6 +970,13 @@
         goto out_free;
     }
 
+    if (disk->script) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "External block scripts"
+                   " not yet supported, sorry");
+        rc = ERROR_INVAL;
+        goto out_free;
+    }
+
     devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
     if (devid==-1) {
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid or unsupported"
@@ -1040,7 +1047,7 @@
     flexarray_append(back, "online");
     flexarray_append(back, "1");
     flexarray_append(back, "removable");
-    flexarray_append(back, libxl__sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 
0));
+    flexarray_append(back, libxl__sprintf(&gc, "%d", (disk->removable) ? 1 : 
0));
     flexarray_append(back, "bootable");
     flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
     flexarray_append(back, "state");
@@ -1583,7 +1590,7 @@
                 libxl__sprintf(gc, "%s/%s/type", be_path, *dir)), 
                 &(pdisk->backend));
             pdisk->vdev = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(gc, 
"%s/%s/dev", be_path, *dir), &len);
-            pdisk->unpluggable = atoi(libxl__xs_read(gc, XBT_NULL, 
libxl__sprintf(gc, "%s/%s/removable", be_path, *dir)));
+            pdisk->removable = atoi(libxl__xs_read(gc, XBT_NULL, 
libxl__sprintf(gc, "%s/%s/removable", be_path, *dir)));
             if (!strcmp(libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, 
"%s/%s/mode", be_path, *dir)), "w"))
                 pdisk->readwrite = 1;
             else
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl.h       Mon Jun 06 09:49:57 2011 +0100
@@ -232,7 +232,7 @@
 
 /* context functions */
 int libxl_ctx_alloc(libxl_ctx **pctx, int version, xentoollog_logger *lg);
-int libxl_ctx_free(libxl_ctx *ctx);
+int libxl_ctx_free(libxl_ctx *ctx /* 0 is OK */);
 int libxl_ctx_postfork(libxl_ctx *ctx);
 
 /* domain related functions */
@@ -499,6 +499,14 @@
     return domid > 0 && domid < DOMID_FIRST_RESERVED;
 }
 
+int libxl_flask_context_to_sid(libxl_ctx *ctx, char *buf, size_t len,
+                               uint32_t *ssidref);
+int libxl_flask_sid_to_context(libxl_ctx *ctx, uint32_t ssidref, char **buf, 
+                               size_t *len);
+int libxl_flask_getenforce(libxl_ctx *ctx);
+int libxl_flask_setenforce(libxl_ctx *ctx, int mode);
+int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
+
 /* common paths */
 const char *libxl_sbindir_path(void);
 const char *libxl_bindir_path(void);
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl     Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl.idl     Mon Jun 06 09:49:57 2011 +0100
@@ -89,6 +89,7 @@
 libxl_dominfo = Struct("dominfo",[
     ("uuid",        libxl_uuid),
     ("domid",       libxl_domid),
+    ("ssidref",      uint32),
     ("running",     bool),
     ("blocked",     bool),
     ("paused",      bool),
@@ -138,7 +139,7 @@
     ("hvm",          bool),
     ("hap",          bool),
     ("oos",          bool),
-    ("ssidref",      integer),
+    ("ssidref",      uint32),
     ("name",         string),
     ("uuid",         libxl_uuid),
     ("xsdata",       libxl_key_value_list),
@@ -278,7 +279,8 @@
     ("vdev", string),
     ("backend", libxl_disk_backend),
     ("format", libxl_disk_format),
-    ("unpluggable", integer),
+    ("script", string),
+    ("removable", integer),
     ("readwrite", integer),
     ("is_cdrom", integer),
     ])
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl_device.c        Mon Jun 06 09:49:57 2011 +0100
@@ -485,7 +485,9 @@
             }
             if (starting && FD_ISSET(starting->for_spawn->fd, &rfds)) {
                 unsigned char dummy;
-                read(starting->for_spawn->fd, &dummy, sizeof(dummy));
+                if (read(starting->for_spawn->fd, &dummy, sizeof(dummy)) != 1)
+                    LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG,
+                                     "failed to read spawn status pipe");
             }
         }
     }
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c  Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl_exec.c  Mon Jun 06 09:49:57 2011 +0100
@@ -45,7 +45,7 @@
     env_debug = getenv("_LIBXL_DEBUG_EXEC_FDS");
     if (!env_debug) return;
 
-    debug = strtol(env_debug, (char **) NULL, 10);atoi(env_debug);
+    debug = strtol(env_debug, (char **) NULL, 10);
     if (debug <= 0) return;
 
     for (i = 4; i < 256; i++) {
@@ -220,8 +220,10 @@
     rc = (WIFEXITED(status) ? WEXITSTATUS(status) :
           WIFSIGNALED(status) && WTERMSIG(status) < 127
           ? WTERMSIG(status)+128 : -1);
-    if (for_spawn)
-        write(pipes[1], &dummy, sizeof(dummy));
+    if (for_spawn) {
+        if (write(pipes[1], &dummy, sizeof(dummy)) != 1)
+            perror("libxl__spawn_spawn: unable to signal child exit to 
parent");
+    }
     _exit(rc);
 
  err_parent_pipes:
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_flask.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_flask.c Mon Jun 06 09:49:57 2011 +0100
@@ -0,0 +1,71 @@
+/*
+ *
+ *  Author: Machon Gregory, <mbgrego@xxxxxxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2,
+ *  as published by the Free Software Foundation.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <xenctrl.h>
+
+#include "libxl.h"
+#include "libxl_internal.h"
+
+int libxl_flask_context_to_sid(libxl_ctx *ctx, char *buf, size_t len,
+                               uint32_t *ssidref)
+{
+    int rc;
+
+    rc = xc_flask_context_to_sid(ctx->xch, buf, len, ssidref);
+   
+    return rc;
+}
+
+int libxl_flask_sid_to_context(libxl_ctx *ctx, uint32_t ssidref, 
+                               char **buf, size_t *len)
+{
+    int rc;
+    char tmp[XC_PAGE_SIZE];
+
+    rc = xc_flask_sid_to_context(ctx->xch, ssidref, tmp, sizeof(tmp));
+                                    
+    if (!rc) {
+        *len = strlen(tmp);
+        *buf = strdup(tmp); 
+    }
+     
+    return rc;
+}
+
+int libxl_flask_getenforce(libxl_ctx *ctx)
+{
+    int rc;
+
+    rc = xc_flask_getenforce(ctx->xch);
+
+    return rc; 
+}
+
+int libxl_flask_setenforce(libxl_ctx *ctx, int mode)
+{
+    int rc;
+
+    rc = xc_flask_setenforce(ctx->xch, mode);
+
+    return rc;
+}
+
+int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size)
+{
+
+    int rc;
+
+    rc = xc_flask_load(ctx->xch, policy, size);
+
+    return rc;
+}
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl_internal.h      Mon Jun 06 09:49:57 2011 +0100
@@ -370,4 +370,8 @@
 _hidden int libxl__file_reference_unmap(libxl_file_reference *f);
 
 _hidden int libxl__e820_alloc(libxl_ctx *ctx, uint32_t domid, 
libxl_domain_config *d_config);
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+
 #endif
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl_pci.c   Mon Jun 06 09:49:57 2011 +0100
@@ -48,7 +48,7 @@
     value = 0;
     value |= (pcidev->bus & 0xff) << 16;
     value |= (pcidev->dev & 0x1f) << (8+3);
-    value |= (pcidev->func & 0x3) << (8+0);
+    value |= (pcidev->func & 0x7) << (8+0);
 
     return value;
 }
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxl_utils.c Mon Jun 06 09:49:57 2011 +0100
@@ -556,7 +556,7 @@
     libxl_string_to_backend(ctx, val, &(disk->backend));
     disk->vdev = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/dev", 
be_path));
     val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/removable", 
be_path));
-    disk->unpluggable = !strcmp(val, "1");
+    disk->removable = !strcmp(val, "1");
     val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mode", 
be_path));
     disk->readwrite = !!strcmp(val, "w");
     val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/device-type", 
diskpath));
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg.c
--- a/tools/libxl/libxlu_cfg.c  Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg.c  Mon Jun 06 09:49:57 2011 +0100
@@ -1,3 +1,21 @@
+/*
+ * libxlu_cfg.c - xl configuration file parsing: setup and helper functions
+ *
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+
 #include <limits.h>
 
 #include "libxlu_internal.h"
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_i.h
--- a/tools/libxl/libxlu_cfg_i.h        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_i.h        Mon Jun 06 09:49:57 2011 +0100
@@ -1,3 +1,20 @@
+/*
+ * libxlu_cfg_i.h - xl configuration file parsing: parser-internal declarations
+ *
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
 #ifndef LIBXLU_CFG_I_H
 #define LIBXLU_CFG_I_H
 
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_l.c
--- a/tools/libxl/libxlu_cfg_l.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_l.c        Mon Jun 06 09:49:57 2011 +0100
@@ -479,7 +479,23 @@
 #define YY_RESTORE_YY_MORE_OFFSET
 #line 1 "libxlu_cfg_l.l"
 /* -*- fundamental -*- */
-#line 4 "libxlu_cfg_l.l"
+/*
+ * libxlu_cfg_l.l - xl configuration file parsing: lexer
+ *
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+#line 20 "libxlu_cfg_l.l"
 #include "libxlu_cfg_i.h"
 
 #define ctx ((CfgParseContext*)yyextra)
@@ -498,7 +514,7 @@
 void xlu__cfg_yyset_column(int  column_no, yyscan_t yyscanner);
 
 
-#line 502 "libxlu_cfg_l.c"
+#line 518 "libxlu_cfg_l.c"
 
 #define INITIAL 0
 #define lexerr 1
@@ -743,10 +759,10 @@
        register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 37 "libxlu_cfg_l.l"
+#line 53 "libxlu_cfg_l.l"
 
 
-#line 750 "libxlu_cfg_l.c"
+#line 766 "libxlu_cfg_l.c"
 
     yylval = yylval_param;
 
@@ -849,7 +865,7 @@
 
 case 1:
 YY_RULE_SETUP
-#line 39 "libxlu_cfg_l.l"
+#line 55 "libxlu_cfg_l.l"
 {
                           yylval->string= xlu__cfgl_strdup(ctx,yytext);
                           GOT(IDENT);
@@ -857,7 +873,7 @@
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 43 "libxlu_cfg_l.l"
+#line 59 "libxlu_cfg_l.l"
 {
                           yylval->string= xlu__cfgl_strdup(ctx,yytext);
                           GOT(NUMBER);
@@ -865,43 +881,43 @@
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 48 "libxlu_cfg_l.l"
+#line 64 "libxlu_cfg_l.l"
 
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 50 "libxlu_cfg_l.l"
+#line 66 "libxlu_cfg_l.l"
 { GOT(','); }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 51 "libxlu_cfg_l.l"
+#line 67 "libxlu_cfg_l.l"
 { GOT('['); }
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 52 "libxlu_cfg_l.l"
+#line 68 "libxlu_cfg_l.l"
 { GOT(']'); }
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 53 "libxlu_cfg_l.l"
+#line 69 "libxlu_cfg_l.l"
 { GOT('='); }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 54 "libxlu_cfg_l.l"
+#line 70 "libxlu_cfg_l.l"
 { GOT(';'); }
        YY_BREAK
 case 9:
 /* rule 9 can match eol */
 YY_RULE_SETUP
-#line 56 "libxlu_cfg_l.l"
+#line 72 "libxlu_cfg_l.l"
 { yylloc->first_line= yylineno-1; return NEWLINE; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 58 "libxlu_cfg_l.l"
+#line 74 "libxlu_cfg_l.l"
 {
                           yylval->string= xlu__cfgl_dequote(ctx,yytext);
                           GOT(STRING);
@@ -909,7 +925,7 @@
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 62 "libxlu_cfg_l.l"
+#line 78 "libxlu_cfg_l.l"
 {
                           yylval->string= xlu__cfgl_dequote(ctx,yytext);
                           GOT(STRING);
@@ -917,7 +933,7 @@
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 67 "libxlu_cfg_l.l"
+#line 83 "libxlu_cfg_l.l"
 {
                           ctx->likely_python= 1;
                           BEGIN(lexerr);
@@ -926,7 +942,7 @@
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 73 "libxlu_cfg_l.l"
+#line 89 "libxlu_cfg_l.l"
 {
                           BEGIN(lexerr);
                           yymore();
@@ -934,7 +950,7 @@
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 78 "libxlu_cfg_l.l"
+#line 94 "libxlu_cfg_l.l"
 {
                           xlu__cfgl_lexicalerror(ctx,"lexical error");
                           BEGIN(0);
@@ -943,7 +959,7 @@
 case 15:
 /* rule 15 can match eol */
 YY_RULE_SETUP
-#line 83 "libxlu_cfg_l.l"
+#line 99 "libxlu_cfg_l.l"
 {
                           xlu__cfgl_lexicalerror(ctx,"lexical error");
                           BEGIN(0);
@@ -952,10 +968,10 @@
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 88 "libxlu_cfg_l.l"
+#line 104 "libxlu_cfg_l.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
        YY_BREAK
-#line 959 "libxlu_cfg_l.c"
+#line 975 "libxlu_cfg_l.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(lexerr):
        yyterminate();
@@ -2105,4 +2121,4 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 88 "libxlu_cfg_l.l"
+#line 104 "libxlu_cfg_l.l"
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_l.h
--- a/tools/libxl/libxlu_cfg_l.h        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_l.h        Mon Jun 06 09:49:57 2011 +0100
@@ -350,7 +350,7 @@
 #undef YY_DECL
 #endif
 
-#line 88 "libxlu_cfg_l.l"
+#line 104 "libxlu_cfg_l.l"
 
 #line 356 "libxlu_cfg_l.h"
 #undef xlu__cfg_yyIN_HEADER
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_l.l
--- a/tools/libxl/libxlu_cfg_l.l        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_l.l        Mon Jun 06 09:49:57 2011 +0100
@@ -1,4 +1,20 @@
 /* -*- fundamental -*- */
+/*
+ * libxlu_cfg_l.l - xl configuration file parsing: lexer
+ *
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
 
 %{
 #include "libxlu_cfg_i.h"
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_y.c
--- a/tools/libxl/libxlu_cfg_y.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_y.c        Mon Jun 06 09:49:57 2011 +0100
@@ -90,7 +90,7 @@
 
 
 /* Copy the first part of user declarations.  */
-#line 3 "libxlu_cfg_y.y"
+#line 19 "libxlu_cfg_y.y"
 
 #define YYLEX_PARAM ctx->scanner
 #include "libxlu_cfg_i.h"
@@ -117,7 +117,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 9 "libxlu_cfg_y.y"
+#line 25 "libxlu_cfg_y.y"
 {
   char *string;
   XLU_ConfigSetting *setting;
@@ -439,9 +439,9 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    31,    31,    32,    34,    34,    36,    37,    39,    40,
-      42,    43,    45,    46,    48,    49,    50,    52,    53,    55,
-      57
+       0,    47,    47,    48,    50,    50,    52,    53,    55,    56,
+      58,    59,    61,    62,    64,    65,    66,    68,    69,    71,
+      73
 };
 #endif
 
@@ -1062,37 +1062,37 @@
   switch (yytype)
     {
       case 3: /* "IDENT" */
-#line 24 "libxlu_cfg_y.y"
+#line 40 "libxlu_cfg_y.y"
        { free((yyvaluep->string)); };
 #line 1068 "libxlu_cfg_y.c"
        break;
       case 4: /* "STRING" */
-#line 24 "libxlu_cfg_y.y"
+#line 40 "libxlu_cfg_y.y"
        { free((yyvaluep->string)); };
 #line 1073 "libxlu_cfg_y.c"
        break;
       case 5: /* "NUMBER" */
-#line 24 "libxlu_cfg_y.y"
+#line 40 "libxlu_cfg_y.y"
        { free((yyvaluep->string)); };
 #line 1078 "libxlu_cfg_y.c"
        break;
       case 17: /* "value" */
-#line 27 "libxlu_cfg_y.y"
+#line 43 "libxlu_cfg_y.y"
        { xlu__cfg_set_free((yyvaluep->setting)); };
 #line 1083 "libxlu_cfg_y.c"
        break;
       case 18: /* "atom" */
-#line 24 "libxlu_cfg_y.y"
+#line 40 "libxlu_cfg_y.y"
        { free((yyvaluep->string)); };
 #line 1088 "libxlu_cfg_y.c"
        break;
       case 19: /* "valuelist" */
-#line 27 "libxlu_cfg_y.y"
+#line 43 "libxlu_cfg_y.y"
        { xlu__cfg_set_free((yyvaluep->setting)); };
 #line 1093 "libxlu_cfg_y.c"
        break;
       case 20: /* "values" */
-#line 27 "libxlu_cfg_y.y"
+#line 43 "libxlu_cfg_y.y"
        { xlu__cfg_set_free((yyvaluep->setting)); };
 #line 1098 "libxlu_cfg_y.c"
        break;
@@ -1417,52 +1417,52 @@
   switch (yyn)
     {
         case 4:
-#line 34 "libxlu_cfg_y.y"
+#line 50 "libxlu_cfg_y.y"
     { xlu__cfg_set_store(ctx,(yyvsp[(1) - (3)].string),(yyvsp[(3) - 
(3)].setting),(yylsp[(3) - (3)]).first_line); ;}
     break;
 
   case 10:
-#line 42 "libxlu_cfg_y.y"
+#line 58 "libxlu_cfg_y.y"
     { (yyval.setting)= xlu__cfg_set_mk(ctx,1,(yyvsp[(1) - (1)].string)); ;}
     break;
 
   case 11:
-#line 43 "libxlu_cfg_y.y"
+#line 59 "libxlu_cfg_y.y"
     { (yyval.setting)= (yyvsp[(3) - (4)].setting); ;}
     break;
 
   case 12:
-#line 45 "libxlu_cfg_y.y"
+#line 61 "libxlu_cfg_y.y"
     { (yyval.string)= (yyvsp[(1) - (1)].string); ;}
     break;
 
   case 13:
-#line 46 "libxlu_cfg_y.y"
+#line 62 "libxlu_cfg_y.y"
     { (yyval.string)= (yyvsp[(1) - (1)].string); ;}
     break;
 
   case 14:
-#line 48 "libxlu_cfg_y.y"
+#line 64 "libxlu_cfg_y.y"
     { (yyval.setting)= xlu__cfg_set_mk(ctx,0,0); ;}
     break;
 
   case 15:
-#line 49 "libxlu_cfg_y.y"
+#line 65 "libxlu_cfg_y.y"
     { (yyval.setting)= (yyvsp[(1) - (1)].setting); ;}
     break;
 
   case 16:
-#line 50 "libxlu_cfg_y.y"
+#line 66 "libxlu_cfg_y.y"
     { (yyval.setting)= (yyvsp[(1) - (3)].setting); ;}
     break;
 
   case 17:
-#line 52 "libxlu_cfg_y.y"
+#line 68 "libxlu_cfg_y.y"
     { (yyval.setting)= xlu__cfg_set_mk(ctx,2,(yyvsp[(1) - (2)].string)); ;}
     break;
 
   case 18:
-#line 53 "libxlu_cfg_y.y"
+#line 69 "libxlu_cfg_y.y"
     { xlu__cfg_set_add(ctx,(yyvsp[(1) - (5)].setting),(yyvsp[(4) - 
(5)].string)); (yyval.setting)= (yyvsp[(1) - (5)].setting); ;}
     break;
 
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_y.h
--- a/tools/libxl/libxlu_cfg_y.h        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_y.h        Mon Jun 06 09:49:57 2011 +0100
@@ -56,7 +56,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 9 "libxlu_cfg_y.y"
+#line 25 "libxlu_cfg_y.y"
 {
   char *string;
   XLU_ConfigSetting *setting;
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_cfg_y.y
--- a/tools/libxl/libxlu_cfg_y.y        Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_cfg_y.y        Mon Jun 06 09:49:57 2011 +0100
@@ -1,4 +1,20 @@
 /* -*- fundamental -*- */
+/*
+ * libxlu_cfg_l.y - xl configuration file parsing: parser
+ *
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
 
 %{
 #define YYLEX_PARAM ctx->scanner
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/libxlu_internal.h
--- a/tools/libxl/libxlu_internal.h     Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/libxlu_internal.h     Mon Jun 06 09:49:57 2011 +0100
@@ -45,4 +45,8 @@
     void *scanner;
 } CfgParseContext;
 
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+
 #endif /*LIBXLU_INTERNAL_H*/
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/xl.h
--- a/tools/libxl/xl.h  Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/xl.h  Mon Jun 06 09:49:57 2011 +0100
@@ -87,6 +87,9 @@
 int main_cpupoolcpuremove(int argc, char **argv);
 int main_cpupoolmigrate(int argc, char **argv);
 int main_cpupoolnumasplit(int argc, char **argv);
+int main_getenforce(int argc, char **argv);
+int main_setenforce(int argc, char **argv);
+int main_loadpolicy(int argc, char **argv);
 
 void help(const char *command);
 
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Mon Jun 06 09:49:57 2011 +0100
@@ -393,7 +393,7 @@
         printf("\t\t\t(physpath %s)\n", d_config->disks[i].pdev_path);
         printf("\t\t\t(phystype %d)\n", d_config->disks[i].backend);
         printf("\t\t\t(virtpath %s)\n", d_config->disks[i].vdev);
-        printf("\t\t\t(unpluggable %d)\n", d_config->disks[i].unpluggable);
+        printf("\t\t\t(unpluggable %d)\n", d_config->disks[i].removable);
         printf("\t\t\t(readwrite %d)\n", d_config->disks[i].readwrite);
         printf("\t\t\t(is_cdrom %d)\n", d_config->disks[i].is_cdrom);
         printf("\t\t)\n");
@@ -591,7 +591,7 @@
                 *p = '\0';
                 if ( !strcmp(tok, "cdrom") ) {
                     disk->is_cdrom = 1;
-                    disk->unpluggable = 1;
+                    disk->removable = 1;
                 }else{
                     fprintf(stderr, "Unknown virtual disk type: %s\n", tok);
                     return 0;
@@ -652,6 +652,19 @@
 
     libxl_init_create_info(c_info);
 
+    if (!xlu_cfg_get_string (config, "seclabel", &buf)) {
+        e = libxl_flask_context_to_sid(ctx, (char *)buf, strlen(buf),
+                                    &c_info->ssidref);
+        if (e) {
+            if (errno == ENOSYS) {
+                fprintf(stderr, "XSM Disabled: seclabel not supported\n");    
+            } else {
+                fprintf(stderr, "Invalid seclabel: %s\n", buf);
+                exit(1);
+            }
+        }
+    }
+
     c_info->hvm = 0;
     if (!xlu_cfg_get_string (config, "builder", &buf) &&
         !strncmp(buf, "hvm", strlen(buf)))
@@ -1503,10 +1516,6 @@
 
     parse_config_data(config_file, config_data, config_len, &d_config, 
&d_config.dm_info);
 
-    ret = 0;
-    if (dom_info->dryrun)
-        goto out;
-
     if (migrate_fd >= 0) {
         if (d_config.c_info.name) {
             /* when we receive a domain we get its name from the config
@@ -1525,9 +1534,13 @@
         }
     }
 
-    if (debug)
+    if (debug || dom_info->dryrun)
         printf_info(-1, &d_config, &d_config.dm_info);
 
+    ret = 0;
+    if (dom_info->dryrun)
+        goto out;
+
 start:
     domid = -1;
 
@@ -2264,13 +2277,14 @@
     }
 }
 
-static void list_domains(int verbose, const libxl_dominfo *info, int nb_domain)
+static void list_domains(int verbose, int context, const libxl_dominfo *info, 
int nb_domain)
 {
     int i;
     static const char shutdown_reason_letters[]= "-rscw";
 
     printf("Name                                        ID   Mem 
VCPUs\tState\tTime(s)");
-    if (verbose) printf("   UUID                            Reason-Code");
+    if (verbose) printf("   UUID                            
Reason-Code\tSecurity Label");
+    if (context && !verbose) printf("   Security Label");
     printf("\n");
     for (i = 0; i < nb_domain; i++) {
         char *domname;
@@ -2294,9 +2308,22 @@
         free(domname);
         if (verbose) {
             printf(" " LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info[i].uuid));
-           if (info[i].shutdown) printf(" %8x", shutdown_reason);
-           else printf(" %8s", "-");
-       }
+            if (info[i].shutdown) printf(" %8x", shutdown_reason);
+            else printf(" %8s", "-");
+        }
+        if (verbose || context) {
+            int rc;
+            size_t size;
+            char *buf;
+            rc = libxl_flask_sid_to_context(ctx, info[i].ssidref, &buf, 
+                                            &size); 
+            if (rc < 0)
+                printf("  -");
+            else {
+                printf("  %s", buf);
+                free(buf);
+            }
+        }
         putchar('\n');
     }
 }
@@ -3032,12 +3059,14 @@
 int main_list(int argc, char **argv)
 {
     int opt, verbose = 0;
+    int context = 0;
     int details = 0;
     int option_index = 0;
     static struct option long_options[] = {
         {"long", 0, 0, 'l'},
         {"help", 0, 0, 'h'},
         {"verbose", 0, 0, 'v'},
+        {"context", 0, 0, 'Z'},
         {0, 0, 0, 0}
     };
 
@@ -3046,7 +3075,7 @@
     int nb_domain, rc;
 
     while (1) {
-        opt = getopt_long(argc, argv, "lvh", long_options, &option_index);
+        opt = getopt_long(argc, argv, "lvhZ", long_options, &option_index);
         if (opt == -1)
             break;
 
@@ -3060,6 +3089,9 @@
         case 'v':
             verbose = 1;
             break;
+        case 'Z':
+            context = 1;
+            break;
         default:
             fprintf(stderr, "option `%c' not supported.\n", optopt);
             break;
@@ -3095,7 +3127,7 @@
     if (details)
         list_domains_details(info, nb_domain);
     else
-        list_domains(verbose, info, nb_domain);
+        list_domains(verbose, context, info, nb_domain);
 
     free(info_free);
 
@@ -4149,7 +4181,7 @@
         return 1;
     }
     disk.vdev = argv[optind+2];
-    disk.unpluggable = 1;
+    disk.removable = 1;
     disk.readwrite = ((argc-optind <= 3) || (argv[optind+3][0] == 'w'));
 
     if (domain_qualifier_to_domid(argv[optind], &fe_domid, 0) < 0) {
@@ -5280,3 +5312,122 @@
 
     return ret;
 }
+
+int main_getenforce(int argc, char **argv)
+{
+    int ret;
+
+    ret = libxl_flask_getenforce(ctx);
+
+    if (ret < 0) {
+        if (errno == ENOSYS)
+            printf("Flask XSM Disabled\n");
+        else
+            fprintf(stderr, "Failed to get enforcing mode\n");
+    }
+    else if (ret == 1)
+        printf("Enforcing\n");
+    else if (ret == 0)
+        printf("Permissive\n");
+
+    return ret; 
+}
+
+int main_setenforce(int argc, char **argv)
+{
+    int ret, mode = -1;
+    const char *p = NULL;
+
+    if (optind >= argc) {
+        help("setenforce");
+        return 2;
+    }
+
+    p = argv[optind];
+
+    if (!strcmp(p, "0"))
+        mode = 0;
+    else if (!strcmp(p, "1"))
+        mode = 1;
+    else if (!strcasecmp(p, "permissive"))
+        mode = 0;
+    else if (!strcasecmp(p, "enforcing"))
+        mode = 1;
+    else {
+        help("setenforce");
+        return 2;
+    }
+   
+    ret = libxl_flask_setenforce(ctx, mode);
+
+    if (ret) {
+        if (errno == ENOSYS) {
+            fprintf(stderr, "Flask XSM disabled\n");
+        } 
+        else 
+            fprintf(stderr, "error occured while setting enforcing mode 
(%i)\n", ret);
+    }
+
+    return ret;
+}
+
+int main_loadpolicy(int argc, char **argv)
+{
+    const char *polFName;
+    int polFd = 0;
+    void *polMemCp = NULL;
+    struct stat info;
+    int ret;
+
+    if (optind >= argc) {
+        help("loadpolicy");
+        return 2;
+    }
+
+    polFName = argv[optind];
+    polFd = open(polFName, O_RDONLY);
+    if ( polFd < 0 ) {
+        fprintf(stderr, "Error occurred opening policy file '%s': %s\n",
+                polFName, strerror(errno));
+        ret = -1;
+        goto done;
+    }
+    
+    ret = stat(polFName, &info);
+    if ( ret < 0 ) {
+        fprintf(stderr, "Error occurred retrieving information about"
+                "policy file '%s': %s\n", polFName, strerror(errno));
+        goto done;
+    }
+
+    polMemCp = malloc(info.st_size);
+     
+    ret = read(polFd, polMemCp, info.st_size);
+    if ( ret < 0 ) {
+        fprintf(stderr, "Unable to read new Flask policy file: %s\n",
+                strerror(errno));
+        goto done;
+    }
+
+    ret = libxl_flask_loadpolicy(ctx, polMemCp, info.st_size);
+
+    if (ret < 0) {
+        if (errno == ENOSYS) {
+            fprintf(stderr, "Flask XSM disabled\n");
+        } else {
+            errno = -ret;
+            fprintf(stderr, "Unable to load new Flask policy: %s\n",
+                    strerror(errno));
+            ret = -1;
+        }
+    } else {
+        printf("Successfully loaded policy.\n");
+    }
+
+done:
+    free(polMemCp);
+    if ( polFd > 0 )
+        close(polFd);
+
+    return ret;
+}
diff -r 840e16142824 -r 68947fbeaa76 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Thu Jun 02 13:16:52 2011 +0100
+++ b/tools/libxl/xl_cmdtable.c Mon Jun 06 09:49:57 2011 +0100
@@ -36,7 +36,8 @@
       "List information about all/some domains",
       "[options] [Domain]\n",
       "-l, --long              Output all VM details\n"
-      "-v, --verbose           Prints out UUIDs",
+      "-v, --verbose           Prints out UUIDs and security context\n"
+      "-Z, --context           Prints out security context"
     },
     { "destroy",
       &main_destroy,
@@ -364,6 +365,21 @@
       "Splits up the machine into one CPU pool per NUMA node",
       "",
     },
+    { "getenforce",
+      &main_getenforce,
+      "Returns the current enforcing mode of the Flask Xen security module",
+      "",
+    },
+    { "setenforce",
+      &main_setenforce,
+      "Sets the current enforcing mode of the Flask Xen security module",
+      "<1|0|Enforcing|Permissive>",
+    },
+    { "loadpolicy",
+      &main_loadpolicy,
+      "Loads a new policy int the Flask Xen security module",
+      "<policy file>",
+    },
 };
 
 int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
diff -r 840e16142824 -r 68947fbeaa76 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Mon Jun 06 09:49:57 2011 +0100
@@ -2375,7 +2375,6 @@
     return rc ? len : 0; /* fake a copy_from_user() return code */
 }
 
-#define bitmaskof(idx)  (1U << ((idx) & 31))
 void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
                                    unsigned int *ecx, unsigned int *edx)
 {
@@ -2402,7 +2401,7 @@
         /* Fix up OSXSAVE. */
         if ( xsave_enabled(v) )
             *ecx |= (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE) ?
-                     bitmaskof(X86_FEATURE_OSXSAVE) : 0;
+                     cpufeat_mask(X86_FEATURE_OSXSAVE) : 0;
         break;
     case 0xb:
         /* Fix the x2APIC identifier. */
@@ -2433,7 +2432,7 @@
            tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */
         if ( v->domain->arch.tsc_mode != TSC_MODE_DEFAULT ||
              !host_tsc_is_safe() )
-            *edx &= ~bitmaskof(X86_FEATURE_RDTSCP);
+            *edx &= ~cpufeat_mask(X86_FEATURE_RDTSCP);
         break;
     }
 }
@@ -2462,7 +2461,7 @@
     fixed_range_base = (uint64_t *)v->arch.hvm_vcpu.mtrr.fixed_ranges;
 
     hvm_cpuid(1, &cpuid[0], &cpuid[1], &cpuid[2], &cpuid[3]);
-    mtrr = !!(cpuid[3] & bitmaskof(X86_FEATURE_MTRR));
+    mtrr = !!(cpuid[3] & cpufeat_mask(X86_FEATURE_MTRR));
 
     switch ( msr )
     {
@@ -2574,7 +2573,7 @@
                (uint32_t)msr_content, (uint32_t)(msr_content >> 32));
 
     hvm_cpuid(1, &cpuid[0], &cpuid[1], &cpuid[2], &cpuid[3]);
-    mtrr = !!(cpuid[3] & bitmaskof(X86_FEATURE_MTRR));
+    mtrr = !!(cpuid[3] & cpufeat_mask(X86_FEATURE_MTRR));
 
     switch ( msr )
     {
diff -r 840e16142824 -r 68947fbeaa76 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Jun 06 09:49:57 2011 +0100
@@ -1191,7 +1191,6 @@
         vmcb_set_cr0(vmcb, vmcb_get_cr0(vmcb) & ~X86_CR0_TS);
 }
 
-#define bitmaskof(idx)  (1U << ((idx) & 31))
 static void svm_cpuid_intercept(
     unsigned int *eax, unsigned int *ebx,
     unsigned int *ecx, unsigned int *edx)
diff -r 840e16142824 -r 68947fbeaa76 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Jun 06 09:49:57 2011 +0100
@@ -1484,7 +1484,6 @@
     }
 }
 
-#define bitmaskof(idx)  (1U << ((idx) & 31))
 static void vmx_cpuid_intercept(
     unsigned int *eax, unsigned int *ebx,
     unsigned int *ecx, unsigned int *edx)
@@ -1501,9 +1500,9 @@
             /* SYSCALL is visible iff running in long mode. */
             hvm_get_segment_register(v, x86_seg_cs, &cs);
             if ( cs.attr.fields.l )
-                *edx |= bitmaskof(X86_FEATURE_SYSCALL);
+                *edx |= cpufeat_mask(X86_FEATURE_SYSCALL);
             else
-                *edx &= ~(bitmaskof(X86_FEATURE_SYSCALL));
+                *edx &= ~(cpufeat_mask(X86_FEATURE_SYSCALL));
 
             break;
     }
diff -r 840e16142824 -r 68947fbeaa76 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/arch/x86/setup.c      Mon Jun 06 09:49:57 2011 +0100
@@ -57,6 +57,10 @@
 static bool_t __initdata opt_watchdog;
 boolean_param("watchdog", opt_watchdog);
 
+/* smep: Enable/disable Supervisor Mode Execution Protection (default on). */
+static bool_t __initdata disable_smep;
+invbool_param("smep", disable_smep);
+
 /* **** Linux config option: propagated to domain0. */
 /* "acpi=off":    Sisables both ACPI table parsing and interpreter. */
 /* "acpi=force":  Override the disable blacklist.                   */
@@ -1200,11 +1204,17 @@
     arch_init_memory();
 
     identify_cpu(&boot_cpu_data);
+
     if ( cpu_has_fxsr )
         set_in_cr4(X86_CR4_OSFXSR);
     if ( cpu_has_xmm )
         set_in_cr4(X86_CR4_OSXMMEXCPT);
 
+    if ( disable_smep )
+        setup_clear_cpu_cap(X86_FEATURE_SMEP);
+    if ( cpu_has_smep )
+        set_in_cr4(X86_CR4_SMEP);
+
     local_irq_enable();
 
 #ifdef CONFIG_X86_64
diff -r 840e16142824 -r 68947fbeaa76 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/arch/x86/traps.c      Mon Jun 06 09:49:57 2011 +0100
@@ -813,6 +813,13 @@
            __clear_bit(X86_FEATURE_X2APIC % 32, &c);
         __set_bit(X86_FEATURE_HYPERVISOR % 32, &c);
         break;
+    case 7:
+        if ( regs->ecx == 0 )
+            b &= cpufeat_mask(X86_FEATURE_FSGSBASE);
+        else
+            b = 0;
+        a = c = d = 0;
+        break;
     case 0x80000001:
         /* Modify Feature Information. */
         if ( is_pv_32bit_vcpu(current) )
@@ -1132,7 +1139,13 @@
     (((va) >= HYPERVISOR_VIRT_START))
 #endif
 
-static int __spurious_page_fault(
+enum pf_type {
+    real_fault,
+    smep_fault,
+    spurious_fault
+};
+
+static enum pf_type __page_fault_type(
     unsigned long addr, unsigned int error_code)
 {
     unsigned long mfn, cr3 = read_cr3();
@@ -1144,7 +1157,7 @@
 #endif
     l2_pgentry_t l2e, *l2t;
     l1_pgentry_t l1e, *l1t;
-    unsigned int required_flags, disallowed_flags;
+    unsigned int required_flags, disallowed_flags, page_user;
 
     /*
      * We do not take spurious page faults in IRQ handlers as we do not
@@ -1152,11 +1165,11 @@
      * map_domain_page() is not IRQ-safe.
      */
     if ( in_irq() )
-        return 0;
+        return real_fault;
 
     /* Reserved bit violations are never spurious faults. */
     if ( error_code & PFEC_reserved_bit )
-        return 0;
+        return real_fault;
 
     required_flags  = _PAGE_PRESENT;
     if ( error_code & PFEC_write_access )
@@ -1168,6 +1181,8 @@
     if ( error_code & PFEC_insn_fetch )
         disallowed_flags |= _PAGE_NX_BIT;
 
+    page_user = _PAGE_USER;
+
     mfn = cr3 >> PAGE_SHIFT;
 
 #if CONFIG_PAGING_LEVELS >= 4
@@ -1177,7 +1192,8 @@
     unmap_domain_page(l4t);
     if ( ((l4e_get_flags(l4e) & required_flags) != required_flags) ||
          (l4e_get_flags(l4e) & disallowed_flags) )
-        return 0;
+        return real_fault;
+    page_user &= l4e_get_flags(l4e);
 #endif
 
 #if CONFIG_PAGING_LEVELS >= 3
@@ -1190,13 +1206,14 @@
     unmap_domain_page(l3t);
 #if CONFIG_PAGING_LEVELS == 3
     if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
-        return 0;
+        return real_fault;
 #else
     if ( ((l3e_get_flags(l3e) & required_flags) != required_flags) ||
          (l3e_get_flags(l3e) & disallowed_flags) )
-        return 0;
+        return real_fault;
+    page_user &= l3e_get_flags(l3e);
     if ( l3e_get_flags(l3e) & _PAGE_PSE )
-        return 1;
+        goto leaf;
 #endif
 #endif
 
@@ -1206,9 +1223,10 @@
     unmap_domain_page(l2t);
     if ( ((l2e_get_flags(l2e) & required_flags) != required_flags) ||
          (l2e_get_flags(l2e) & disallowed_flags) )
-        return 0;
+        return real_fault;
+    page_user &= l2e_get_flags(l2e);
     if ( l2e_get_flags(l2e) & _PAGE_PSE )
-        return 1;
+        goto leaf;
 
     l1t = map_domain_page(mfn);
     l1e = l1e_read_atomic(&l1t[l1_table_offset(addr)]);
@@ -1216,26 +1234,36 @@
     unmap_domain_page(l1t);
     if ( ((l1e_get_flags(l1e) & required_flags) != required_flags) ||
          (l1e_get_flags(l1e) & disallowed_flags) )
-        return 0;
-
-    return 1;
+        return real_fault;
+    page_user &= l1e_get_flags(l1e);
+
+leaf:
+    /*
+     * Supervisor Mode Execution Protection (SMEP):
+     * Disallow supervisor execution from user-accessible mappings
+     */
+    if ( (read_cr4() & X86_CR4_SMEP) && page_user &&
+         ((error_code & (PFEC_insn_fetch|PFEC_user_mode)) == PFEC_insn_fetch) )
+        return smep_fault;
+
+    return spurious_fault;
 }
 
-static int spurious_page_fault(
+static enum pf_type spurious_page_fault(
     unsigned long addr, unsigned int error_code)
 {
     unsigned long flags;
-    int           is_spurious;
+    enum pf_type pf_type;
 
     /*
      * Disabling interrupts prevents TLB flushing, and hence prevents
      * page tables from becoming invalid under our feet during the walk.
      */
     local_irq_save(flags);
-    is_spurious = __spurious_page_fault(addr, error_code);
+    pf_type = __page_fault_type(addr, error_code);
     local_irq_restore(flags);
 
-    return is_spurious;
+    return pf_type;
 }
 
 static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs)
@@ -1310,6 +1338,7 @@
 {
     unsigned long addr, fixup;
     unsigned int error_code;
+    enum pf_type pf_type;
 
     addr = read_cr2();
 
@@ -1325,7 +1354,9 @@
 
     if ( unlikely(!guest_mode(regs)) )
     {
-        if ( spurious_page_fault(addr, error_code) )
+        pf_type = spurious_page_fault(addr, error_code);
+        BUG_ON(pf_type == smep_fault);
+        if ( pf_type != real_fault )
             return;
 
         if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
@@ -1347,9 +1378,17 @@
               error_code, _p(addr));
     }
 
-    if ( unlikely(current->domain->arch.suppress_spurious_page_faults
-                  && spurious_page_fault(addr, error_code)) )
-        return;
+    if ( unlikely(current->domain->arch.suppress_spurious_page_faults) )
+    {
+        pf_type = spurious_page_fault(addr, error_code);
+        if ( pf_type == smep_fault )
+        {
+            gdprintk(XENLOG_ERR, "Fatal SMEP fault\n");
+            domain_crash(current->domain);
+        }
+        if ( pf_type != real_fault )
+            return;
+    }
 
     propagate_page_fault(addr, regs->error_code);
 }
diff -r 840e16142824 -r 68947fbeaa76 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h  Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/include/asm-x86/cpufeature.h  Mon Jun 06 09:49:57 2011 +0100
@@ -141,11 +141,13 @@
 #define X86_FEATURE_TBM         (6*32+21) /* trailing bit manipulations */
 #define X86_FEATURE_TOPOEXT     (6*32+22) /* topology extensions CPUID leafs */
 
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 7 */
 #define X86_FEATURE_FSGSBASE   (7*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_SMEP       (7*32+ 7) /* Supervisor Mode Execution 
Protection */
 
 #define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
+#define cpufeat_mask(idx)       (1u << ((idx) & 31))
 
 #ifdef __i386__
 #define cpu_has_vme            boot_cpu_has(X86_FEATURE_VME)
@@ -201,6 +203,8 @@
 #define cpu_has_fsgsbase       boot_cpu_has(X86_FEATURE_FSGSBASE)
 #endif
 
+#define cpu_has_smep            boot_cpu_has(X86_FEATURE_SMEP)
+
 #define cpu_has_ffxsr           ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) \
                                  && boot_cpu_has(X86_FEATURE_FFXSR))
 
diff -r 840e16142824 -r 68947fbeaa76 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/include/asm-x86/domain.h      Mon Jun 06 09:49:57 2011 +0100
@@ -516,12 +516,14 @@
 /* Convert between guest-visible and real CR4 values. */
 #define pv_guest_cr4_to_real_cr4(v)                         \
     (((v)->arch.pv_vcpu.ctrlreg[4]                          \
-      | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))    \
-      | ((v)->domain->arch.vtsc ? X86_CR4_TSD : 0)         \
-      | ((xsave_enabled(v))? X86_CR4_OSXSAVE : 0))              \
-      & ~X86_CR4_DE)
-#define real_cr4_to_pv_guest_cr4(c) \
-    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD | X86_CR4_OSXSAVE))
+      | (mmu_cr4_features                                   \
+         & (X86_CR4_PGE | X86_CR4_PSE | X86_CR4_SMEP))      \
+      | ((v)->domain->arch.vtsc ? X86_CR4_TSD : 0)          \
+      | ((xsave_enabled(v))? X86_CR4_OSXSAVE : 0))          \
+     & ~X86_CR4_DE)
+#define real_cr4_to_pv_guest_cr4(c)                         \
+    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD        \
+             | X86_CR4_OSXSAVE | X86_CR4_SMEP))
 
 void domain_cpuid(struct domain *d,
                   unsigned int  input,
diff -r 840e16142824 -r 68947fbeaa76 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Thu Jun 02 13:16:52 2011 +0100
+++ b/xen/include/asm-x86/processor.h   Mon Jun 06 09:49:57 2011 +0100
@@ -85,6 +85,7 @@
 #define X86_CR4_SMXE           0x4000  /* enable SMX */
 #define X86_CR4_FSGSBASE       0x10000 /* enable {rd,wr}{fs,gs}base */
 #define X86_CR4_OSXSAVE        0x40000 /* enable XSAVE/XRSTOR */
+#define X86_CR4_SMEP           0x100000/* enable SMEP */
 
 /*
  * Trap/fault mnemonics.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>