- fate#309894: Xen needs to correctly understand family 15h CPU

topology 
- fate#311376: EFI support in SP2
- fate#311529: Native UEFI booting under Xen (installation)
  23074-pfn.h.patch
  23571-vtd-fault-verbosity.patch
  23574-x86-dom0-compressed-ELF.patch
  23575-x86-DMI.patch
  23610-x86-topology-info.patch
  23611-amd-fam15-topology.patch
  23613-EFI-headers.patch
  23614-x86_64-EFI-boot.patch
  23615-x86_64-EFI-runtime.patch
  23616-x86_64-EFI-MPS.patch

- Mark xen-scsi.ko supported (bnc#582265, fate#309459).

- fate#310308: Hypervisor assisted watchdog driver 
  ioemu-watchdog-support.patch
  ioemu-watchdog-linkage.patch
  ioemu-watchdog-ib700-timer.patch
  tools-watchdog-support.patch

- bnc#702025 - VUL-0: xen: VT-d (PCI passthrough) MSI trap 
  injection  (CVE-2011-1898)
  Fixed in Xen version 4.1.1

- fate#310956: Support Direct Kernel Boot for FV guests
  kernel-boot-hvm.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=130
This commit is contained in:
Charles Arnold 2011-07-01 19:31:25 +00:00 committed by Git OBS Bridge
parent 41471498df
commit ed105f0f54
33 changed files with 9136 additions and 101 deletions

114
23074-pfn.h.patch Normal file
View File

@ -0,0 +1,114 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1300887295 0
# Node ID c80e0fb4fe932b4d8379ea5739af93ae22a30ea5
# Parent 3831bd253e02aa0536ed32e936777d026abb955e
Define new <pfn.h> header for PFN_{DOWN,UP} macros.
Signed-off-by: Keir Fraser <keir@xen.org>
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -21,6 +21,7 @@
#include <xen/bitops.h>
#include <xen/compat.h>
#include <xen/libelf.h>
+#include <xen/pfn.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <asm/io.h>
--- a/xen/arch/x86/e820.c
+++ b/xen/arch/x86/e820.c
@@ -4,6 +4,7 @@
#include <xen/mm.h>
#include <xen/compat.h>
#include <xen/dmi.h>
+#include <xen/pfn.h>
#include <asm/e820.h>
#include <asm/page.h>
#include <asm/processor.h>
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -99,6 +99,7 @@
#include <xen/event.h>
#include <xen/iocap.h>
#include <xen/guest_access.h>
+#include <xen/pfn.h>
#include <asm/paging.h>
#include <asm/shadow.h>
#include <asm/page.h>
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -18,6 +18,7 @@
#include <xen/pci_regs.h>
#include <xen/iocap.h>
#include <xen/keyhandler.h>
+#include <xen/pfn.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/desc.h>
--- a/xen/arch/x86/numa.c
+++ b/xen/arch/x86/numa.c
@@ -13,6 +13,7 @@
#include <xen/keyhandler.h>
#include <xen/time.h>
#include <xen/smp.h>
+#include <xen/pfn.h>
#include <asm/acpi.h>
#include <xen/sched.h>
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -21,6 +21,7 @@
#include <xen/rcupdate.h>
#include <xen/vga.h>
#include <xen/dmi.h>
+#include <xen/pfn.h>
#include <xen/nodemask.h>
#include <public/version.h>
#ifdef CONFIG_COMPAT
--- a/xen/arch/x86/srat.c
+++ b/xen/arch/x86/srat.c
@@ -17,6 +17,7 @@
#include <xen/nodemask.h>
#include <xen/acpi.h>
#include <xen/numa.h>
+#include <xen/pfn.h>
#include <asm/e820.h>
#include <asm/page.h>
--- a/xen/arch/x86/tboot.c
+++ b/xen/arch/x86/tboot.c
@@ -6,6 +6,7 @@
#include <xen/domain_page.h>
#include <xen/iommu.h>
#include <xen/acpi.h>
+#include <xen/pfn.h>
#include <asm/fixmap.h>
#include <asm/page.h>
#include <asm/processor.h>
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -396,8 +396,6 @@ static inline uint32_t cacheattr_to_pte_
#endif /* !__ASSEMBLY__ */
-#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK)
#endif /* __X86_PAGE_H__ */
--- /dev/null
+++ b/xen/include/xen/pfn.h
@@ -0,0 +1,9 @@
+#ifndef __XEN_PFN_H__
+#define __XEN_PFN_H__
+
+#include <asm/page.h>
+
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+
+#endif /* __XEN_PFN_H__ */

View File

@ -25,7 +25,7 @@ Signed-off-by: Keir Fraser <keir@xen.org>
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -61,6 +61,10 @@ integer_param("maxcpus", max_cpus);
@@ -62,6 +62,10 @@ integer_param("maxcpus", max_cpus);
static bool_t __initdata opt_watchdog;
boolean_param("watchdog", opt_watchdog);
@ -36,7 +36,7 @@ Signed-off-by: Keir Fraser <keir@xen.org>
/* **** Linux config option: propagated to domain0. */
/* "acpi=off": Sisables both ACPI table parsing and interpreter. */
/* "acpi=force": Override the disable blacklist. */
@@ -1204,11 +1208,17 @@ void __init __start_xen(unsigned long mb
@@ -1205,11 +1209,17 @@ void __init __start_xen(unsigned long mb
arch_init_memory();
identify_cpu(&boot_cpu_data);

View File

@ -0,0 +1,142 @@
# HG changeset patch
# User Allen Kay <allen.m.kay@intel.com>
# Date 1308823884 -3600
# Node ID d3ac71f22e8621d9a7604f82f3976337e6c97a9a
# Parent 065ca14be963fe4da55d629ed0b3692a14253a86
[VTD] print out debug message in vt-d fault handler only when iommu=debug is set
Print out debug messages in vtd_page_fault() handler only when
iommu=debug is set xen boot parameter.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -822,7 +822,7 @@ static int __init parse_ivrs_table(struc
BUG_ON(!table);
- if ( amd_iommu_debug )
+ if ( iommu_debug )
dump_acpi_table_header(table);
/* parse IVRS blocks */
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -48,7 +48,7 @@ bool_t __read_mostly iommu_snoop = 1;
bool_t __read_mostly iommu_qinval = 1;
bool_t __read_mostly iommu_intremap = 1;
bool_t __read_mostly iommu_hap_pt_share;
-bool_t __read_mostly amd_iommu_debug;
+bool_t __read_mostly iommu_debug;
bool_t __read_mostly amd_iommu_perdev_intremap;
static void __init parse_iommu_param(char *s)
@@ -74,8 +74,8 @@ static void __init parse_iommu_param(cha
iommu_qinval = 0;
else if ( !strcmp(s, "no-intremap") )
iommu_intremap = 0;
- else if ( !strcmp(s, "amd-iommu-debug") )
- amd_iommu_debug = 1;
+ else if ( !strcmp(s, "debug") )
+ iommu_debug = 1;
else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
amd_iommu_perdev_intremap = 1;
else if ( !strcmp(s, "dom0-passthrough") )
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -821,7 +821,7 @@ static int iommu_page_fault_do_one(struc
if ( fault_type == DMA_REMAP )
{
- dprintk(XENLOG_WARNING VTDPREFIX,
+ INTEL_IOMMU_DEBUG(
"DMAR:[%s] Request device [%02x:%02x.%d] "
"fault addr %"PRIx64", iommu reg = %p\n"
"DMAR:[fault reason %02xh] %s\n",
@@ -830,12 +830,13 @@ static int iommu_page_fault_do_one(struc
PCI_FUNC(source_id & 0xFF), addr, iommu->reg,
fault_reason, reason);
#ifndef __i386__ /* map_domain_page() cannot be used in this context */
- print_vtd_entries(iommu, (source_id >> 8),
+ if (iommu_debug)
+ print_vtd_entries(iommu, (source_id >> 8),
(source_id & 0xff), (addr >> PAGE_SHIFT));
#endif
}
else
- dprintk(XENLOG_WARNING VTDPREFIX,
+ INTEL_IOMMU_DEBUG(
"INTR-REMAP: Request device [%02x:%02x.%d] "
"fault index %"PRIx64", iommu reg = %p\n"
"INTR-REMAP:[fault reason %02xh] %s\n",
@@ -849,26 +850,19 @@ static int iommu_page_fault_do_one(struc
static void iommu_fault_status(u32 fault_status)
{
if ( fault_status & DMA_FSTS_PFO )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Fault Overflow\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Fault Overflow\n");
if ( fault_status & DMA_FSTS_PPF )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Primary Pending Fault\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Primary Pending Fault\n");
if ( fault_status & DMA_FSTS_AFO )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Advanced Fault Overflow\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Advanced Fault Overflow\n");
if ( fault_status & DMA_FSTS_APF )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Advanced Pending Fault\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Advanced Pending Fault\n");
if ( fault_status & DMA_FSTS_IQE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Queue Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Queue Error\n");
if ( fault_status & DMA_FSTS_ICE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Completion Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Completion Error\n");
if ( fault_status & DMA_FSTS_ITE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Time-out Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Time-out Error\n");
}
#define PRIMARY_FAULT_REG_LEN (16)
--- a/xen/drivers/passthrough/vtd/iommu.h
+++ b/xen/drivers/passthrough/vtd/iommu.h
@@ -512,4 +512,11 @@ struct intel_iommu {
struct acpi_drhd_unit *drhd;
};
+#define INTEL_IOMMU_DEBUG(fmt, args...) \
+ do \
+ { \
+ if ( iommu_debug ) \
+ dprintk(XENLOG_WARNING VTDPREFIX, fmt, ## args); \
+ } while(0)
+
#endif
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -34,7 +34,7 @@
#define AMD_IOMMU_DEBUG(fmt, args...) \
do \
{ \
- if ( amd_iommu_debug ) \
+ if ( iommu_debug ) \
printk(XENLOG_INFO "AMD-Vi: " fmt, ## args); \
} while(0)
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -31,7 +31,7 @@ extern bool_t force_iommu, iommu_verbose
extern bool_t iommu_workaround_bios_bug, iommu_passthrough;
extern bool_t iommu_snoop, iommu_qinval, iommu_intremap;
extern bool_t iommu_hap_pt_share;
-extern bool_t amd_iommu_debug;
+extern bool_t iommu_debug;
extern bool_t amd_iommu_perdev_intremap;
extern struct rangeset *mmio_ro_ranges;

View File

@ -0,0 +1,123 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1308825237 -3600
# Node ID d7644abc218d3232b9d957ce94fc4b4bcc1f456e
# Parent 584c2e5e03d96f912cdfe90f8e9f910d5d661706
x86: allow Dom0 image to be compressed ELF
Rather than being able to decompress only the payloads of bzImage
containers, extend the logic to also decompress simple compressed ELF
images. At once, allow uncompressed bzImage payloads.
This is a prerequisite for native EFI booting support (where, in the
absence of a capable secondary boot loader, the image will always be
in compressed form).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/bzimage.c
+++ b/xen/arch/x86/bzimage.c
@@ -5,6 +5,7 @@
#include <xen/string.h>
#include <xen/types.h>
#include <xen/decompress.h>
+#include <xen/libelf.h>
#include <asm/bzimage.h>
#define HEAPORDER 3
@@ -199,25 +200,36 @@ static __init int bzimage_check(struct s
return 1;
}
-int __init bzimage_headroom(char *image_start, unsigned long image_length)
+static unsigned long __initdata orig_image_len;
+
+unsigned long __init bzimage_headroom(char *image_start,
+ unsigned long image_length)
{
struct setup_header *hdr = (struct setup_header *)image_start;
- char *img;
- int err, headroom;
+ int err;
+ unsigned long headroom;
err = bzimage_check(hdr, image_length);
- if (err < 1)
+ if ( err < 0 )
return 0;
- img = image_start + (hdr->setup_sects+1) * 512;
- img += hdr->payload_offset;
+ if ( err > 0 )
+ {
+ image_start += (hdr->setup_sects + 1) * 512 + hdr->payload_offset;
+ image_length = hdr->payload_length;
+ }
+
+ if ( elf_is_elfbinary(image_start) )
+ return 0;
- headroom = output_length(img, hdr->payload_length);
- if (gzip_check(img, hdr->payload_length)) {
+ orig_image_len = image_length;
+ headroom = output_length(image_start, image_length);
+ if (gzip_check(image_start, image_length))
+ {
headroom += headroom >> 12; /* Add 8 bytes for every 32K input block */
headroom += (32768 + 18); /* Add 32K + 18 bytes of extra headroom */
} else
- headroom += hdr->payload_length;
+ headroom += image_length;
headroom = (headroom + 4095) & ~4095;
return headroom;
@@ -229,18 +241,24 @@ int __init bzimage_parse(char *image_bas
int err = bzimage_check(hdr, *image_len);
unsigned long output_len;
- if (err < 1)
+ if ( err < 0 )
return err;
+ if ( err > 0 )
+ {
+ *image_start += (hdr->setup_sects + 1) * 512 + hdr->payload_offset;
+ *image_len = hdr->payload_length;
+ }
+
+ if ( elf_is_elfbinary(*image_start) )
+ return 0;
+
BUG_ON(!(image_base < *image_start));
- *image_start += (hdr->setup_sects+1) * 512;
- *image_start += hdr->payload_offset;
- *image_len = hdr->payload_length;
- output_len = output_length(*image_start, *image_len);
+ output_len = output_length(*image_start, orig_image_len);
- if ( (err = perform_gunzip(image_base, *image_start, *image_len)) > 0 )
- err = decompress(*image_start, *image_len, image_base);
+ if ( (err = perform_gunzip(image_base, *image_start, orig_image_len)) > 0 )
+ err = decompress(*image_start, orig_image_len, image_base);
if ( !err )
{
--- a/xen/include/asm-x86/bzimage.h
+++ b/xen/include/asm-x86/bzimage.h
@@ -4,10 +4,9 @@
#include <xen/config.h>
#include <xen/init.h>
-int __init bzimage_headroom(char *image_start, unsigned long image_length);
+unsigned long bzimage_headroom(char *image_start, unsigned long image_length);
-int __init bzimage_parse(char *image_base,
- char **image_start,
- unsigned long *image_len);
+int bzimage_parse(char *image_base, char **image_start,
+ unsigned long *image_len);
#endif /* __X86_BZIMAGE_H__ */

154
23575-x86-DMI.patch Normal file
View File

@ -0,0 +1,154 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1308825280 -3600
# Node ID 4d9598a6a7777c50e109d7e2eb6d1cb28bcb4509
# Parent d7644abc218d3232b9d957ce94fc4b4bcc1f456e
x86/DMI: use proper structures instead of byte offsets
Besides being (in my eyes) desirable cleanup, this at once represents
another prerequisite for native EFI booting support.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -10,11 +10,31 @@
#include <asm/system.h>
#include <xen/dmi.h>
-#define bt_ioremap(b,l) ((u8 *)__acpi_map_table(b,l))
+#define bt_ioremap(b,l) ((void *)__acpi_map_table(b,l))
#define bt_iounmap(b,l) ((void)0)
#define memcpy_fromio memcpy
#define alloc_bootmem(l) xmalloc_bytes(l)
+struct dmi_eps {
+ char anchor[5]; /* "_DMI_" */
+ u8 checksum;
+ u16 size;
+ u32 address;
+ u16 num_structures;
+ u8 revision;
+} __attribute__((packed));
+
+struct smbios_eps {
+ char anchor[4]; /* "_SM_" */
+ u8 checksum;
+ u8 length;
+ u8 major, minor;
+ u16 max_size;
+ u8 revision;
+ u8 _rsrvd_[5];
+ struct dmi_eps dmi;
+} __attribute__((packed));
+
struct dmi_header
{
u8 type;
@@ -90,62 +110,70 @@ static int __init dmi_table(u32 base, in
}
-inline static int __init dmi_checksum(u8 *buf)
+static inline bool_t __init dmi_checksum(const void __iomem *buf,
+ unsigned int len)
{
- u8 sum=0;
- int a;
+ u8 sum = 0;
+ const u8 *p = buf;
+ unsigned int a;
- for(a=0; a<15; a++)
- sum+=buf[a];
- return (sum==0);
+ for (a = 0; a < len; a++)
+ sum += p[a];
+ return sum == 0;
}
int __init dmi_get_table(u32 *base, u32 *len)
{
- u8 buf[15];
+ struct dmi_eps eps;
char __iomem *p, *q;
p = maddr_to_virt(0xF0000);
for (q = p; q < p + 0x10000; q += 16) {
- memcpy_fromio(buf, q, 15);
- if (memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) {
- *base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
- *len=buf[7]<<8|buf[6];
+ memcpy_fromio(&eps, q, 15);
+ if (memcmp(eps.anchor, "_DMI_", 5) == 0 &&
+ dmi_checksum(&eps, sizeof(eps))) {
+ *base = eps.address;
+ *len = eps.size;
return 0;
}
}
return -1;
}
+static int __init _dmi_iterate(const struct dmi_eps *dmi,
+ const struct smbios_eps __iomem *smbios,
+ void (*decode)(struct dmi_header *))
+{
+ u16 num = dmi->num_structures;
+ u16 len = dmi->size;
+ u32 base = dmi->address;
+
+ /*
+ * DMI version 0.0 means that the real version is taken from
+ * the SMBIOS version, which we may not know at this point.
+ */
+ if (dmi->revision)
+ printk(KERN_INFO "DMI %d.%d present.\n",
+ dmi->revision >> 4, dmi->revision & 0x0f);
+ else if (!smbios)
+ printk(KERN_INFO "DMI present.\n");
+ dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
+ num, len));
+ dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
+ return dmi_table(base, len, num, decode);
+}
+
static int __init dmi_iterate(void (*decode)(struct dmi_header *))
{
- u8 buf[15];
+ struct dmi_eps eps;
char __iomem *p, *q;
p = maddr_to_virt(0xF0000);
for (q = p; q < p + 0x10000; q += 16) {
- memcpy_fromio(buf, q, 15);
- if (memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) {
- u16 num=buf[13]<<8|buf[12];
- u16 len=buf[7]<<8|buf[6];
- u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
-
- /*
- * DMI version 0.0 means that the real version is taken from
- * the SMBIOS version, which we don't know at this point.
- */
- if(buf[14]!=0)
- printk(KERN_INFO "DMI %d.%d present.\n",
- buf[14]>>4, buf[14]&0x0F);
- else
- printk(KERN_INFO "DMI present.\n");
- dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
- num, len));
- dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
- base));
- if(dmi_table(base,len, num, decode)==0)
- return 0;
- }
+ memcpy_fromio(&eps, q, sizeof(eps));
+ if (memcmp(eps.anchor, "_DMI_", 5) == 0 &&
+ dmi_checksum(&eps, sizeof(eps)))
+ return _dmi_iterate(&eps, NULL, decode);
}
return -1;
}

View File

@ -0,0 +1,212 @@
References: fate#309894
# HG changeset patch
# User Wei Huang <wei.huang2@amd.com>
# Date 1309248811 -3600
# Node ID 87c2013c2aa2d4874f892507e6cc7b52219a3acf
# Parent 819c315a919daec434f80ffb6e790ac492cbd2a7
x86: consolidate cpu_core_id and phys_proc_id into cpuinfo_x86 struct
This patch moves cpu_core_id and phys_proc_id into cpuinfo_x86
structure. This is similar to upstream Linux kernel's approach.
Signed-off-by: Wei Huang <wei.huang2@amd.com>
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -579,11 +579,11 @@ static void __devinit init_amd(struct cp
while ((1 << bits) < c->x86_max_cores)
bits++;
}
- cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
- phys_proc_id[cpu] >>= bits;
+ c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1);
+ c->phys_proc_id >>= bits;
if (opt_cpu_info)
printk("CPU %d(%d) -> Core %d\n",
- cpu, c->x86_max_cores, cpu_core_id[cpu]);
+ cpu, c->x86_max_cores, c->cpu_core_id);
}
#endif
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -326,7 +326,7 @@ void __cpuinit generic_identify(struct c
early_intel_workaround(c);
#ifdef CONFIG_X86_HT
- phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
+ c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
#endif
}
@@ -362,6 +362,8 @@ void __cpuinit identify_cpu(struct cpuin
c->x86_max_cores = 1;
c->x86_num_siblings = 1;
c->x86_clflush_size = 0;
+ c->phys_proc_id = BAD_APICID;
+ c->cpu_core_id = BAD_APICID;
memset(&c->x86_capability, 0, sizeof c->x86_capability);
if (!have_cpuid_p()) {
@@ -510,7 +512,6 @@ void __cpuinit detect_extended_topology(
unsigned int ht_mask_width, core_plus_mask_width;
unsigned int core_select_mask, core_level_siblings;
unsigned int initial_apicid;
- int cpu = smp_processor_id();
if ( c->cpuid_level < 0xb )
return;
@@ -545,9 +546,9 @@ void __cpuinit detect_extended_topology(
core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
- cpu_core_id[cpu] = phys_pkg_id(initial_apicid, ht_mask_width)
+ c->cpu_core_id = phys_pkg_id(initial_apicid, ht_mask_width)
& core_select_mask;
- phys_proc_id[cpu] = phys_pkg_id(initial_apicid, core_plus_mask_width);
+ c->phys_proc_id = phys_pkg_id(initial_apicid, core_plus_mask_width);
c->apicid = phys_pkg_id(initial_apicid, 0);
c->x86_max_cores = (core_level_siblings / c->x86_num_siblings);
@@ -555,10 +556,10 @@ void __cpuinit detect_extended_topology(
if ( opt_cpu_info )
{
printk("CPU: Physical Processor ID: %d\n",
- phys_proc_id[cpu]);
+ c->phys_proc_id);
if ( c->x86_max_cores > 1 )
printk("CPU: Processor Core ID: %d\n",
- cpu_core_id[cpu]);
+ c->cpu_core_id);
}
}
@@ -567,7 +568,6 @@ void __cpuinit detect_ht(struct cpuinfo_
{
u32 eax, ebx, ecx, edx;
int index_msb, core_bits;
- int cpu = smp_processor_id();
cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -590,11 +590,11 @@ void __cpuinit detect_ht(struct cpuinfo_
}
index_msb = get_count_order(c->x86_num_siblings);
- phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+ c->phys_proc_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
if (opt_cpu_info)
printk("CPU: Physical Processor ID: %d\n",
- phys_proc_id[cpu]);
+ c->phys_proc_id);
c->x86_num_siblings = c->x86_num_siblings / c->x86_max_cores;
@@ -602,12 +602,12 @@ void __cpuinit detect_ht(struct cpuinfo_
core_bits = get_count_order(c->x86_max_cores);
- cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
+ c->cpu_core_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
((1 << core_bits) - 1);
if (opt_cpu_info && c->x86_max_cores > 1)
printk("CPU: Processor Core ID: %d\n",
- cpu_core_id[cpu]);
+ c->cpu_core_id);
}
}
#endif
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -1041,9 +1041,9 @@ void x86_mc_get_cpu_info(unsigned cpu, u
if (nthreads != NULL)
*nthreads = 1;
} else {
- *chipid = phys_proc_id[cpu];
+ *chipid = c->phys_proc_id;
if (c->x86_max_cores > 1)
- *coreid = cpu_core_id[cpu];
+ *coreid = c->cpu_core_id;
else
*coreid = 0;
*threadid = c->apicid & ((1 << (c->x86_num_siblings - 1)) - 1);
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -52,12 +52,6 @@
/* Set if we find a B stepping CPU */
static int smp_b_stepping;
-/* Package ID of each logical CPU */
-int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-
-/* Core ID of each logical CPU */
-int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU_READ_MOSTLY(cpumask_t, cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
@@ -258,8 +252,8 @@ static void set_cpu_sibling_map(int cpu)
{
for_each_cpu_mask ( i, cpu_sibling_setup_map )
{
- if ( (phys_proc_id[cpu] == phys_proc_id[i]) &&
- (cpu_core_id[cpu] == cpu_core_id[i]) )
+ if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) &&
+ (c[cpu].cpu_core_id == c[i].cpu_core_id) )
{
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
@@ -282,7 +276,7 @@ static void set_cpu_sibling_map(int cpu)
for_each_cpu_mask ( i, cpu_sibling_setup_map )
{
- if ( phys_proc_id[cpu] == phys_proc_id[i] )
+ if ( c[cpu].phys_proc_id == c[i].phys_proc_id )
{
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
@@ -843,8 +837,8 @@ remove_siblinginfo(int cpu)
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
- phys_proc_id[cpu] = BAD_APICID;
- cpu_core_id[cpu] = BAD_APICID;
+ c[cpu].phys_proc_id = BAD_APICID;
+ c[cpu].cpu_core_id = BAD_APICID;
cpu_clear(cpu, cpu_sibling_setup_map);
}
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -175,6 +175,8 @@ struct cpuinfo_x86 {
__u32 x86_max_cores; /* cpuid returned max cores value */
__u32 booted_cores; /* number of cores as seen by OS */
__u32 x86_num_siblings; /* cpuid logical cpus per chip value */
+ int phys_proc_id; /* package ID of each logical CPU */
+ int cpu_core_id; /* core ID of each logical CPU*/
__u32 apicid;
unsigned short x86_clflush_size;
} __cacheline_aligned;
@@ -194,8 +196,6 @@ extern struct cpuinfo_x86 cpu_data[];
#endif
extern u64 host_pat;
-extern int phys_proc_id[NR_CPUS];
-extern int cpu_core_id[NR_CPUS];
extern bool_t opt_cpu_info;
/* Maximum width of physical addresses supported by the hardware */
@@ -215,8 +215,8 @@ extern void detect_ht(struct cpuinfo_x86
static always_inline void detect_ht(struct cpuinfo_x86 *c) {}
#endif
-#define cpu_to_core(_cpu) (cpu_core_id[_cpu])
-#define cpu_to_socket(_cpu) (phys_proc_id[_cpu])
+#define cpu_to_core(_cpu) (cpu_data[_cpu].cpu_core_id)
+#define cpu_to_socket(_cpu) (cpu_data[_cpu].phys_proc_id)
/*
* Generic CPUID function

View File

@ -0,0 +1,168 @@
References: fate#309894
# HG changeset patch
# User Wei Huang <wei.huang2@amd.com>
# Date 1309248833 -3600
# Node ID c2c12b2dafb5b1d3bfcc4c05a60ca4f9051c90e7
# Parent 87c2013c2aa2d4874f892507e6cc7b52219a3acf
x86: AMD core-pair topology detection code
This patch is to support core-pair topology introduced by AMD CPUs,
which introduces a new concept of [core, compute unit]. There is a new
feature bit for topology extension in CPUID:0x80000001. Also a new
CPUID 0x8000001E is introduced for CPU topology enumeration. This
patch collects the sibling information from the new CPUID and will be
stored in the sibling map in Xen hypervisor.
Signed-off-by: Wei Huang <wei.huang2@amd.com>
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -344,6 +344,49 @@ static void check_syscfg_dram_mod_en(voi
wrmsrl(MSR_K8_SYSCFG, syscfg);
}
+static void __devinit amd_get_topology(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_HT
+ int cpu;
+ unsigned bits;
+
+ if (c->x86_max_cores <= 1)
+ return;
+ /*
+ * On a AMD multi core setup the lower bits of the APIC id
+ * distingush the cores.
+ */
+ cpu = smp_processor_id();
+ bits = (cpuid_ecx(0x80000008) >> 12) & 0xf;
+
+ if (bits == 0) {
+ while ((1 << bits) < c->x86_max_cores)
+ bits++;
+ }
+
+ /* Low order bits define the core id */
+ c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1);
+ /* Convert local APIC ID into the socket ID */
+ c->phys_proc_id >>= bits;
+ /* Collect compute unit ID if available */
+ if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
+ u32 eax, ebx, ecx, edx;
+
+ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+ c->compute_unit_id = ebx & 0xFF;
+ c->x86_num_siblings = ((ebx >> 8) & 0x3) + 1;
+ }
+
+ if (opt_cpu_info)
+ printk("CPU %d(%d) -> Processor %d, %s %d\n",
+ cpu, c->x86_max_cores, c->phys_proc_id,
+ cpu_has(c, X86_FEATURE_TOPOEXT) ? "Compute Unit" :
+ "Core",
+ cpu_has(c, X86_FEATURE_TOPOEXT) ? c->compute_unit_id :
+ c->cpu_core_id);
+#endif
+}
+
static void __devinit init_amd(struct cpuinfo_x86 *c)
{
u32 l, h;
@@ -566,26 +609,7 @@ static void __devinit init_amd(struct cp
}
}
-#ifdef CONFIG_X86_HT
- /*
- * On a AMD multi core setup the lower bits of the APIC id
- * distingush the cores.
- */
- if (c->x86_max_cores > 1) {
- int cpu = smp_processor_id();
- unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf;
-
- if (bits == 0) {
- while ((1 << bits) < c->x86_max_cores)
- bits++;
- }
- c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1);
- c->phys_proc_id >>= bits;
- if (opt_cpu_info)
- printk("CPU %d(%d) -> Core %d\n",
- cpu, c->x86_max_cores, c->cpu_core_id);
- }
-#endif
+ amd_get_topology(c);
/* Pointless to use MWAIT on Family10 as it does not deep sleep. */
if (c->x86 >= 0x10 && !force_mwait)
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -364,6 +364,7 @@ void __cpuinit identify_cpu(struct cpuin
c->x86_clflush_size = 0;
c->phys_proc_id = BAD_APICID;
c->cpu_core_id = BAD_APICID;
+ c->compute_unit_id = BAD_APICID;
memset(&c->x86_capability, 0, sizeof c->x86_capability);
if (!have_cpuid_p()) {
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -241,6 +241,14 @@ static int booting_cpu;
/* CPUs for which sibling maps can be computed. */
static cpumask_t cpu_sibling_setup_map;
+static void link_thread_siblings(int cpu1, int cpu2)
+{
+ cpu_set(cpu1, per_cpu(cpu_sibling_map, cpu2));
+ cpu_set(cpu2, per_cpu(cpu_sibling_map, cpu1));
+ cpu_set(cpu1, per_cpu(cpu_core_map, cpu2));
+ cpu_set(cpu2, per_cpu(cpu_core_map, cpu1));
+}
+
static void set_cpu_sibling_map(int cpu)
{
int i;
@@ -252,13 +260,13 @@ static void set_cpu_sibling_map(int cpu)
{
for_each_cpu_mask ( i, cpu_sibling_setup_map )
{
- if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) &&
- (c[cpu].cpu_core_id == c[i].cpu_core_id) )
- {
- cpu_set(i, per_cpu(cpu_sibling_map, cpu));
- cpu_set(cpu, per_cpu(cpu_sibling_map, i));
- cpu_set(i, per_cpu(cpu_core_map, cpu));
- cpu_set(cpu, per_cpu(cpu_core_map, i));
+ if ( cpu_has(c, X86_FEATURE_TOPOEXT) ) {
+ if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) &&
+ (c[cpu].compute_unit_id == c[i].compute_unit_id) )
+ link_thread_siblings(cpu, i);
+ } else if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) &&
+ (c[cpu].cpu_core_id == c[i].cpu_core_id) ) {
+ link_thread_siblings(cpu, i);
}
}
}
@@ -839,6 +847,7 @@ remove_siblinginfo(int cpu)
cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = BAD_APICID;
c[cpu].cpu_core_id = BAD_APICID;
+ c[cpu].compute_unit_id = BAD_APICID;
cpu_clear(cpu, cpu_sibling_setup_map);
}
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -175,9 +175,10 @@ struct cpuinfo_x86 {
__u32 x86_max_cores; /* cpuid returned max cores value */
__u32 booted_cores; /* number of cores as seen by OS */
__u32 x86_num_siblings; /* cpuid logical cpus per chip value */
+ __u32 apicid;
int phys_proc_id; /* package ID of each logical CPU */
int cpu_core_id; /* core ID of each logical CPU*/
- __u32 apicid;
+ int compute_unit_id; /* AMD compute unit ID of each logical CPU */
unsigned short x86_clflush_size;
} __cacheline_aligned;

2725
23613-EFI-headers.patch Normal file

File diff suppressed because it is too large Load Diff

2485
23614-x86_64-EFI-boot.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,787 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1309249249 -3600
# Node ID d19e778442673050bba8ea8cf61585902ff81162
# Parent 8b7d00f2abb21b504f6f8e1a6cc235cee8eb0858
x86-64: EFI runtime code
This allows Dom0 access to all suitable EFI runtime services. The
actual calls into EFI are done in "physical" mode, as entering virtual
mode has been determined to be incompatible with kexec (EFI's
SetVirtualAddressMap() can be called only once, and hence the
secondary kernel can't establish its mappings). ("Physical" mode here
being quoted because this is a mode with paging enabled [otherwise
64-bit mode wouldn't work] but all mappings being 1:1.)
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -16,6 +16,7 @@
#include <xen/stringify.h>
#include <xen/vga.h>
#include <asm/e820.h>
+#include <asm/mm.h>
#include <asm/msr.h>
#include <asm/processor.h>
@@ -1149,6 +1150,53 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
for( ; ; ); /* not reached */
}
+static __init void copy_mapping(unsigned long mfn, unsigned long end,
+ bool_t (*is_valid)(unsigned long smfn,
+ unsigned long emfn))
+{
+ unsigned long next;
+
+ for ( ; mfn < end; mfn = next )
+ {
+ l4_pgentry_t l4e = efi_l4_pgtable[l4_table_offset(mfn << PAGE_SHIFT)];
+ l3_pgentry_t *l3src, *l3dst;
+ unsigned long va = (unsigned long)mfn_to_virt(mfn);
+
+ next = mfn + (1UL << (L3_PAGETABLE_SHIFT - PAGE_SHIFT));
+ if ( !is_valid(mfn, min(next, end)) )
+ continue;
+ if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+ {
+ l3dst = alloc_xen_pagetable();
+ BUG_ON(!l3dst);
+ clear_page(l3dst);
+ efi_l4_pgtable[l4_table_offset(mfn << PAGE_SHIFT)] =
+ l4e_from_paddr(virt_to_maddr(l3dst), __PAGE_HYPERVISOR);
+ }
+ else
+ l3dst = l4e_to_l3e(l4e);
+ l3src = l4e_to_l3e(idle_pg_table[l4_table_offset(va)]);
+ l3dst[l3_table_offset(mfn << PAGE_SHIFT)] = l3src[l3_table_offset(va)];
+ }
+}
+
+static bool_t __init ram_range_valid(unsigned long smfn, unsigned long emfn)
+{
+ unsigned long sz = pfn_to_pdx(emfn - 1) / PDX_GROUP_COUNT + 1;
+
+ return !(smfn & pfn_hole_mask) &&
+ find_next_bit(pdx_group_valid, sz,
+ pfn_to_pdx(smfn) / PDX_GROUP_COUNT) < sz;
+}
+
+static bool_t __init rt_range_valid(unsigned long smfn, unsigned long emfn)
+{
+ return 1;
+}
+
+#define INVALID_VIRTUAL_ADDRESS (0xBAAADUL << \
+ (EFI_PAGE_SHIFT + BITS_PER_LONG - 32))
+
void __init efi_init_memory(void)
{
unsigned int i;
@@ -1169,11 +1217,11 @@ void __init efi_init_memory(void)
if ( !(desc->Attribute & EFI_MEMORY_RUNTIME) )
continue;
+ desc->VirtualStart = INVALID_VIRTUAL_ADDRESS;
+
smfn = PFN_DOWN(desc->PhysicalStart);
emfn = PFN_UP(desc->PhysicalStart + len);
- desc->VirtualStart = 0xBAAADUL << (EFI_PAGE_SHIFT + BITS_PER_LONG - 32);
-
if ( desc->Attribute & EFI_MEMORY_WB )
/* nothing */;
else if ( desc->Attribute & EFI_MEMORY_WT )
@@ -1217,5 +1265,34 @@ void __init efi_init_memory(void)
#if 0 /* Incompatible with kexec. */
efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size,
mdesc_ver, efi_memmap);
+#else
+ /* Set up 1:1 page tables to do runtime calls in "physical" mode. */
+ efi_l4_pgtable = alloc_xen_pagetable();
+ BUG_ON(!efi_l4_pgtable);
+ clear_page(efi_l4_pgtable);
+
+ copy_mapping(0, max_page, ram_range_valid);
+
+ /* Insert non-RAM runtime mappings. */
+ for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+ {
+ const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+
+ if ( desc->Attribute & EFI_MEMORY_RUNTIME )
+ {
+ if ( desc->VirtualStart != INVALID_VIRTUAL_ADDRESS )
+ copy_mapping(PFN_DOWN(desc->PhysicalStart),
+ PFN_UP(desc->PhysicalStart +
+ (desc->NumberOfPages << EFI_PAGE_SHIFT)),
+ rt_range_valid);
+ else
+ /* XXX */;
+ }
+ }
+
+ /* Insert Xen mappings. */
+ for ( i = l4_table_offset(HYPERVISOR_VIRT_START);
+ i < l4_table_offset(HYPERVISOR_VIRT_END); ++i )
+ efi_l4_pgtable[i] = idle_pg_table[i];
#endif
}
--- a/xen/arch/x86/efi/compat.c
+++ b/xen/arch/x86/efi/compat.c
@@ -4,13 +4,27 @@
#define efi_get_info efi_compat_get_info
#define xenpf_efi_info compat_pf_efi_info
+#define efi_runtime_call efi_compat_runtime_call
+#define xenpf_efi_runtime_call compat_pf_efi_runtime_call
+
+#define xenpf_efi_guid compat_pf_efi_guid
+#define xenpf_efi_time compat_pf_efi_time
+
#define COMPAT
#undef DEFINE_XEN_GUEST_HANDLE
#define DEFINE_XEN_GUEST_HANDLE DEFINE_COMPAT_HANDLE
+#undef XEN_GUEST_HANDLE
+#define XEN_GUEST_HANDLE COMPAT_HANDLE
#undef guest_handle_okay
#define guest_handle_okay compat_handle_okay
#undef guest_handle_cast
#define guest_handle_cast compat_handle_cast
+#undef __copy_from_guest
+#define __copy_from_guest __copy_from_compat
+#undef copy_from_guest_offset
+#define copy_from_guest_offset copy_from_compat_offset
+#undef copy_to_guest
+#define copy_to_guest copy_to_compat
#undef __copy_to_guest_offset
#define __copy_to_guest_offset __copy_to_compat_offset
#include "runtime.c"
--- a/xen/arch/x86/efi/efi.h
+++ b/xen/arch/x86/efi/efi.h
@@ -5,6 +5,8 @@
#include <efi/efidevp.h>
#include <efi/efiapi.h>
#include <xen/efi.h>
+#include <xen/spinlock.h>
+#include <asm/page.h>
extern unsigned int efi_num_ct;
extern EFI_CONFIGURATION_TABLE *efi_ct;
@@ -16,3 +18,8 @@ extern EFI_RUNTIME_SERVICES *efi_rs;
extern UINTN efi_memmap_size, efi_mdesc_size;
extern void *efi_memmap;
+
+extern l4_pgentry_t *efi_l4_pgtable;
+
+unsigned long efi_rs_enter(void);
+void efi_rs_leave(unsigned long);
--- a/xen/arch/x86/efi/runtime.c
+++ b/xen/arch/x86/efi/runtime.c
@@ -2,6 +2,7 @@
#include <xen/cache.h>
#include <xen/errno.h>
#include <xen/guest_access.h>
+#include <xen/time.h>
DEFINE_XEN_GUEST_HANDLE(CHAR16);
@@ -19,6 +20,7 @@ unsigned int __read_mostly efi_fw_revisi
const CHAR16 *__read_mostly efi_fw_vendor;
EFI_RUNTIME_SERVICES *__read_mostly efi_rs;
+static DEFINE_SPINLOCK(efi_rs_lock);
UINTN __read_mostly efi_memmap_size;
UINTN __read_mostly efi_mdesc_size;
@@ -30,6 +32,68 @@ struct efi __read_mostly efi = {
.smbios = EFI_INVALID_TABLE_ADDR,
};
+l4_pgentry_t *__read_mostly efi_l4_pgtable;
+
+unsigned long efi_rs_enter(void)
+{
+ unsigned long cr3 = read_cr3();
+
+ spin_lock(&efi_rs_lock);
+
+ /* prevent fixup_page_fault() from doing anything */
+ irq_enter();
+
+ write_cr3(virt_to_maddr(efi_l4_pgtable));
+
+ return cr3;
+}
+
+void efi_rs_leave(unsigned long cr3)
+{
+ write_cr3(cr3);
+ irq_exit();
+ spin_unlock(&efi_rs_lock);
+}
+
+unsigned long efi_get_time(void)
+{
+ EFI_TIME time;
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->GetTime(&time, NULL);
+ efi_rs_leave(cr3);
+
+ if ( EFI_ERROR(status) )
+ return 0;
+
+ return mktime(time.Year, time.Month, time.Day,
+ time.Hour, time.Minute, time.Second);
+}
+
+void efi_halt_system(void)
+{
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+ efi_rs_leave(cr3);
+
+ printk(XENLOG_WARNING "EFI: could not halt system (%#lx)\n", status);
+}
+
+void efi_reset_system(bool_t warm)
+{
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->ResetSystem(warm ? EfiResetWarm : EfiResetCold,
+ EFI_SUCCESS, 0, NULL);
+ efi_rs_leave(cr3);
+
+ printk(XENLOG_WARNING "EFI: could not reset system (%#lx)\n", status);
+}
+
#endif
int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
@@ -86,3 +150,267 @@ int efi_get_info(uint32_t idx, union xen
return 0;
}
+
+static long gwstrlen(XEN_GUEST_HANDLE(CHAR16) str)
+{
+ unsigned long len;
+
+ for ( len = 0; ; ++len )
+ {
+ CHAR16 c;
+
+ if ( copy_from_guest_offset(&c, str, len, 1) )
+ return -EFAULT;
+ if ( !c )
+ break;
+ }
+
+ return len;
+}
+
+static inline EFI_TIME *cast_time(struct xenpf_efi_time *time)
+{
+#define chk_fld(F, f) \
+ BUILD_BUG_ON(sizeof(cast_time(NULL)->F) != sizeof(time->f) || \
+ offsetof(EFI_TIME, F) != offsetof(struct xenpf_efi_time, f))
+ chk_fld(Year, year);
+ chk_fld(Month, month);
+ chk_fld(Day, day);
+ chk_fld(Hour, hour);
+ chk_fld(Minute, min);
+ chk_fld(Second, sec);
+ chk_fld(Nanosecond, ns);
+ chk_fld(TimeZone, tz);
+ chk_fld(Daylight, daylight);
+#undef chk_fld
+ return (void *)time;
+}
+
+static inline EFI_GUID *cast_guid(struct xenpf_efi_guid *guid)
+{
+#define chk_fld(n) \
+ BUILD_BUG_ON(sizeof(cast_guid(NULL)->Data##n) != sizeof(guid->data##n) || \
+ offsetof(EFI_GUID, Data##n) != \
+ offsetof(struct xenpf_efi_guid, data##n))
+ chk_fld(1);
+ chk_fld(2);
+ chk_fld(3);
+ chk_fld(4);
+#undef chk_fld
+ return (void *)guid;
+}
+
+int efi_runtime_call(struct xenpf_efi_runtime_call *op)
+{
+ unsigned long cr3;
+ EFI_STATUS status = EFI_NOT_STARTED;
+ int rc = 0;
+
+ switch ( op->function )
+ {
+ case XEN_EFI_get_time:
+ {
+ EFI_TIME_CAPABILITIES caps;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetTime(cast_time(&op->u.get_time.time), &caps);
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) )
+ {
+ op->u.get_time.resolution = caps.Resolution;
+ op->u.get_time.accuracy = caps.Accuracy;
+ if ( caps.SetsToZero )
+ op->misc = XEN_EFI_GET_TIME_SET_CLEARS_NS;
+ }
+ }
+ break;
+
+ case XEN_EFI_set_time:
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetTime(cast_time(&op->u.set_time));
+ efi_rs_leave(cr3);
+ break;
+
+ case XEN_EFI_get_wakeup_time:
+ {
+ BOOLEAN enabled, pending;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetWakeupTime(&enabled, &pending,
+ cast_time(&op->u.get_wakeup_time));
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) )
+ {
+ if ( enabled )
+ op->misc |= XEN_EFI_GET_WAKEUP_TIME_ENABLED;
+ if ( pending )
+ op->misc |= XEN_EFI_GET_WAKEUP_TIME_PENDING;
+ }
+ }
+ break;
+
+ case XEN_EFI_set_wakeup_time:
+ if ( op->misc & ~(XEN_EFI_SET_WAKEUP_TIME_ENABLE |
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY) )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetWakeupTime(!!(op->misc &
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE),
+ (op->misc &
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY) ?
+ NULL :
+ cast_time(&op->u.set_wakeup_time));
+ efi_rs_leave(cr3);
+
+ op->misc = 0;
+ break;
+
+ case XEN_EFI_get_next_high_monotonic_count:
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetNextHighMonotonicCount(&op->misc);
+ efi_rs_leave(cr3);
+ break;
+
+ case XEN_EFI_get_variable:
+ {
+ CHAR16 *name;
+ long len;
+ unsigned char *data;
+ UINTN size;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ len = gwstrlen(guest_handle_cast(op->u.get_variable.name, CHAR16));
+ if ( len < 0 )
+ return len;
+ name = xmalloc_array(CHAR16, ++len);
+ if ( !name )
+ return -ENOMEM;
+ __copy_from_guest(name, op->u.get_variable.name, len);
+
+ size = op->u.get_variable.size;
+ if ( size )
+ {
+ data = xmalloc_bytes(size);
+ if ( !data )
+ {
+ xfree(name);
+ return -ENOMEM;
+ }
+ }
+ else
+ data = NULL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetVariable(
+ name, cast_guid(&op->u.get_variable.vendor_guid),
+ &op->misc, &size, data);
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) &&
+ copy_to_guest(op->u.get_variable.data, data, size) )
+ rc = -EFAULT;
+ op->u.get_variable.size = size;
+
+ xfree(data);
+ xfree(name);
+ }
+ break;
+
+ case XEN_EFI_set_variable:
+ {
+ CHAR16 *name;
+ long len;
+ unsigned char *data;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ len = gwstrlen(guest_handle_cast(op->u.set_variable.name, CHAR16));
+ if ( len < 0 )
+ return len;
+ name = xmalloc_array(CHAR16, ++len);
+ if ( !name )
+ return -ENOMEM;
+ __copy_from_guest(name, op->u.set_variable.name, len);
+
+ data = xmalloc_bytes(op->u.set_variable.size);
+ if ( !data )
+ rc = -ENOMEM;
+ else if ( copy_from_guest(data, op->u.set_variable.data,
+ op->u.set_variable.size) )
+ rc = -EFAULT;
+ else
+ {
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetVariable(
+ name, cast_guid(&op->u.set_variable.vendor_guid),
+ op->misc, op->u.set_variable.size, data);
+ efi_rs_leave(cr3);
+ }
+
+ xfree(data);
+ xfree(name);
+ }
+ break;
+
+ case XEN_EFI_get_next_variable_name:
+ {
+ union {
+ CHAR16 *str;
+ unsigned char *raw;
+ } name;
+ UINTN size;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ size = op->u.get_next_variable_name.size;
+ name.raw = xmalloc_bytes(size);
+ if ( !name.raw )
+ return -ENOMEM;
+ copy_from_guest(name.raw, op->u.get_next_variable_name.name, size);
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetNextVariableName(
+ &size, name.str,
+ cast_guid(&op->u.get_next_variable_name.vendor_guid));
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) &&
+ copy_to_guest(op->u.get_next_variable_name.name, name.raw, size) )
+ rc = -EFAULT;
+ op->u.get_next_variable_name.size = size;
+
+ xfree(name.raw);
+ }
+ break;
+
+ default:
+ return -ENOSYS;
+ }
+
+#ifndef COMPAT
+ op->status = status;
+#else
+ op->status = (status & 0x3fffffff) | (status >> 62);
+#endif
+
+ return rc;
+}
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -1,6 +1,7 @@
#include <xen/efi.h>
#include <xen/errno.h>
#include <xen/init.h>
+#include <asm/bug.h>
#ifndef efi_enabled
const bool_t efi_enabled = 0;
@@ -8,6 +9,15 @@ const bool_t efi_enabled = 0;
void __init efi_init_memory(void) { }
+unsigned long efi_get_time(void)
+{
+ BUG();
+ return 0;
+}
+
+void efi_halt_system(void) { }
+void efi_reset_system(bool_t warm) { }
+
int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
{
return -ENOSYS;
@@ -15,3 +25,11 @@ int efi_get_info(uint32_t idx, union xen
int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *)
__attribute__((__alias__("efi_get_info")));
+
+int efi_runtime_call(struct xenpf_efi_runtime_call *op)
+{
+ return -ENOSYS;
+}
+
+int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *)
+ __attribute__((__alias__("efi_runtime_call")));
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -309,6 +309,17 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
}
break;
+ case XENPF_efi_runtime_call:
+ ret = xsm_efi_runtime_call();
+ if ( ret )
+ break;
+
+ ret = efi_runtime_call(&op->u.efi_runtime_call);
+ if ( ret == 0 &&
+ copy_field_to_guest(u_xenpf_op, op, u.efi_runtime_call) )
+ ret = -EFAULT;
+ break;
+
case XENPF_enter_acpi_sleep:
ret = xsm_acpi_sleep();
if ( ret )
--- a/xen/arch/x86/shutdown.c
+++ b/xen/arch/x86/shutdown.c
@@ -15,6 +15,7 @@
#include <xen/console.h>
#include <xen/shutdown.h>
#include <xen/acpi.h>
+#include <xen/efi.h>
#include <asm/msr.h>
#include <asm/regs.h>
#include <asm/mc146818rtc.h>
@@ -95,6 +96,7 @@ void machine_halt(void)
watchdog_disable();
console_start_sync();
local_irq_enable();
+ efi_halt_system();
smp_call_function(__machine_halt, NULL, 0);
__machine_halt(NULL);
}
@@ -337,6 +339,8 @@ void machine_restart(unsigned int delay_
if ( tboot_in_measured_env() )
tboot_shutdown(TB_SHUTDOWN_REBOOT);
+ efi_reset_system(reboot_mode != 0);
+
/* Rebooting needs to touch the page at absolute address 0. */
*((unsigned short *)__va(0x472)) = reboot_mode;
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -21,6 +21,7 @@
#include <xen/smp.h>
#include <xen/irq.h>
#include <xen/softirq.h>
+#include <xen/efi.h>
#include <xen/cpuidle.h>
#include <xen/keyhandler.h>
#include <xen/guest_access.h>
@@ -756,6 +757,13 @@ static unsigned long get_cmos_time(void)
unsigned long res, flags;
int i;
+ if ( efi_enabled )
+ {
+ res = efi_get_time();
+ if ( res )
+ return res;
+ }
+
spin_lock_irqsave(&rtc_lock, flags);
/* read RTC exactly on falling edge of update flag */
--- a/xen/arch/x86/x86_64/platform_hypercall.c
+++ b/xen/arch/x86/x86_64/platform_hypercall.c
@@ -12,6 +12,7 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_
#define do_platform_op(x) compat_platform_op(_##x)
#define efi_get_info efi_compat_get_info
+#define efi_runtime_call(x) efi_compat_runtime_call(x)
#define xen_processor_px compat_processor_px
#define xen_processor_px_t compat_processor_px_t
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -114,6 +114,77 @@ struct xenpf_platform_quirk {
typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
+#define XENPF_efi_runtime_call 49
+#define XEN_EFI_get_time 1
+#define XEN_EFI_set_time 2
+#define XEN_EFI_get_wakeup_time 3
+#define XEN_EFI_set_wakeup_time 4
+#define XEN_EFI_get_next_high_monotonic_count 5
+#define XEN_EFI_get_variable 6
+#define XEN_EFI_set_variable 7
+#define XEN_EFI_get_next_variable_name 8
+struct xenpf_efi_runtime_call {
+ uint32_t function;
+ /*
+ * This field is generally used for per sub-function flags (defined
+ * below), except for the XEN_EFI_get_next_high_monotonic_count case,
+ * where it holds the single returned value.
+ */
+ uint32_t misc;
+ unsigned long status;
+ union {
+#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001
+ struct {
+ struct xenpf_efi_time {
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t min;
+ uint8_t sec;
+ uint32_t ns;
+ int16_t tz;
+ uint8_t daylight;
+ } time;
+ uint32_t resolution;
+ uint32_t accuracy;
+ } get_time;
+
+ struct xenpf_efi_time set_time;
+
+#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001
+#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002
+ struct xenpf_efi_time get_wakeup_time;
+
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE 0x00000001
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002
+ struct xenpf_efi_time set_wakeup_time;
+
+#define XEN_EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define XEN_EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+ struct {
+ XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
+ unsigned long size;
+ XEN_GUEST_HANDLE(void) data;
+ struct xenpf_efi_guid {
+ uint32_t data1;
+ uint16_t data2;
+ uint16_t data3;
+ uint8_t data4[8];
+ } vendor_guid;
+ } get_variable, set_variable;
+
+ struct {
+ unsigned long size;
+ XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
+ struct xenpf_efi_guid vendor_guid;
+ } get_next_variable_name;
+ } u;
+};
+typedef struct xenpf_efi_runtime_call xenpf_efi_runtime_call_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t);
+
#define XENPF_firmware_info 50
#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
@@ -388,6 +459,7 @@ struct xen_platform_op {
struct xenpf_read_memtype read_memtype;
struct xenpf_microcode_update microcode;
struct xenpf_platform_quirk platform_quirk;
+ struct xenpf_efi_runtime_call efi_runtime_call;
struct xenpf_firmware_info firmware_info;
struct xenpf_enter_acpi_sleep enter_acpi_sleep;
struct xenpf_change_freq change_freq;
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -29,10 +29,18 @@ extern struct efi efi;
union xenpf_efi_info;
union compat_pf_efi_info;
+struct xenpf_efi_runtime_call;
+struct compat_pf_efi_runtime_call;
+
void efi_init_memory(void);
+unsigned long efi_get_time(void);
+void efi_halt_system(void);
+void efi_reset_system(bool_t warm);
#ifndef COMPAT
int efi_get_info(uint32_t idx, union xenpf_efi_info *);
+int efi_runtime_call(struct xenpf_efi_runtime_call *);
#endif
int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *);
+int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *);
#endif /* __XEN_EFI_H__ */
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -131,6 +131,7 @@ struct xsm_operations {
int (*physinfo) (void);
int (*platform_quirk) (uint32_t);
int (*firmware_info) (void);
+ int (*efi_runtime_call) (void);
int (*acpi_sleep) (void);
int (*change_freq) (void);
int (*getidletime) (void);
@@ -546,6 +547,11 @@ static inline int xsm_firmware_info (voi
return xsm_call(firmware_info());
}
+static inline int xsm_efi_runtime_call (void)
+{
+ return xsm_call(efi_runtime_call());
+}
+
static inline int xsm_acpi_sleep (void)
{
return xsm_call(acpi_sleep());

150
23616-x86_64-EFI-MPS.patch Normal file
View File

@ -0,0 +1,150 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1309249288 -3600
# Node ID dffcd8b4c197b58d2acb914d0e07a100e340f7ae
# Parent d19e778442673050bba8ea8cf61585902ff81162
x86-64: EFI MPS support
It's not clear this is needed - Linux doesn't use the MPS table even
if available, and no system having one was seen so far.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1309268736 -3600
# Node ID d22b64ccf088db8bfce1d6c4830f08e3e834ec84
# Parent 6d404796a8e587eb648a66f2859991d385b65eb6
x86_32: Fix build after EFI MPS patch.
Signed-off-by: Keir Fraser <keir@xen.org>
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -897,12 +897,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
{
static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
+ static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
efi.acpi20 = (long)efi_ct[i].VendorTable;
if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
efi.acpi = (long)efi_ct[i].VendorTable;
+ if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
+ efi.mps = (long)efi_ct[i].VendorTable;
if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
efi.smbios = (long)efi_ct[i].VendorTable;
}
--- a/xen/arch/x86/efi/runtime.c
+++ b/xen/arch/x86/efi/runtime.c
@@ -29,6 +29,7 @@ void *__read_mostly efi_memmap;
struct efi __read_mostly efi = {
.acpi = EFI_INVALID_TABLE_ADDR,
.acpi20 = EFI_INVALID_TABLE_ADDR,
+ .mps = EFI_INVALID_TABLE_ADDR,
.smbios = EFI_INVALID_TABLE_ADDR,
};
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -19,6 +19,8 @@
#include <xen/init.h>
#include <xen/acpi.h>
#include <xen/delay.h>
+#include <xen/efi.h>
+#include <xen/pfn.h>
#include <xen/sched.h>
#include <asm/mc146818rtc.h>
@@ -655,6 +657,14 @@ static inline void __init construct_defa
}
}
+#define FIX_EFI_MPF FIX_KEXEC_BASE_0
+
+static __init void efi_unmap_mpf(void)
+{
+ if (efi_enabled)
+ __set_fixmap(FIX_EFI_MPF, 0, 0);
+}
+
static struct intel_mp_floating *mpf_found;
/*
@@ -669,6 +679,7 @@ void __init get_smp_config (void)
* processors, where MPS only supports physical.
*/
if (acpi_lapic && acpi_ioapic) {
+ efi_unmap_mpf();
printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
return;
}
@@ -699,6 +709,7 @@ void __init get_smp_config (void)
* override the defaults.
*/
if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
+ efi_unmap_mpf();
smp_found_config = 0;
printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
@@ -725,6 +737,8 @@ void __init get_smp_config (void)
} else
BUG();
+ efi_unmap_mpf();
+
printk(KERN_INFO "Processors: %d\n", num_processors);
/*
* Only use the first configuration found.
@@ -779,10 +793,37 @@ static int __init smp_scan_config (unsig
return 0;
}
+static void __init efi_check_config(void)
+{
+ struct intel_mp_floating *mpf;
+
+ if (efi.mps == EFI_INVALID_TABLE_ADDR)
+ return;
+
+ __set_fixmap(FIX_EFI_MPF, PFN_DOWN(efi.mps), __PAGE_HYPERVISOR);
+ mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)efi.mps & (PAGE_SIZE-1));
+
+ if (memcmp(mpf->mpf_signature, "_MP_", 4) == 0 &&
+ mpf->mpf_length == 1 &&
+ mpf_checksum((void *)mpf, 16) &&
+ (mpf->mpf_specification == 1 || mpf->mpf_specification == 4)) {
+ smp_found_config = 1;
+ printk(KERN_INFO "SMP MP-table at %08lx\n", efi.mps);
+ mpf_found = mpf;
+ }
+ else
+ efi_unmap_mpf();
+}
+
void __init find_smp_config (void)
{
unsigned int address;
+ if (efi_enabled) {
+ efi_check_config();
+ return;
+ }
+
/*
* FIXME: Linux assumes you have 640K of base ram..
* this continues the error...
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -17,6 +17,7 @@ extern const bool_t efi_enabled;
/* Add fields here only if they need to be referenced from non-EFI code. */
struct efi {
+ unsigned long mps; /* MPS table */
unsigned long acpi; /* ACPI table (IA64 ext 0.71) */
unsigned long acpi20; /* ACPI table (ACPI 2.0) */
unsigned long smbios; /* SM BIOS table */

View File

@ -2,7 +2,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2913,7 +2913,7 @@ class XendDomainInfo:
@@ -2927,7 +2927,7 @@ class XendDomainInfo:
self.guest_bitsize = self.image.getBitSize()
# Make sure there's enough RAM available for the domain

157
change-vnc-passwd.patch Normal file
View File

@ -0,0 +1,157 @@
Add support of change-vnc-password while vm is running.
Signed-off-by: Chunyan Liu <cyliu@novell.com>
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/vl.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
@@ -200,7 +200,7 @@ DriveInfo drives_table[MAX_DRIVES+1];
int nb_drives;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int vga_ram_size;
-static DisplayState *display_state;
+DisplayState *display_state;
int nographic;
static int curses;
static int sdl;
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/vnc.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/vnc.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/vnc.c
@@ -2591,6 +2591,7 @@ int vnc_display_password(DisplayState *d
if (password && password[0]) {
if (!(vs->password = qemu_strdup(password)))
return -1;
+ vs->auth = VNC_AUTH_VNC;
}
return 0;
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/xenstore.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/xenstore.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/xenstore.c
@@ -25,6 +25,7 @@
#include "qemu-timer.h"
#include "qemu-xen.h"
+extern DisplayState *display_state;
struct xs_handle *xsh = NULL;
static char *media_filename[MAX_DRIVES+1];
static QEMUTimer *insert_timer = NULL;
@@ -1006,6 +1007,19 @@ static void xenstore_process_dm_command_
} else if (!strncmp(command, "continue", len)) {
fprintf(logfile, "dm-command: continue after state save\n");
xen_pause_requested = 0;
+ } else if (!strncmp(command, "chgvncpasswd", len)) {
+ fprintf(logfile, "dm-command: change vnc passwd\n");
+ if (pasprintf(&path,
+ "/local/domain/0/backend/vfb/%u/0/vncpasswd", domid) == -1) {
+ fprintf(logfile, "out of memory reading dm command parameter\n");
+ goto out;
+ }
+ par = xs_read(xsh, XBT_NULL, path, &len);
+ if (!par)
+ goto out;
+ if (vnc_display_password(display_state, par) == 0)
+ xenstore_record_dm_state("vncpasswdchged");
+ free(par);
} else if (!strncmp(command, "usb-add", len)) {
fprintf(logfile, "dm-command: usb-add a usb device\n");
if (pasprintf(&path,
Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1489,6 +1489,20 @@ class XendDomainInfo:
target = max_target
self.setMemoryTarget(target)
+ def chgvncpasswd(self, passwd):
+ if self._stateGet() != DOM_STATE_HALTED:
+ path = '/local/domain/0/backend/vfb/%u/0/' % self.getDomid()
+ xstransact.Write(path, 'vncpasswd', passwd)
+ self.image.signalDeviceModel("chgvncpasswd", "vncpasswdchged")
+
+ for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
+ if dev_type == 'vfb':
+ dev_info['vncpasswd'] = passwd
+ dev_info['other_config']['vncpasswd'] = passwd
+ self.info.device_update(dev_uuid, cfg_xenapi = dev_info)
+ break
+ xen.xend.XendDomain.instance().managed_config_save(self)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
Index: xen-4.1.1-testing/tools/python/xen/xend/server/XMLRPCServer.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/server/XMLRPCServer.py
+++ xen-4.1.1-testing/tools/python/xen/xend/server/XMLRPCServer.py
@@ -95,7 +95,7 @@ methods = ['device_create', 'device_conf
'destroyDevice','getDeviceSxprs',
'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
'send_sysrq', 'getVCPUInfo', 'waitForDevices',
- 'getRestartCount', 'getBlockDeviceClass']
+ 'getRestartCount', 'getBlockDeviceClass', 'chgvncpasswd']
exclude = ['domain_create', 'domain_restore']
Index: xen-4.1.1-testing/tools/python/xen/xm/main.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xm/main.py
+++ xen-4.1.1-testing/tools/python/xen/xm/main.py
@@ -21,6 +21,7 @@
"""Grand unified management application for Xen.
"""
+import getpass
import atexit
import cmd
import os
@@ -289,6 +290,9 @@ SUBCOMMAND_HELP = {
'getenforce' : ('', 'Returns the current enforcing mode for the Flask XSM module (Enforcing,Permissive)'),
'setenforce' : ('[ (Enforcing|1) | (Permissive|0) ]',
'Modifies the current enforcing mode for the Flask XSM module'),
+ #change vnc password
+ 'change-vnc-passwd' : ('<Domain>',\
+ 'Change vnc password'),
}
SUBCOMMAND_OPTIONS = {
@@ -421,6 +425,7 @@ common_commands = [
"usb-del",
"domstate",
"vcpu-set",
+ "change-vnc-passwd",
]
domain_commands = [
@@ -462,6 +467,7 @@ domain_commands = [
"vcpu-list",
"vcpu-pin",
"vcpu-set",
+ "change-vnc-passwd",
]
host_commands = [
@@ -3881,6 +3887,10 @@ def xm_cpupool_migrate(args):
else:
server.xend.cpu_pool.migrate(domname, poolname)
+def xm_chgvncpasswd(args):
+ arg_check(args, "change-vnc-passwd", 1)
+ pwd = getpass.getpass("Enter new password: ")
+ server.xend.domain.chgvncpasswd(args[0], pwd)
commands = {
"shell": xm_shell,
@@ -3993,6 +4003,8 @@ commands = {
"usb-del": xm_usb_del,
#domstate
"domstate": xm_domstate,
+ #change vnc password:
+ "change-vnc-passwd": xm_chgvncpasswd,
}
## The commands supported by a separate argument parser in xend.xm.

View File

@ -2,7 +2,7 @@ Index: xen-4.1.1-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.
===================================================================
--- xen-4.1.1-testing.orig/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ xen-4.1.1-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -425,6 +425,11 @@ static int __devinit platform_pci_init(s
@@ -426,6 +426,11 @@ static int __devinit platform_pci_init(s
platform_mmio = mmio_addr;
platform_mmiolen = mmio_len;

View File

@ -10,7 +10,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendConfig.py
'rtc_timeoffset': int,
'parallel': str,
'serial': str,
@@ -515,6 +516,8 @@ class XendConfig(dict):
@@ -517,6 +518,8 @@ class XendConfig(dict):
if self.is_hvm():
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
@ -46,16 +46,16 @@ Index: xen-4.1.1-testing/tools/python/xen/xm/create.py
gopts.var('acpi', val='ACPI',
fn=set_int, default=1,
use="Disable or enable ACPI of HVM domain.")
@@ -1091,7 +1095,7 @@ def configure_hvm(config_image, vals):
@@ -1106,7 +1110,7 @@ def configure_hvm(config_image, vals):
'timer_mode',
'usb', 'usbdevice',
'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten',
- 'vncunused', 'viridian', 'vpt_align',
+ 'vncunused', 'vpt_align',
'watchdog', 'watchdog_action',
'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci',
'memory_sharing' ]
@@ -1100,6 +1104,10 @@ def configure_hvm(config_image, vals):
@@ -1116,6 +1120,10 @@ def configure_hvm(config_image, vals):
config_image.append([a, vals.__dict__[a]])
if vals.vncpasswd is not None:
config_image.append(['vncpasswd', vals.vncpasswd])

View File

@ -24,7 +24,7 @@ Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/vl.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
@@ -5830,9 +5830,9 @@ int main(int argc, char **argv, char **e
@@ -5852,9 +5852,9 @@ int main(int argc, char **argv, char **e
if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s)))
fprintf(stderr,"Can not read our own domid: %s\n", msg);
else
@ -40,7 +40,7 @@ Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/xenstore.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/xenstore.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/xenstore.c
@@ -447,7 +447,7 @@ void xenstore_init(void)
@@ -448,7 +448,7 @@ void xenstore_init(void)
}
}
@ -49,7 +49,7 @@ Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/xenstore.c
{
char **e_danger = NULL;
char *buf = NULL;
@@ -760,15 +760,19 @@ void xenstore_parse_domain_config(int hv
@@ -761,15 +761,19 @@ void xenstore_parse_domain_config(int hv
#endif

View File

@ -0,0 +1,34 @@
Subject: qdev: convert watchdogs
From: Markus Armbruster armbru@redhat.com Fri Aug 21 10:31:34 2009 +0200
Date: Thu Aug 27 20:35:24 2009 -0500:
Git: 09aaa1602f9381c0e0fb539390b1793e51bdfc7b
* THIS IS ONLY THE BUG FIX PART OF THE UPSTREAM PATCH *
Fixes ib700 not to use vm_clock before it is initialized: in
wdt_ib700_init(), called from register_watchdogs(), which runs before
init_timers(). The bug made ib700_write_enable_reg() crash in
qemu_del_timer().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_ib700.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/wdt_ib700.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_ib700.c
@@ -93,6 +93,7 @@ static int ib700_load(QEMUFile *f, void
/* Create and initialize a virtual IB700 during PC creation. */
static void ib700_pc_init(PCIBus *unused)
{
+ timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL);
register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL);
@@ -108,5 +109,4 @@ static WatchdogTimerModel model = {
void wdt_ib700_init(void)
{
watchdog_add_model(&model);
- timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
}

View File

@ -0,0 +1,72 @@
Subject: Move watchdog, watchdog_action, give them internal linkage
From: Markus Armbruster armbru@redhat.com Fri Aug 21 10:31:32 2009 +0200
Date: Thu Aug 27 20:30:23 2009 -0500:
Git: 88b3be201acf64e0bd19782bebd533901c951c87
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/watchdog.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.c
@@ -26,6 +26,16 @@
#include "sysemu.h"
#include "hw/watchdog.h"
+/* Possible values for action parameter. */
+#define WDT_RESET 1 /* Hard reset. */
+#define WDT_SHUTDOWN 2 /* Shutdown. */
+#define WDT_POWEROFF 3 /* Quit. */
+#define WDT_PAUSE 4 /* Pause. */
+#define WDT_DEBUG 5 /* Prints a message and continues running. */
+#define WDT_NONE 6 /* Do nothing. */
+
+static WatchdogTimerModel *watchdog;
+static int watchdog_action = WDT_RESET;
static LIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
void watchdog_add_model(WatchdogTimerModel *model)
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.h
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/watchdog.h
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.h
@@ -27,13 +27,6 @@
extern void wdt_i6300esb_init(void);
extern void wdt_ib700_init(void);
-/* Possible values for action parameter. */
-#define WDT_RESET 1 /* Hard reset. */
-#define WDT_SHUTDOWN 2 /* Shutdown. */
-#define WDT_POWEROFF 3 /* Quit. */
-#define WDT_PAUSE 4 /* Pause. */
-#define WDT_DEBUG 5 /* Prints a message and continues running. */
-#define WDT_NONE 6 /* Do nothing. */
struct WatchdogTimerModel {
LIST_ENTRY(WatchdogTimerModel) entry;
@@ -50,10 +43,6 @@ struct WatchdogTimerModel {
};
typedef struct WatchdogTimerModel WatchdogTimerModel;
-/* in vl.c */
-extern WatchdogTimerModel *watchdog;
-extern int watchdog_action;
-
/* in hw/watchdog.c */
extern int select_watchdog(const char *p);
extern int select_watchdog_action(const char *action);
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/vl.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
@@ -250,8 +250,6 @@ int no_shutdown = 0;
int cursor_hide = 1;
int graphic_rotate = 0;
int daemonize = 0;
-WatchdogTimerModel *watchdog = NULL;
-int watchdog_action = WDT_RESET;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;

View File

@ -0,0 +1,963 @@
Subject: Hardware watchdog
From: Richard W.M. Jones rjones@redhat.com Sat Apr 25 13:56:19 2009 +0100
Date: Fri May 1 09:44:11 2009 -0500:
Git: 9dd986ccf68f142aaafe543d80cf877716d91d4e
Here is an updated hardware watchdog patch, which should fix
everything that was raised about the previous version ...
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/Makefile.target
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/Makefile.target
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/Makefile.target
@@ -580,6 +580,10 @@ OBJS += e1000.o
# Serial mouse
OBJS += msmouse.o
+# Generic watchdog support and some watchdog devices
+OBJS += watchdog.o
+OBJS += wdt_ib700.o wdt_i6300esb.o
+
ifeq ($(TARGET_BASE_ARCH), i386)
# Hardware support
ifdef CONFIG_AUDIO
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/pc.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/pc.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/pc.c
@@ -41,6 +41,7 @@
#include "virtio-balloon.h"
#include "virtio-console.h"
#include "hpet_emul.h"
+#include "watchdog.h"
#ifdef CONFIG_PASSTHROUGH
#include "pass-through.h"
@@ -1050,6 +1051,8 @@ vga_bios_error:
}
}
+ watchdog_pc_init(pci_bus);
+
for(i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.c
===================================================================
--- /dev/null
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.c
@@ -0,0 +1,136 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include "qemu-common.h"
+#include "sys-queue.h"
+#include "sysemu.h"
+#include "hw/watchdog.h"
+
+static LIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
+
+void watchdog_add_model(WatchdogTimerModel *model)
+{
+ LIST_INSERT_HEAD(&watchdog_list, model, entry);
+}
+
+/* Returns:
+ * 0 = continue
+ * 1 = exit program with error
+ * 2 = exit program without error
+ */
+int select_watchdog(const char *p)
+{
+ WatchdogTimerModel *model;
+
+ if (watchdog) {
+ fprintf(stderr,
+ "qemu: only one watchdog option may be given\n");
+ return 1;
+ }
+
+ /* -watchdog ? lists available devices and exits cleanly. */
+ if (strcmp(p, "?") == 0) {
+ LIST_FOREACH(model, &watchdog_list, entry) {
+ fprintf(stderr, "\t%s\t%s\n",
+ model->wdt_name, model->wdt_description);
+ }
+ return 2;
+ }
+
+ LIST_FOREACH(model, &watchdog_list, entry) {
+ if (strcasecmp(model->wdt_name, p) == 0) {
+ watchdog = model;
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");
+ LIST_FOREACH(model, &watchdog_list, entry) {
+ fprintf(stderr, "\t%s\t%s\n",
+ model->wdt_name, model->wdt_description);
+ }
+ return 1;
+}
+
+int select_watchdog_action(const char *p)
+{
+ if (strcasecmp(p, "reset") == 0)
+ watchdog_action = WDT_RESET;
+ else if (strcasecmp(p, "shutdown") == 0)
+ watchdog_action = WDT_SHUTDOWN;
+ else if (strcasecmp(p, "poweroff") == 0)
+ watchdog_action = WDT_POWEROFF;
+ else if (strcasecmp(p, "pause") == 0)
+ watchdog_action = WDT_PAUSE;
+ else if (strcasecmp(p, "debug") == 0)
+ watchdog_action = WDT_DEBUG;
+ else if (strcasecmp(p, "none") == 0)
+ watchdog_action = WDT_NONE;
+ else
+ return -1;
+
+ return 0;
+}
+
+/* This actually performs the "action" once a watchdog has expired,
+ * ie. reboot, shutdown, exit, etc.
+ */
+void watchdog_perform_action(void)
+{
+ switch(watchdog_action) {
+ case WDT_RESET: /* same as 'system_reset' in monitor */
+ qemu_system_reset_request();
+ break;
+
+ case WDT_SHUTDOWN: /* same as 'system_powerdown' in monitor */
+ qemu_system_powerdown_request();
+ break;
+
+ case WDT_POWEROFF: /* same as 'quit' command in monitor */
+ exit(0);
+ break;
+
+ case WDT_PAUSE: /* same as 'stop' command in monitor */
+ vm_stop(0);
+ break;
+
+ case WDT_DEBUG:
+ fprintf(stderr, "watchdog: timer fired\n");
+ break;
+
+ case WDT_NONE:
+ break;
+ }
+}
+
+void watchdog_pc_init(PCIBus *pci_bus)
+{
+ if (watchdog)
+ watchdog->wdt_pc_init(pci_bus);
+}
+
+void register_watchdogs(void)
+{
+ wdt_ib700_init();
+ wdt_i6300esb_init();
+}
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.h
===================================================================
--- /dev/null
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/watchdog.h
@@ -0,0 +1,65 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#ifndef QEMU_WATCHDOG_H
+#define QEMU_WATCHDOG_H
+
+extern void wdt_i6300esb_init(void);
+extern void wdt_ib700_init(void);
+
+/* Possible values for action parameter. */
+#define WDT_RESET 1 /* Hard reset. */
+#define WDT_SHUTDOWN 2 /* Shutdown. */
+#define WDT_POWEROFF 3 /* Quit. */
+#define WDT_PAUSE 4 /* Pause. */
+#define WDT_DEBUG 5 /* Prints a message and continues running. */
+#define WDT_NONE 6 /* Do nothing. */
+
+struct WatchdogTimerModel {
+ LIST_ENTRY(WatchdogTimerModel) entry;
+
+ /* Short name of the device - used to select it on the command line. */
+ const char *wdt_name;
+ /* Longer description (eg. manufacturer and full model number). */
+ const char *wdt_description;
+
+ /* This callback should create/register the device. It is called
+ * indirectly from hw/pc.c when the virtual PC is being set up.
+ */
+ void (*wdt_pc_init)(PCIBus *pci_bus);
+};
+typedef struct WatchdogTimerModel WatchdogTimerModel;
+
+/* in vl.c */
+extern WatchdogTimerModel *watchdog;
+extern int watchdog_action;
+
+/* in hw/watchdog.c */
+extern int select_watchdog(const char *p);
+extern int select_watchdog_action(const char *action);
+extern void watchdog_add_model(WatchdogTimerModel *model);
+extern void watchdog_perform_action(void);
+extern void watchdog_pc_init(PCIBus *pci_bus);
+extern void register_watchdogs(void);
+
+#endif /* QEMU_WATCHDOG_H */
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_i6300esb.c
===================================================================
--- /dev/null
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_i6300esb.c
@@ -0,0 +1,470 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include <inttypes.h>
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "watchdog.h"
+#include "hw.h"
+#include "isa.h"
+#include "pc.h"
+#include "pci.h"
+
+/*#define I6300ESB_DEBUG 1*/
+
+#ifdef I6300ESB_DEBUG
+#define i6300esb_debug(fs,...) \
+ fprintf(stderr,"i6300esb: %s: "fs,__func__,##__VA_ARGS__)
+#else
+#define i6300esb_debug(fs,...)
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_ESB_9
+#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
+#endif
+
+/* PCI configuration registers */
+#define ESB_CONFIG_REG 0x60 /* Config register */
+#define ESB_LOCK_REG 0x68 /* WDT lock register */
+
+/* Memory mapped registers (offset from base address) */
+#define ESB_TIMER1_REG 0x00 /* Timer1 value after each reset */
+#define ESB_TIMER2_REG 0x04 /* Timer2 value after each reset */
+#define ESB_GINTSR_REG 0x08 /* General Interrupt Status Register */
+#define ESB_RELOAD_REG 0x0c /* Reload register */
+
+/* Lock register bits */
+#define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
+#define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */
+#define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */
+
+/* Config register bits */
+#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
+#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
+#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
+
+/* Reload register bits */
+#define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */
+
+/* Magic constants */
+#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
+#define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */
+
+/* Device state. */
+struct I6300State {
+ PCIDevice dev; /* PCI device state, must be first field. */
+
+ int reboot_enabled; /* "Reboot" on timer expiry. The real action
+ * performed depends on the -watchdog-action
+ * param passed on QEMU command line.
+ */
+ int clock_scale; /* Clock scale. */
+#define CLOCK_SCALE_1KHZ 0
+#define CLOCK_SCALE_1MHZ 1
+
+ int int_type; /* Interrupt type generated. */
+#define INT_TYPE_IRQ 0 /* APIC 1, INT 10 */
+#define INT_TYPE_SMI 2
+#define INT_TYPE_DISABLED 3
+
+ int free_run; /* If true, reload timer on expiry. */
+ int locked; /* If true, enabled field cannot be changed. */
+ int enabled; /* If true, watchdog is enabled. */
+
+ QEMUTimer *timer; /* The actual watchdog timer. */
+
+ uint32_t timer1_preload; /* Values preloaded into timer1, timer2. */
+ uint32_t timer2_preload;
+ int stage; /* Stage (1 or 2). */
+
+ int unlock_state; /* Guest writes 0x80, 0x86 to unlock the
+ * registers, and we transition through
+ * states 0 -> 1 -> 2 when this happens.
+ */
+
+ int previous_reboot_flag; /* If the watchdog caused the previous
+ * reboot, this flag will be set.
+ */
+};
+
+typedef struct I6300State I6300State;
+
+/* This function is called when the watchdog has either been enabled
+ * (hence it starts counting down) or has been keep-alived.
+ */
+static void i6300esb_restart_timer(I6300State *d, int stage)
+{
+ int64_t timeout;
+
+ if (!d->enabled)
+ return;
+
+ d->stage = stage;
+
+ if (d->stage <= 1)
+ timeout = d->timer1_preload;
+ else
+ timeout = d->timer2_preload;
+
+ if (d->clock_scale == CLOCK_SCALE_1KHZ)
+ timeout <<= 15;
+ else
+ timeout <<= 5;
+
+ /* Get the timeout in units of ticks_per_sec. */
+ timeout = ticks_per_sec * timeout / 33000000;
+
+ i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
+
+ qemu_mod_timer(d->timer, qemu_get_clock(vm_clock) + timeout);
+}
+
+/* This is called when the guest disables the watchdog. */
+static void i6300esb_disable_timer(I6300State *d)
+{
+ i6300esb_debug("timer disabled\n");
+
+ qemu_del_timer(d->timer);
+}
+
+static void i6300esb_reset(I6300State *d)
+{
+ /* XXX We should probably reset other parts of the state here,
+ * but we should also reset our state on general machine reset
+ * too. For now just disable the timer so it doesn't fire
+ * again after the reboot.
+ */
+ i6300esb_disable_timer(d);
+}
+
+/* This function is called when the watchdog expires. Note that
+ * the hardware has two timers, and so expiry happens in two stages.
+ * If d->stage == 1 then we perform the first stage action (usually,
+ * sending an interrupt) and then restart the timer again for the
+ * second stage. If the second stage expires then the watchdog
+ * really has run out.
+ */
+static void i6300esb_timer_expired(void *vp)
+{
+ I6300State *d = (I6300State *) vp;
+
+ i6300esb_debug("stage %d\n", d->stage);
+
+ if (d->stage == 1) {
+ /* What to do at the end of stage 1? */
+ switch (d->int_type) {
+ case INT_TYPE_IRQ:
+ fprintf(stderr, "i6300esb_timer_expired: I would send APIC 1 INT 10 here if I knew how (XXX)\n");
+ break;
+ case INT_TYPE_SMI:
+ fprintf(stderr, "i6300esb_timer_expired: I would send SMI here if I knew how (XXX)\n");
+ break;
+ }
+
+ /* Start the second stage. */
+ i6300esb_restart_timer(d, 2);
+ } else {
+ /* Second stage expired, reboot for real. */
+ if (d->reboot_enabled) {
+ d->previous_reboot_flag = 1;
+ watchdog_perform_action(); /* This reboots, exits, etc */
+ i6300esb_reset(d);
+ }
+
+ /* In "free running mode" we start stage 1 again. */
+ if (d->free_run)
+ i6300esb_restart_timer(d, 1);
+ }
+}
+
+static void i6300esb_config_write(PCIDevice *dev, uint32_t addr,
+ uint32_t data, int len)
+{
+ I6300State *d = (I6300State *) dev;
+ int old;
+
+ i6300esb_debug("addr = %x, data = %x, len = %d\n", addr, data, len);
+
+ if (addr == ESB_CONFIG_REG && len == 2) {
+ d->reboot_enabled = (data & ESB_WDT_REBOOT) == 0;
+ d->clock_scale =
+ (data & ESB_WDT_FREQ) != 0 ? CLOCK_SCALE_1MHZ : CLOCK_SCALE_1KHZ;
+ d->int_type = (data & ESB_WDT_INTTYPE);
+ } else if (addr == ESB_LOCK_REG && len == 1) {
+ if (!d->locked) {
+ d->locked = (data & ESB_WDT_LOCK) != 0;
+ d->free_run = (data & ESB_WDT_FUNC) != 0;
+ old = d->enabled;
+ d->enabled = (data & ESB_WDT_ENABLE) != 0;
+ if (!old && d->enabled) /* Enabled transitioned from 0 -> 1 */
+ i6300esb_restart_timer(d, 1);
+ else if (!d->enabled)
+ i6300esb_disable_timer(d);
+ }
+ } else {
+ pci_default_write_config(dev, addr, data, len);
+ }
+}
+
+static uint32_t i6300esb_config_read(PCIDevice *dev, uint32_t addr, int len)
+{
+ I6300State *d = (I6300State *) dev;
+ uint32_t data;
+
+ i6300esb_debug ("addr = %x, len = %d\n", addr, len);
+
+ if (addr == ESB_CONFIG_REG && len == 2) {
+ data =
+ (d->reboot_enabled ? 0 : ESB_WDT_REBOOT) |
+ (d->clock_scale == CLOCK_SCALE_1MHZ ? ESB_WDT_FREQ : 0) |
+ d->int_type;
+ return data;
+ } else if (addr == ESB_LOCK_REG && len == 1) {
+ data =
+ (d->free_run ? ESB_WDT_FUNC : 0) |
+ (d->locked ? ESB_WDT_LOCK : 0) |
+ (d->enabled ? ESB_WDT_ENABLE : 0);
+ return data;
+ } else {
+ return pci_default_read_config(dev, addr, len);
+ }
+}
+
+static uint32_t i6300esb_mem_readb(void *vp, target_phys_addr_t addr)
+{
+ i6300esb_debug ("addr = %x\n", (int) addr);
+
+ return 0;
+}
+
+static uint32_t i6300esb_mem_readw(void *vp, target_phys_addr_t addr)
+{
+ uint32_t data = 0;
+ I6300State *d = (I6300State *) vp;
+
+ i6300esb_debug("addr = %x\n", (int) addr);
+
+ if (addr == 0xc) {
+ /* The previous reboot flag is really bit 9, but there is
+ * a bug in the Linux driver where it thinks it's bit 12.
+ * Set both.
+ */
+ data = d->previous_reboot_flag ? 0x1200 : 0;
+ }
+
+ return data;
+}
+
+static uint32_t i6300esb_mem_readl(void *vp, target_phys_addr_t addr)
+{
+ i6300esb_debug("addr = %x\n", (int) addr);
+
+ return 0;
+}
+
+static void i6300esb_mem_writeb(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+ I6300State *d = (I6300State *) vp;
+
+ i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
+
+ if (addr == 0xc && val == 0x80)
+ d->unlock_state = 1;
+ else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+ d->unlock_state = 2;
+}
+
+static void i6300esb_mem_writew(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+ I6300State *d = (I6300State *) vp;
+
+ i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
+
+ if (addr == 0xc && val == 0x80)
+ d->unlock_state = 1;
+ else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+ d->unlock_state = 2;
+ else {
+ if (d->unlock_state == 2) {
+ if (addr == 0xc) {
+ if ((val & 0x100) != 0)
+ /* This is the "ping" from the userspace watchdog in
+ * the guest ...
+ */
+ i6300esb_restart_timer(d, 1);
+
+ /* Setting bit 9 resets the previous reboot flag.
+ * There's a bug in the Linux driver where it sets
+ * bit 12 instead.
+ */
+ if ((val & 0x200) != 0 || (val & 0x1000) != 0) {
+ d->previous_reboot_flag = 0;
+ }
+ }
+
+ d->unlock_state = 0;
+ }
+ }
+}
+
+static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+ I6300State *d = (I6300State *) vp;
+
+ i6300esb_debug ("addr = %x, val = %x\n", (int) addr, val);
+
+ if (addr == 0xc && val == 0x80)
+ d->unlock_state = 1;
+ else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+ d->unlock_state = 2;
+ else {
+ if (d->unlock_state == 2) {
+ if (addr == 0)
+ d->timer1_preload = val & 0xfffff;
+ else if (addr == 4)
+ d->timer2_preload = val & 0xfffff;
+
+ d->unlock_state = 0;
+ }
+ }
+}
+
+static void i6300esb_map(PCIDevice *dev, int region_num,
+ uint32_t addr, uint32_t size, int type)
+{
+ static CPUReadMemoryFunc *mem_read[3] = {
+ i6300esb_mem_readb,
+ i6300esb_mem_readw,
+ i6300esb_mem_readl,
+ };
+ static CPUWriteMemoryFunc *mem_write[3] = {
+ i6300esb_mem_writeb,
+ i6300esb_mem_writew,
+ i6300esb_mem_writel,
+ };
+ I6300State *d = (I6300State *) dev;
+ int io_mem;
+
+ i6300esb_debug("addr = %x, size = %x, type = %d\n", addr, size, type);
+
+ io_mem = cpu_register_io_memory (0, mem_read, mem_write, d);
+ cpu_register_physical_memory (addr, 0x10, io_mem);
+ /* qemu_register_coalesced_mmio (addr, 0x10); ? */
+}
+
+static void i6300esb_save(QEMUFile *f, void *vp)
+{
+ I6300State *d = (I6300State *) vp;
+
+ pci_device_save(&d->dev, f);
+ qemu_put_be32(f, d->reboot_enabled);
+ qemu_put_be32(f, d->clock_scale);
+ qemu_put_be32(f, d->int_type);
+ qemu_put_be32(f, d->free_run);
+ qemu_put_be32(f, d->locked);
+ qemu_put_be32(f, d->enabled);
+ qemu_put_timer(f, d->timer);
+ qemu_put_be32(f, d->timer1_preload);
+ qemu_put_be32(f, d->timer2_preload);
+ qemu_put_be32(f, d->stage);
+ qemu_put_be32(f, d->unlock_state);
+ qemu_put_be32(f, d->previous_reboot_flag);
+}
+
+static int i6300esb_load(QEMUFile *f, void *vp, int version)
+{
+ I6300State *d = (I6300State *) vp;
+
+ if (version != sizeof (I6300State))
+ return -EINVAL;
+
+ pci_device_load(&d->dev, f);
+ d->reboot_enabled = qemu_get_be32(f);
+ d->clock_scale = qemu_get_be32(f);
+ d->int_type = qemu_get_be32(f);
+ d->free_run = qemu_get_be32(f);
+ d->locked = qemu_get_be32(f);
+ d->enabled = qemu_get_be32(f);
+ qemu_get_timer(f, d->timer);
+ d->timer1_preload = qemu_get_be32(f);
+ d->timer2_preload = qemu_get_be32(f);
+ d->stage = qemu_get_be32(f);
+ d->unlock_state = qemu_get_be32(f);
+ d->previous_reboot_flag = qemu_get_be32(f);
+
+ return 0;
+}
+
+/* Create and initialize a virtual Intel 6300ESB during PC creation. */
+static void i6300esb_pc_init(PCIBus *pci_bus)
+{
+ I6300State *d;
+ uint8_t *pci_conf;
+
+ if (!pci_bus) {
+ fprintf(stderr, "wdt_i6300esb: no PCI bus in this machine\n");
+ return;
+ }
+
+ d = (I6300State *)
+ pci_register_device (pci_bus, "i6300esb_wdt", sizeof (I6300State),
+ -1,
+ i6300esb_config_read, i6300esb_config_write);
+
+ d->reboot_enabled = 1;
+ d->clock_scale = CLOCK_SCALE_1KHZ;
+ d->int_type = INT_TYPE_IRQ;
+ d->free_run = 0;
+ d->locked = 0;
+ d->enabled = 0;
+ d->timer = qemu_new_timer(vm_clock, i6300esb_timer_expired, d);
+ d->timer1_preload = 0xfffff;
+ d->timer2_preload = 0xfffff;
+ d->stage = 1;
+ d->unlock_state = 0;
+ d->previous_reboot_flag = 0;
+
+ pci_conf = d->dev.config;
+ pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
+ pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9);
+ pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
+ pci_conf[0x0e] = 0x00;
+
+ pci_register_io_region(&d->dev, 0, 0x10,
+ PCI_ADDRESS_SPACE_MEM, i6300esb_map);
+
+ register_savevm("i6300esb_wdt", -1, sizeof(I6300State),
+ i6300esb_save, i6300esb_load, d);
+}
+
+static WatchdogTimerModel model = {
+ .wdt_name = "i6300esb",
+ .wdt_description = "Intel 6300ESB",
+ .wdt_pc_init = i6300esb_pc_init,
+};
+
+void wdt_i6300esb_init(void)
+{
+ watchdog_add_model(&model);
+}
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_ib700.c
===================================================================
--- /dev/null
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/wdt_ib700.c
@@ -0,0 +1,112 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "watchdog.h"
+#include "hw.h"
+#include "isa.h"
+#include "pc.h"
+
+/*#define IB700_DEBUG 1*/
+
+#ifdef IB700_DEBUG
+#define ib700_debug(fs,...) \
+ fprintf(stderr,"ib700: %s: "fs,__func__,##__VA_ARGS__)
+#else
+#define ib700_debug(fs,...)
+#endif
+
+/* This is the timer. We use a global here because the watchdog
+ * code ensures there is only one watchdog (it is located at a fixed,
+ * unchangable IO port, so there could only ever be one anyway).
+ */
+static QEMUTimer *timer = NULL;
+
+/* A write to this register enables the timer. */
+static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data)
+{
+ static int time_map[] = {
+ 30, 28, 26, 24, 22, 20, 18, 16,
+ 14, 12, 10, 8, 6, 4, 2, 0
+ };
+ int64 timeout;
+
+ ib700_debug("addr = %x, data = %x\n", addr, data);
+
+ timeout = (int64_t) time_map[data & 0xF] * ticks_per_sec;
+ qemu_mod_timer(timer, qemu_get_clock (vm_clock) + timeout);
+}
+
+/* A write (of any value) to this register disables the timer. */
+static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data)
+{
+ ib700_debug("addr = %x, data = %x\n", addr, data);
+
+ qemu_del_timer(timer);
+}
+
+/* This is called when the watchdog expires. */
+static void ib700_timer_expired(void *vp)
+{
+ ib700_debug("watchdog expired\n");
+
+ watchdog_perform_action();
+ qemu_del_timer(timer);
+}
+
+static void ib700_save(QEMUFile *f, void *vp)
+{
+ qemu_put_timer(f, timer);
+}
+
+static int ib700_load(QEMUFile *f, void *vp, int version)
+{
+ if (version != 0)
+ return -EINVAL;
+
+ qemu_get_timer(f, timer);
+
+ return 0;
+}
+
+/* Create and initialize a virtual IB700 during PC creation. */
+static void ib700_pc_init(PCIBus *unused)
+{
+ register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL);
+
+ register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL);
+ register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL);
+}
+
+static WatchdogTimerModel model = {
+ .wdt_name = "ib700",
+ .wdt_description = "iBASE 700",
+ .wdt_pc_init = ib700_pc_init,
+};
+
+void wdt_ib700_init(void)
+{
+ watchdog_add_model(&model);
+ timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
+}
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/monitor.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/monitor.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/monitor.c
@@ -26,6 +26,7 @@
#include "hw/pcmcia.h"
#include "hw/pc.h"
#include "hw/pci.h"
+#include "hw/watchdog.h"
#include "gdbstub.h"
#include "net.h"
#include "qemu-char.h"
@@ -531,6 +532,13 @@ static void do_gdbserver(const char *por
}
#endif
+static void do_watchdog_action(const char *action)
+{
+ if (select_watchdog_action(action) == -1) {
+ qemu_printf("Unknown watchdog action '%s'\n", action);
+ }
+}
+
static void term_printc(int c)
{
term_printf("'");
@@ -1605,6 +1613,8 @@ static const term_cmd_t term_cmds[] = {
"target", "request VM to change it's memory allocation (in MB)" },
{ "set_link", "ss", do_set_link,
"name [up|down]", "change the link status of a network adapter" },
+ { "watchdog_action", "s", do_watchdog_action,
+ "[reset|shutdown|poweroff|pause|debug|none]", "change watchdog action" },
{ "cpu_set", "is", do_cpu_set_nr,
"cpu [online|offline]", "change cpu state" },
{ NULL, NULL, },
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/vl.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/vl.c
@@ -30,6 +30,7 @@
#include "hw/isa.h"
#include "hw/baum.h"
#include "hw/bt.h"
+#include "hw/watchdog.h"
#include "net.h"
#include "console.h"
#include "sysemu.h"
@@ -249,6 +250,8 @@ int no_shutdown = 0;
int cursor_hide = 1;
int graphic_rotate = 0;
int daemonize = 0;
+WatchdogTimerModel *watchdog = NULL;
+int watchdog_action = WDT_RESET;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
@@ -4167,6 +4170,10 @@ static void help(int exitcode)
"-startdate select initial date of the clock\n"
"-icount [N|auto]\n"
" enable virtual instruction counter with 2^N clock ticks per instruction\n"
+ "-watchdog i6300esb|ib700\n"
+ " enable virtual hardware watchdog [default=none]\n"
+ "-watchdog-action reset|shutdown|poweroff|pause|debug|none\n"
+ " action when watchdog fires [default=reset]\n"
"-echr chr set terminal escape character instead of ctrl-a\n"
"-virtioconsole c\n"
" set virtio console\n"
@@ -4314,6 +4321,8 @@ enum {
QEMU_OPTION_localtime,
QEMU_OPTION_startdate,
QEMU_OPTION_icount,
+ QEMU_OPTION_watchdog,
+ QEMU_OPTION_watchdog_action,
QEMU_OPTION_echr,
QEMU_OPTION_virtiocon,
QEMU_OPTION_show_cursor,
@@ -4440,6 +4449,8 @@ static const QEMUOption qemu_options[] =
{ "localtime", 0, QEMU_OPTION_localtime },
{ "startdate", HAS_ARG, QEMU_OPTION_startdate },
{ "icount", HAS_ARG, QEMU_OPTION_icount },
+ { "watchdog", HAS_ARG, QEMU_OPTION_watchdog },
+ { "watchdog-action", HAS_ARG, QEMU_OPTION_watchdog_action },
{ "echr", HAS_ARG, QEMU_OPTION_echr },
{ "virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon },
{ "show-cursor", 0, QEMU_OPTION_show_cursor },
@@ -4941,6 +4952,8 @@ int main(int argc, char **argv, char **e
tb_size = 0;
autostart= 1;
+ register_watchdogs();
+
optind = 1;
for(;;) {
if (optind >= argc)
@@ -5315,6 +5328,17 @@ int main(int argc, char **argv, char **e
serial_devices[serial_device_index] = optarg;
serial_device_index++;
break;
+ case QEMU_OPTION_watchdog:
+ i = select_watchdog(optarg);
+ if (i > 0)
+ exit (i == 1 ? 1 : 0);
+ break;
+ case QEMU_OPTION_watchdog_action:
+ if (select_watchdog_action(optarg) == -1) {
+ fprintf(stderr, "Unknown -watchdog-action parameter\n");
+ exit(1);
+ }
+ break;
case QEMU_OPTION_virtiocon:
if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
fprintf(stderr, "qemu: too many virtio consoles\n");

245
kernel-boot-hvm.patch Normal file
View File

@ -0,0 +1,245 @@
Direct kernel boot to HVM guests has regression from xen-3.3 to xen-4.0.
Foreport this feature to latest qemu-xen. Make a fake boot sector with given
kernel and initrd, which could be accessed by hvmloader.
Signed-off-by: Chunyan Liu <cyliu@novell.com>
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/block.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/block.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/block.c
@@ -596,6 +596,16 @@ int bdrv_read(BlockDriverState *bs, int6
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
+
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(buf, bs->boot_sector_data, 512);
+ sector_num++;
+ nb_sectors--;
+ buf += 512;
+ if (nb_sectors == 0)
+ return 0;
+ }
+
if (drv->bdrv_pread) {
int ret, len;
len = nb_sectors * 512;
@@ -631,6 +641,10 @@ int bdrv_write(BlockDriverState *bs, int
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(bs->boot_sector_data, buf, 512);
+ }
+
if (drv->bdrv_pwrite) {
int ret, len, count = 0;
len = nb_sectors * 512;
@@ -934,6 +948,16 @@ void bdrv_guess_geometry(BlockDriverStat
}
}
+/* force a given boot sector. */
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
+{
+ bs->boot_sector_enabled = 1;
+ if (size > 512)
+ size = 512;
+ memcpy(bs->boot_sector_data, data, size);
+ memset(bs->boot_sector_data + size, 0, 512 - size);
+}
+
void bdrv_set_geometry_hint(BlockDriverState *bs,
int cyls, int heads, int secs)
{
@@ -1464,6 +1488,14 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri
if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL;
+ /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(buf, bs->boot_sector_data, 512);
+ sector_num++;
+ nb_sectors--;
+ buf += 512;
+ }
+
ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
if (ret) {
@@ -1489,6 +1521,10 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL;
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(bs->boot_sector_data, buf, 512);
+ }
+
ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
if (ret) {
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/block_int.h
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/block_int.h
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/block_int.h
@@ -122,6 +122,9 @@ struct BlockDriverState {
BlockDriver *drv; /* NULL means no media */
void *opaque;
+ int boot_sector_enabled;
+ uint8_t boot_sector_data[512];
+
char filename[1024];
char backing_file[1024]; /* if non zero, the image is a diff of
this file image */
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/pc.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/pc.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/pc.c
@@ -474,45 +474,28 @@ static void bochs_bios_init(void)
/* Generate an initial boot sector which sets state and jump to
a specified vector */
-static void generate_bootsect(uint8_t *option_rom,
- uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
+static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
{
- uint8_t rom[512], *p, *reloc;
- uint8_t sum;
+ uint8_t bootsect[512], *p;
int i;
+ int hda;
+
+ hda = drive_get_index(IF_IDE, 0, 0);
+ if (hda == -1) {
+ fprintf(stderr, "A disk image must be given for 'hda' when booting "
+ "a Linux kernel\n(if you really don't want it, use /dev/zero)\n");
+ exit(1);
+ }
+ memset(bootsect, 0, sizeof(bootsect));
- memset(rom, 0, sizeof(rom));
-
- p = rom;
- /* Make sure we have an option rom signature */
- *p++ = 0x55;
- *p++ = 0xaa;
-
- /* ROM size in sectors*/
- *p++ = 1;
-
- /* Hook int19 */
-
- *p++ = 0x50; /* push ax */
- *p++ = 0x1e; /* push ds */
- *p++ = 0x31; *p++ = 0xc0; /* xor ax, ax */
- *p++ = 0x8e; *p++ = 0xd8; /* mov ax, ds */
-
- *p++ = 0xc7; *p++ = 0x06; /* movvw _start,0x64 */
- *p++ = 0x64; *p++ = 0x00;
- reloc = p;
- *p++ = 0x00; *p++ = 0x00;
-
- *p++ = 0x8c; *p++ = 0x0e; /* mov cs,0x66 */
- *p++ = 0x66; *p++ = 0x00;
-
- *p++ = 0x1f; /* pop ds */
- *p++ = 0x58; /* pop ax */
- *p++ = 0xcb; /* lret */
-
- /* Actual code */
- *reloc = (p - rom);
+ /* Copy the MSDOS partition table if possible */
+ bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);
+ /* Make sure we have a partition signature */
+ bootsect[510] = 0x55;
+ bootsect[511] = 0xaa;
+ /* Actual code */
+ p = bootsect;
*p++ = 0xfa; /* CLI */
*p++ = 0xfc; /* CLD */
@@ -542,13 +525,7 @@ static void generate_bootsect(uint8_t *o
*p++ = segs[1]; /* CS */
*p++ = segs[1] >> 8;
- /* sign rom */
- sum = 0;
- for (i = 0; i < (sizeof(rom) - 1); i++)
- sum += rom[i];
- rom[sizeof(rom) - 1] = -sum;
-
- memcpy(option_rom, rom, sizeof(rom));
+ bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect));
}
static long get_file_size(FILE *f)
@@ -565,8 +542,7 @@ static long get_file_size(FILE *f)
return size;
}
-static void load_linux(uint8_t *option_rom,
- const char *kernel_filename,
+static void load_linux(const char *kernel_filename,
const char *initrd_filename,
const char *kernel_cmdline)
{
@@ -632,7 +608,9 @@ static void load_linux(uint8_t *option_r
/* Special pages are placed at end of low RAM: pick an arbitrary one and
* subtract a suitably large amount of padding (64kB) to skip BIOS data. */
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
+ //xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
+ /* BUFIO Page beyond last_pfn, use 0x7ffc instead. Fix ME. */
+ end_low_ram = 0x7ffc;
end_low_ram = (end_low_ram << 12) - (64*1024);
/* highest address for loading the initrd */
@@ -721,7 +699,7 @@ static void load_linux(uint8_t *option_r
memset(gpr, 0, sizeof gpr);
gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
- generate_bootsect(option_rom, gpr, seg, 0);
+ generate_bootsect(gpr, seg, 0);
#endif
}
@@ -932,14 +910,6 @@ vga_bios_error:
int size, offset;
offset = 0;
- if (linux_boot) {
- option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
- load_linux(phys_ram_base + option_rom_offset,
- kernel_filename, initrd_filename, kernel_cmdline);
- cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE,
- option_rom_offset | IO_MEM_ROM);
- offset = TARGET_PAGE_SIZE;
- }
for (i = 0; i < nb_option_roms; i++) {
size = get_image_size(option_rom[i]);
@@ -973,6 +943,9 @@ vga_bios_error:
bochs_bios_init();
+ if (linux_boot)
+ load_linux(kernel_filename, initrd_filename, kernel_cmdline);
+
cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
i8259 = i8259_init(cpu_irq[0]);
ferr_irq = i8259[13];
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/block.h
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/block.h
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/block.h
@@ -82,6 +82,7 @@ int64_t bdrv_getlength(BlockDriverState
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs);
int bdrv_commit(BlockDriverState *bs);
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
/* async block I/O */
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
typedef void BlockDriverCompletionFunc(void *opaque, int ret);

141
log-guest-console.patch Normal file
View File

@ -0,0 +1,141 @@
Add code to support logging xen-domU console, as what xenconsoled does. Log info
will be saved in /var/log/xen/console/guest-domUname.log.
Signed-off-by: Chunyan Liu <cyliu@novell.com>
---
hw/xen_console.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
Index: xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/xen_console.c
===================================================================
--- xen-4.1.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_console.c
+++ xen-4.1.1-testing/tools/ioemu-qemu-xen/hw/xen_console.c
@@ -38,6 +38,8 @@
#include "qemu-char.h"
#include "xen_backend.h"
+static int log_guest = 0;
+
struct buffer {
uint8_t *data;
size_t consumed;
@@ -54,8 +56,24 @@ struct XenConsole {
void *sring;
CharDriverState *chr;
int backlog;
+ int log_fd;
};
+static int write_all(int fd, const char* buf, size_t len)
+{
+ while (len) {
+ ssize_t ret = write(fd, buf, len);
+ if (ret == -1 && errno == EINTR)
+ continue;
+ if (ret < 0)
+ return -1;
+ len -= ret;
+ buf += ret;
+ }
+
+ return 0;
+}
+
static void buffer_append(struct XenConsole *con)
{
struct buffer *buffer = &con->buffer;
@@ -83,6 +101,15 @@ static void buffer_append(struct XenCons
intf->out_cons = cons;
xen_be_send_notify(&con->xendev);
+ if (con->log_fd != -1) {
+ int logret;
+ logret = write_all(con->log_fd, buffer->data + buffer->size - size, size);
+ if (logret < 0) {
+ xen_be_printf(&con->xendev, 1, "Write to log failed on domain %d: %d (%s)\n",
+ con->xendev.dom, errno, strerror(errno));
+ }
+ }
+
if (buffer->max_capacity &&
buffer->size > buffer->max_capacity) {
/* Discard the middle of the data. */
@@ -176,6 +203,36 @@ static void xencons_send(struct XenConso
}
}
+static int create_domain_log(struct XenConsole *con)
+{
+ char *logfile;
+ char *path, *domname;
+ int fd;
+ const char *logdir = "/var/log/xen/console";
+
+ path = xs_get_domain_path(xenstore, con->xendev.dom);
+ domname = xenstore_read_str(path, "name");
+ free(path);
+ if (!domname)
+ return -1;
+
+ if (mkdir(logdir, 0755) && errno != EEXIST)
+ {
+ xen_be_printf(&con->xendev, 1, "Directory %s does not exist and fail to create it!", logdir);
+ return -1;
+ }
+
+ asprintf(&logfile, "%s/guest-%s.log", logdir, domname);
+ qemu_free(domname);
+
+ fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ free(logfile);
+ if (fd == -1)
+ xen_be_printf(&con->xendev, 1, "Failed to open log %s: %d (%s)", logfile, errno, strerror(errno));
+
+ return fd;
+}
+
/* -------------------------------------------------------------------- */
static int con_init(struct XenDevice *xendev)
@@ -183,6 +240,7 @@ static int con_init(struct XenDevice *xe
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
char *type, *dom, label[32];
const char *output;
+ char *logenv = NULL;
/* setup */
dom = xs_get_domain_path(xenstore, con->xendev.dom);
@@ -209,6 +267,10 @@ static int con_init(struct XenDevice *xe
con->chr = qemu_chr_open(label, output, NULL);
xenstore_store_pv_console_info(con->xendev.dev, con->chr, output);
+ logenv = getenv("XENCONSOLED_TRACE");
+ if (logenv != NULL && strlen(logenv) == strlen("guest") && !strcmp(logenv, "guest")) {
+ log_guest = 1;
+ }
return 0;
}
@@ -246,6 +308,9 @@ static int con_initialise(struct XenDevi
con->xendev.remote_port,
con->xendev.local_port,
con->buffer.max_capacity);
+ con->log_fd = -1;
+ if (log_guest)
+ con->log_fd = create_domain_log(con);
return 0;
}
@@ -264,6 +329,12 @@ static void con_disconnect(struct XenDev
xc_gnttab_munmap(xendev->gnttabdev, con->sring, 1);
con->sring = NULL;
}
+
+ if (con->log_fd != -1) {
+ close(con->log_fd);
+ con->log_fd = -1;
+ }
+
}
static void con_event(struct XenDevice *xendev)

View File

@ -2,13 +2,12 @@ Make our PV drivers "Novell supported modules"
Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
Index: xen-4.1.1-testing/unmodified_drivers/linux-2.6/Module.supported
===================================================================
--- /dev/null
+++ xen-4.1.1-testing/unmodified_drivers/linux-2.6/Module.supported
@@ -0,0 +1,5 @@
+++ b/unmodified_drivers/linux-2.6/Module.supported
@@ -0,0 +1,6 @@
+xen-vbd
+xen-platform-pci
+xen-vnif
+xenbus
+xen-balloon
+xen-scsi

View File

@ -0,0 +1,149 @@
Index: xen-4.1.1-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.1.1-testing/tools/python/xen/xm/create.py
@@ -535,6 +535,21 @@ gopts.var('usbdevice', val='NAME',
fn=set_value, default='',
use="Name of USB device to add?")
+gopts.var('watchdog', val='NAME',
+ fn=set_value, default='',
+ use="Watchdog device to use. May be ib700 or i6300esb")
+
+gopts.var('watchdog_action', val='reset|shutdown|poweroff|pause|none|dump',
+ fn=set_value, default="reset",
+ use="""Action when watchdog timer expires:
+ - reset: Default, forcefully reset the guest;
+ - shutdown: Gracefully shutdown the guest (not recommended);
+ - poweroff: Forcefully power off the guest;
+ - pause: Pause the guest;
+ - none: Do nothing;
+ - dump: Automatically dump the guest;
+ """)
+
gopts.var('description', val='NAME',
fn=set_value, default='',
use="Description of a domain")
@@ -1092,6 +1107,7 @@ def configure_hvm(config_image, vals):
'usb', 'usbdevice',
'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten',
'vncunused', 'viridian', 'vpt_align',
+ 'watchdog', 'watchdog_action',
'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci',
'memory_sharing' ]
Index: xen-4.1.1-testing/tools/python/xen/xm/xenapi_create.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.1.1-testing/tools/python/xen/xm/xenapi_create.py
@@ -1113,7 +1113,9 @@ class sxp2xml:
'xen_platform_pci',
'tsc_mode'
'description',
- 'nomigrate'
+ 'nomigrate',
+ 'watchdog',
+ 'watchdog_action'
]
platform_configs = []
Index: xen-4.1.1-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.1.1-testing/tools/python/xen/xend/image.py
@@ -866,7 +866,8 @@ class HVMImageHandler(ImageHandler):
dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
'localtime', 'serial', 'stdvga', 'isa',
- 'acpi', 'usb', 'usbdevice', 'gfx_passthru' ]
+ 'acpi', 'usb', 'usbdevice', 'gfx_passthru',
+ 'watchdog', 'watchdog_action' ]
for a in dmargs:
v = vmConfig['platform'].get(a)
@@ -874,6 +875,7 @@ class HVMImageHandler(ImageHandler):
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
if a == 'keymap': a = 'k'
+ if a == 'watchdog_action': a = 'watchdog-action'
# Handle booleans gracefully
if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']:
Index: xen-4.1.1-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.1.1-testing/tools/python/xen/xend/XendConfig.py
@@ -191,6 +191,8 @@ XENAPI_PLATFORM_CFG_TYPES = {
'xen_platform_pci': int,
"gfx_passthru": int,
'oos' : int,
+ 'watchdog': str,
+ 'watchdog_action': str,
}
# Xen API console 'other_config' keys.
Index: xen-4.1.1-testing/tools/libxl/libxl_dm.c
===================================================================
--- xen-4.1.1-testing.orig/tools/libxl/libxl_dm.c
+++ xen-4.1.1-testing/tools/libxl/libxl_dm.c
@@ -117,6 +117,12 @@ static char ** libxl_build_device_model_
flexarray_vappend(dm_args, "-usbdevice", info->usbdevice, NULL);
}
}
+ if (info->watchdog || info->watchdog_action) {
+ flexarray_append(dm_args, "-watchdog");
+ if (info->watchdog_action) {
+ flexarray_vappend(dm_args, "-watchdog-action", info->watchdog_action, NULL);
+ }
+ }
if (info->soundhw) {
flexarray_vappend(dm_args, "-soundhw", info->soundhw, NULL);
}
@@ -253,6 +259,12 @@ static char ** libxl_build_device_model_
flexarray_vappend(dm_args, "-usbdevice", info->usbdevice, NULL);
}
}
+ if (info->watchdog || info->watchdog_action) {
+ flexarray_append(dm_args, "-watchdog");
+ if (info->watchdog_action) {
+ flexarray_vappend(dm_args, "-watchdog-action", info->watchdog_action, NULL);
+ }
+ }
if (info->soundhw) {
flexarray_vappend(dm_args, "-soundhw", info->soundhw, NULL);
}
Index: xen-4.1.1-testing/tools/libxl/libxl.idl
===================================================================
--- xen-4.1.1-testing.orig/tools/libxl/libxl.idl
+++ xen-4.1.1-testing/tools/libxl/libxl.idl
@@ -164,6 +164,8 @@ libxl_device_model_info = Struct("device
("vcpu_avail", integer, False, "vcpus actually available"),
("xen_platform_pci", integer, False, "enable/disable the xen platform pci device"),
("extra", libxl_string_list, False, "extra parameters pass directly to qemu, NULL terminated"),
+ ("watchdog", string, False, "the watchdog device, ib700 or i6300esb"),
+ ("watchdog_action", string, False, "action to take when the watchdog timer expires"),
],
comment=
"""Device Model information.
Index: xen-4.1.1-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.1.1-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.1.1-testing/tools/libxl/xl_cmdimpl.c
@@ -365,6 +365,8 @@ static void printf_info(int domid,
printf("\t\t\t(usb %d)\n", dm_info->usb);
printf("\t\t\t(usbdevice %s)\n", dm_info->usbdevice);
printf("\t\t\t(apic %d)\n", dm_info->apic);
+ printf("\t\t\t(watchdog %s)\n", dm_info->watchdog);
+ printf("\t\t\t(watchdog_action %s)\n", dm_info->watchdog_action);
printf("\t\t)\n");
} else {
printf("\t\t(linux %d)\n", b_info->hvm);
@@ -1142,6 +1144,8 @@ skip_vfb:
xlu_cfg_replace_string (config, "soundhw", &dm_info->soundhw);
if (!xlu_cfg_get_long (config, "xen_platform_pci", &l))
dm_info->xen_platform_pci = l;
+ xlu_cfg_replace_string (config, "watchdog", &dm_info->watchdog);
+ xlu_cfg_replace_string (config, "watchdog_action", &dm_info->watchdog_action);
if (!xlu_cfg_get_list(config, "device_model_args", &dmargs, &nr_dmargs, 0))
{

View File

@ -1,8 +1,6 @@
Index: xen-4.1.1-testing/xen/arch/x86/platform_hypercall.c
===================================================================
--- xen-4.1.1-testing.orig/xen/arch/x86/platform_hypercall.c
+++ xen-4.1.1-testing/xen/arch/x86/platform_hypercall.c
@@ -22,7 +22,7 @@
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -23,7 +23,7 @@
#include <xen/cpu.h>
#include <asm/current.h>
#include <public/platform.h>
@ -11,7 +9,7 @@ Index: xen-4.1.1-testing/xen/arch/x86/platform_hypercall.c
#include <asm/edd.h>
#include <asm/mtrr.h>
#include <asm/io_apic.h>
@@ -62,6 +62,7 @@ long cpu_down_helper(void *data);
@@ -63,6 +63,7 @@ long cpu_down_helper(void *data);
ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
{
ret_t ret = 0;
@ -19,7 +17,7 @@ Index: xen-4.1.1-testing/xen/arch/x86/platform_hypercall.c
struct xen_platform_op curop, *op = &curop;
if ( !IS_PRIV(current->domain) )
@@ -493,6 +494,24 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
@@ -513,6 +514,24 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
op->u.mem_add.epfn,
op->u.mem_add.pxm);
break;
@ -44,11 +42,9 @@ Index: xen-4.1.1-testing/xen/arch/x86/platform_hypercall.c
default:
ret = -ENOSYS;
break;
Index: xen-4.1.1-testing/xen/include/public/platform.h
===================================================================
--- xen-4.1.1-testing.orig/xen/include/public/platform.h
+++ xen-4.1.1-testing/xen/include/public/platform.h
@@ -355,6 +355,14 @@ struct xenpf_mem_hotadd
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -449,6 +449,14 @@ struct xenpf_mem_hotadd
uint32_t flags;
};
@ -63,7 +59,7 @@ Index: xen-4.1.1-testing/xen/include/public/platform.h
struct xen_platform_op {
uint32_t cmd;
uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -374,6 +382,7 @@ struct xen_platform_op {
@@ -469,6 +477,7 @@ struct xen_platform_op {
struct xenpf_cpu_ol cpu_ol;
struct xenpf_cpu_hotadd cpu_add;
struct xenpf_mem_hotadd mem_add;

View File

@ -1,6 +1,6 @@
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -160,6 +160,8 @@ static int get_superpage(unsigned long m
@@ -162,6 +162,8 @@ static int get_superpage(unsigned long m
#endif
static void put_superpage(unsigned long mfn);
@ -21,7 +21,7 @@
printk("%p ", _p(*stk++));
--- a/xen/arch/x86/x86_32/mm.c
+++ b/xen/arch/x86/x86_32/mm.c
@@ -123,6 +123,8 @@ void __init paging_init(void)
@@ -121,6 +121,8 @@ void __init paging_init(void)
#undef CNT
#undef MFN
@ -64,7 +64,7 @@
unmap_domain_page(l1t);
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -750,6 +750,8 @@ void __init paging_init(void)
@@ -751,6 +751,8 @@ void __init paging_init(void)
#undef CNT
#undef MFN

View File

@ -1,13 +1,11 @@
Index: xen-4.1.1-testing/xen/Makefile
===================================================================
--- xen-4.1.1-testing.orig/xen/Makefile
+++ xen-4.1.1-testing/xen/Makefile
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -1,3 +1,4 @@
+export XEN_CHANGESET = unavailable
# This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated.
export XEN_VERSION = 4
@@ -82,7 +83,7 @@ delete-unfresh-files:
@@ -91,7 +92,7 @@ delete-unfresh-files:
@rm -f $@1 $@2
# compile.h contains dynamic build info. Rebuilt on every 'make' invocation.
@ -16,7 +14,7 @@ Index: xen-4.1.1-testing/xen/Makefile
@sed -e 's/@@date@@/$(shell LC_ALL=C date)/g' \
-e 's/@@time@@/$(shell LC_ALL=C date +%T)/g' \
-e 's/@@whoami@@/$(XEN_WHOAMI)/g' \
@@ -92,10 +93,9 @@ include/xen/compile.h: include/xen/compi
@@ -101,10 +102,9 @@ include/xen/compile.h: include/xen/compi
-e 's/@@version@@/$(XEN_VERSION)/g' \
-e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \
-e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \

View File

@ -241,7 +241,7 @@
status = fread(&buf, 1, sizeof(*h), rtnl);
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -745,7 +745,7 @@ static void __pci_disable_msi(struct msi
@@ -746,7 +746,7 @@ static void __pci_disable_msi(struct msi
{
struct pci_dev *dev;
int pos;
@ -351,7 +351,7 @@
/* read magic: 9 first bits */
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1001,7 +1001,8 @@ static void local_time_calibration(void)
@@ -1009,7 +1009,8 @@ static void local_time_calibration(void)
* System timestamps, extrapolated from local and master oscillators,
* taken during this calibration and the previous calibration.
*/
@ -363,7 +363,7 @@
/* TSC timestamps taken during this calibration and prev calibration. */
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -348,7 +348,7 @@ static void __devinit init_amd(struct cp
@@ -391,7 +391,7 @@ static void __devinit init_amd(struct cp
{
u32 l, h;
int mbytes = num_physpages >> (20-PAGE_SHIFT);
@ -482,7 +482,7 @@
union hypercall_input {
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4900,7 +4900,7 @@ static int ptwr_emulated_update(
@@ -4904,7 +4904,7 @@ static int ptwr_emulated_update(
{
unsigned long mfn;
unsigned long unaligned_addr = addr;
@ -493,7 +493,7 @@
struct domain *d = v->domain;
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -435,7 +435,8 @@ void destroy_m2p_mapping(struct mem_hota
@@ -436,7 +436,8 @@ void destroy_m2p_mapping(struct mem_hota
static int setup_compat_m2p_table(struct mem_hotadd_info *info)
{
unsigned long i, va, smap, emap, rwva, epfn = info->epfn;
@ -633,7 +633,7 @@
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -375,8 +375,7 @@ int __init construct_dom0(
@@ -376,8 +376,7 @@ int __init construct_dom0(
return rc;
/* compatibility check */

View File

@ -1,3 +1,80 @@
-------------------------------------------------------------------
Wed Jun 29 09:37:05 MDT 2011 - carnold@novell.com
- fate#309894: Xen needs to correctly understand family 15h CPU
topology
- fate#311376: EFI support in SP2
- fate#311529: Native UEFI booting under Xen (installation)
23074-pfn.h.patch
23571-vtd-fault-verbosity.patch
23574-x86-dom0-compressed-ELF.patch
23575-x86-DMI.patch
23610-x86-topology-info.patch
23611-amd-fam15-topology.patch
23613-EFI-headers.patch
23614-x86_64-EFI-boot.patch
23615-x86_64-EFI-runtime.patch
23616-x86_64-EFI-MPS.patch
-------------------------------------------------------------------
Wed Jun 29 15:01:54 CEST 2011 - jbeulich@novell.com
- Mark xen-scsi.ko supported (bnc#582265, fate#309459).
-------------------------------------------------------------------
Tue Jun 28 11:07:10 MDT 2011 - carnold@novell.com
- fate#310308: Hypervisor assisted watchdog driver
ioemu-watchdog-support.patch
ioemu-watchdog-linkage.patch
ioemu-watchdog-ib700-timer.patch
tools-watchdog-support.patch
-------------------------------------------------------------------
Mon Jun 27 09:03:17 MDT 2011 - carnold@novell.com
- bnc#702025 - VUL-0: xen: VT-d (PCI passthrough) MSI trap
injection (CVE-2011-1898)
Fixed in Xen version 4.1.1
-------------------------------------------------------------------
Wed Jun 22 18:11:18 CST 2011 - cyliu@novell.com
- fate#310956: Support Direct Kernel Boot for FV guests
kernel-boot-hvm.patch
-------------------------------------------------------------------
Wed Jun 22 13:49:22 CST 2011 - cyliu@novell.com
- fate#310316: Support change vnc password while vm is running
change-vnc-passwd.patch
- fate#310325: Support get domU console log from Dom0
log-guest-console.patch
-------------------------------------------------------------------
Wed Jun 22 11:29:47 CEST 2011 - ohering@suse.de
- fate#311487: remove modprobe.conf files for autoloading of Xen
and Hyper-V drivers
xen.sles11sp1.fate311487.xen_platform_pci.dmistring.patch
add dmi modalias to xen-platform-pci.ko
-------------------------------------------------------------------
Tue Jun 21 14:21:42 MDT 2011 - carnold@novell.com
- fate#308532: [NONCODE] Remove XEN 32-bit Hypervisor
Modify ExclusiveArch in xen.spec to build only x86_64
-------------------------------------------------------------------
Tue Jun 21 08:03:59 MDT 2011 - carnold@novell.com
- fate#309900 - Add Xen support for SVM Decode Assist in AMD family
15h
- fate#309902 - Add Xen support for AMD family 12h processors
- fate#309903 - Add Xen support for AMD family 14h processors
- fate#309906 - Add Xen support for performance event counters in
AMD family 15h
-------------------------------------------------------------------
Fri Jun 17 06:37:36 MDT 2011 - carnold@novell.com

View File

@ -0,0 +1,42 @@
References: fate#311487
Provide a modalias entry in xen-plaform-pci.ko to allow early autoloading in
initrd based on /sys/class/dmi/id/modalias
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
Index: xen-4.1.1-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
===================================================================
--- xen-4.1.1-testing.orig/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ xen-4.1.1-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/version.h>
+#include <linux/dmi.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
@@ -480,6 +481,18 @@ static struct pci_device_id platform_pci
MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
+static const struct dmi_system_id platform_dmi_tbl[] = {
+ {
+ .ident = "Xen PV-on-HVM",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Xen"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HVM domU"),
+ },
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(dmi, platform_dmi_tbl);
+
static struct pci_driver platform_driver = {
name: DRV_NAME,
probe: platform_pci_init,

190
xen.spec
View File

@ -26,6 +26,11 @@ ExclusiveArch: %ix86 x86_64
%define xen_build_dir xen-4.1.1-testing
%define with_kmp 1
%define with_stubdom 0
%ifarch x86_64
%define with_dom0_support 1
%else
%define with_dom0_support 0
%endif
%define _fwdefdir /etc/sysconfig/SuSEfirewall2.d/services
%if %suse_version > 1140
%define with_xend 0
@ -67,6 +72,8 @@ BuildRequires: te_latex
BuildRequires: tetex
%endif
%ifarch x86_64
# EFI
#BuildRequires: libgcc46 gcc46
BuildRequires: glibc-32bit glibc-devel-32bit
BuildRequires: gcc-32bit
BuildRequires: gcc43-32bit
@ -80,8 +87,8 @@ BuildRequires: glibc-devel
%if %{?with_kmp}0
BuildRequires: kernel-source kernel-syms module-init-tools xorg-x11
%endif
Version: 4.1.1_01
Release: 15
Version: 4.1.1_02
Release: 1
License: GPLv2+
Group: System/Kernel
AutoReqProv: on
@ -126,35 +133,45 @@ Source20000: xenalyze.hg.tar.bz2
Patch1: 22998-x86-get_page_from_l1e-retcode.patch
Patch2: 22999-x86-mod_l1_entry-retcode.patch
Patch3: 23000-x86-mod_l2_entry-retcode.patch
Patch4: 23096-x86-hpet-no-cpumask_lock.patch
Patch5: 23099-x86-rwlock-scalability.patch
Patch6: 23103-x86-pirq-guest-eoi-check.patch
Patch7: 23127-vtd-bios-settings.patch
Patch8: 23199-amd-iommu-unmapped-intr-fault.patch
Patch9: 23233-hvm-cr-access.patch
Patch10: 23234-svm-decode-assist-base.patch
Patch11: 23235-svm-decode-assist-crs.patch
Patch12: 23236-svm-decode-assist-invlpg.patch
Patch13: 23238-svm-decode-assist-insn-fetch.patch
Patch14: 23303-cpufreq-misc.patch
Patch15: 23304-amd-oprofile-strings.patch
Patch16: 23305-amd-fam15-xenoprof.patch
Patch17: 23306-amd-fam15-vpmu.patch
Patch18: 23334-amd-fam12+14-vpmu.patch
Patch19: 23383-libxc-rm-static-vars.patch
Patch20: 23437-amd-fam15-TSC-scaling.patch
Patch21: 23462-libxc-cpu-feature.patch
Patch22: 23481-x86-SMEP.patch
Patch23: 23504-x86-SMEP-hvm.patch
Patch24: 23505-x86-cpu-add-arg-check.patch
Patch25: 23508-vmx-proc-based-ctls-probe.patch
Patch26: 23510-hvm-cpuid-DRNG.patch
Patch27: 23511-amd-fam15-no-flush-for-C3.patch
Patch28: 23516-cpuid-ERMS.patch
Patch29: 23538-hvm-pio-emul-no-host-crash.patch
Patch30: 23539-hvm-cpuid-FSGSBASE.patch
Patch31: 23543-x86_64-maddr_to_virt-assertion.patch
Patch32: 23546-fucomip.patch
Patch4: 23074-pfn.h.patch
Patch5: 23096-x86-hpet-no-cpumask_lock.patch
Patch6: 23099-x86-rwlock-scalability.patch
Patch7: 23103-x86-pirq-guest-eoi-check.patch
Patch8: 23127-vtd-bios-settings.patch
Patch9: 23199-amd-iommu-unmapped-intr-fault.patch
Patch10: 23233-hvm-cr-access.patch
Patch11: 23234-svm-decode-assist-base.patch
Patch12: 23235-svm-decode-assist-crs.patch
Patch13: 23236-svm-decode-assist-invlpg.patch
Patch14: 23238-svm-decode-assist-insn-fetch.patch
Patch15: 23303-cpufreq-misc.patch
Patch16: 23304-amd-oprofile-strings.patch
Patch17: 23305-amd-fam15-xenoprof.patch
Patch18: 23306-amd-fam15-vpmu.patch
Patch19: 23334-amd-fam12+14-vpmu.patch
Patch20: 23383-libxc-rm-static-vars.patch
Patch21: 23437-amd-fam15-TSC-scaling.patch
Patch22: 23462-libxc-cpu-feature.patch
Patch23: 23481-x86-SMEP.patch
Patch24: 23504-x86-SMEP-hvm.patch
Patch25: 23505-x86-cpu-add-arg-check.patch
Patch26: 23508-vmx-proc-based-ctls-probe.patch
Patch27: 23510-hvm-cpuid-DRNG.patch
Patch28: 23511-amd-fam15-no-flush-for-C3.patch
Patch29: 23516-cpuid-ERMS.patch
Patch30: 23538-hvm-pio-emul-no-host-crash.patch
Patch31: 23539-hvm-cpuid-FSGSBASE.patch
Patch32: 23543-x86_64-maddr_to_virt-assertion.patch
Patch33: 23546-fucomip.patch
Patch34: 23571-vtd-fault-verbosity.patch
Patch35: 23574-x86-dom0-compressed-ELF.patch
Patch36: 23575-x86-DMI.patch
Patch37: 23610-x86-topology-info.patch
Patch38: 23611-amd-fam15-topology.patch
Patch39: 23613-EFI-headers.patch
Patch40: 23614-x86_64-EFI-boot.patch
Patch41: 23615-x86_64-EFI-runtime.patch
Patch42: 23616-x86_64-EFI-MPS.patch
# Upstream qemu patches
# Our patches
Patch300: xen-config.diff
@ -209,6 +226,7 @@ Patch371: domu-usb-controller.patch
Patch372: usb-list.patch
Patch373: xend-devid-or-name.patch
Patch374: suspend_evtchn_lock.patch
Patch375: log-guest-console.patch
# Patches for snapshot support
Patch400: snapshot-ioemu-save.patch
Patch401: snapshot-ioemu-restore.patch
@ -246,9 +264,15 @@ Patch443: vif-bridge.mtu.patch
Patch445: hotplug.losetup.patch
Patch446: xend-disable-internal-logrotate.patch
Patch447: xend-config-enable-dump-comment.patch
Patch448: change-vnc-passwd.patch
Patch449: kernel-boot-hvm.patch
Patch450: ioemu-watchdog-support.patch
Patch451: ioemu-watchdog-linkage.patch
Patch452: ioemu-watchdog-ib700-timer.patch
Patch453: tools-watchdog-support.patch
# Jim's domain lock patch
Patch450: xend-domain-lock.patch
Patch451: xend-domain-lock-sfex.patch
Patch480: xend-domain-lock.patch
Patch481: xend-domain-lock-sfex.patch
# Hypervisor and PV driver Patches
Patch500: 32on64-extra-mem.patch
Patch501: x86-ioapic-ack-default.patch
@ -263,6 +287,7 @@ Patch510: pv-driver-build.patch
Patch511: supported_module.diff
Patch512: magic_ioport_compat.patch
Patch513: xen.sles11sp1.bug684297.xen_oldmem_pfn_is_ram.patch
Patch514: xen.sles11sp1.fate311487.xen_platform_pci.dmistring.patch
Patch650: disable_emulated_device.diff
Patch651: ioemu-disable-scsi.patch
Patch652: ioemu-disable-emulated-ide-if-pv.patch
@ -405,6 +430,7 @@ Authors:
--------
Ian Pratt <ian.pratt@cl.cam.ac.uk>
%if %{?with_dom0_support}0
%package tools
License: GPLv2+
Summary: Xen Virtualization: Control tools for domain 0
@ -461,6 +487,7 @@ use Xen.
Authors:
--------
Ian Pratt <ian.pratt@cl.cam.ac.uk>
%endif
%package tools-domU
License: GPLv2+
@ -583,6 +610,7 @@ Xen, but is not available for release due to license restrictions.
%endif
%if %{?with_dom0_support}0
%package doc-html
License: GPLv2+
Summary: Xen Virtualization: HTML documentation
@ -621,6 +649,7 @@ xpdf/kpdf/gpdf/gv/... to read the files in
Authors:
--------
Ian Pratt <ian.pratt@cl.cam.ac.uk>
%endif
%prep
%setup -q -n %xen_build_dir -a 1 -a 20000
@ -658,6 +687,16 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch300 -p1
%patch301 -p1
%patch302 -p1
@ -709,6 +748,7 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
%patch372 -p1
%patch373 -p1
#%patch374 -p1 suspend_evtchn_lock, buildservice build problem
%patch375 -p1
%patch400 -p1
%patch401 -p1
%patch402 -p1
@ -743,8 +783,14 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
%patch445 -p1
%patch446 -p1
%patch447 -p1
%patch448 -p1
%patch449 -p1
%patch450 -p1
%patch451 -p1
%patch452 -p1
%patch453 -p1
%patch480 -p1
%patch481 -p1
%patch500 -p1
%patch501 -p1
%patch502 -p1
@ -758,6 +804,7 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
%patch511 -p1
%patch512 -p1
%patch513 -p1
%patch514 -p1
%patch650 -p1
%patch651 -p1
%patch652 -p1
@ -796,10 +843,16 @@ sed -i "s/XEN_CHANGESET[\t ]*=.*\$/XEN_CHANGESET = %{changeset}/" xen/Makefi
RPM_OPT_FLAGS=${RPM_OPT_FLAGS//-fstack-protector/}
export CFLAGS="${RPM_OPT_FLAGS}"
export RPM_OPT_FLAGS
%if %{?with_dom0_support}0
make -C xenalyze.hg CC="gcc -I../xen/include" %{?_smp_mflags}
make -C tools/include/xen-foreign %{?_smp_mflags}
make tools docs %{?_smp_mflags}
make -C tools/debugger/gdbsx
make -C tools/xen-utils-0.1 XEN_INTREE_BUILD=yes
%else
make -C tools/include/xen-foreign %{?_smp_mflags}
make tools docs %{?_smp_mflags}
%endif
%if %{?with_kmp}0
# pv driver modules
export XL=/usr/src/linux
@ -816,10 +869,15 @@ for flavor in %flavors_to_build; do
cd ../..
done
%endif
make -C tools/xen-utils-0.1 XEN_INTREE_BUILD=yes
%install
export CFLAGS="$RPM_OPT_FLAGS"
%if %{?with_dom0_support}0
# EFI
#%ifarch x86_64
#make -C xen install CC=gcc-4.6 max_phys_cpus=%{max_cpus} debug=n crash_debug=n DESTDIR=$RPM_BUILD_ROOT EFI_VENDOR=SuSE %{?_smp_mflags}
#make -C xen clean
#%endif
install_xen()
{
local ext=""
@ -850,7 +908,6 @@ make -C tools/include/xen-foreign %{?_smp_mflags}
export XEN_PYTHON_NATIVE_INSTALL=1
make -C tools install \
DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %{?_smp_mflags}
###cp tools/debugger/gdb/gdb-6.2.1-linux-i386-xen/gdb/gdbserver/gdbserver-xen $RPM_BUILD_ROOT/usr/bin/gdbserver-xen
rm -f $RPM_BUILD_ROOT/usr/sbin/{qcow-create,img2qcow,qcow2raw}
make -C tools/misc/serial-split install \
DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %{?_smp_mflags}
@ -860,8 +917,13 @@ ln -s /usr/lib/xen/bin/qemu-dm $RPM_BUILD_ROOT/%{_libdir}/xen/bin/qemu-dm
%endif
cp -avL xenalyze.hg/dump-raw $RPM_BUILD_ROOT/%{_bindir}/xenalyze.dump-raw
cp -avL xenalyze.hg/xenalyze $RPM_BUILD_ROOT/%{_bindir}
%else
make -C tools install DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %{?_smp_mflags}
make -C tools/misc/serial-split install \
DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %{?_smp_mflags}
%endif
# PV driver modules
%if %{?with_kmp}0
# pv driver modules
export INSTALL_MOD_PATH=$RPM_BUILD_ROOT
export INSTALL_MOD_DIR=updates
for flavor in %flavors_to_build; do
@ -871,8 +933,9 @@ done
mkdir -p $RPM_BUILD_ROOT/etc/modprobe.d
install -m644 %SOURCE20 $RPM_BUILD_ROOT/etc/modprobe.d/xen_pvdrivers.conf
%endif
%if %{?with_dom0_support}0
# Stubdom
%if %{?with_stubdom}0
# stubdom
make stubdom %{?_smp_mflags}
make -C stubdom install \
DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} \
@ -883,7 +946,7 @@ ln -s /usr/lib/xen/bin/stubdom-dm $RPM_BUILD_ROOT/usr/lib64/xen/bin/stubdom-dm
ln -s /usr/lib/xen/bin/stubdompath.sh $RPM_BUILD_ROOT/usr/lib64/xen/bin/stubdompath.sh
%endif
%endif
# docs
# Docs
make -C docs install \
DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} \
DOCDIR=%{_defaultdocdir}/xen
@ -894,7 +957,9 @@ mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc
for name in vtpm.txt crashdb.txt sedf_scheduler_mini-HOWTO.txt xenpaging.txt; do
install -m 644 docs/misc/$name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc/
done
%endif
# init scripts
%if %{?with_dom0_support}0
mkdir -p $RPM_BUILD_ROOT/etc/init.d
install %SOURCE6 $RPM_BUILD_ROOT/etc/init.d/xend
ln -s /etc/init.d/xend $RPM_BUILD_ROOT/usr/sbin/rcxend
@ -935,6 +1000,7 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/domain
mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/migrate
mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/vnet
mkdir -p $RPM_BUILD_ROOT/var/log/xen
mkdir -p $RPM_BUILD_ROOT/var/log/xen/console
ln -s /var/lib/xen/images $RPM_BUILD_ROOT/etc/xen/images
# Bootloader
install -m755 %SOURCE9 $RPM_BUILD_ROOT/usr/lib/xen/boot/
@ -942,7 +1008,6 @@ install -m755 %SOURCE9 $RPM_BUILD_ROOT/usr/lib/xen/boot/
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
mv $RPM_BUILD_ROOT/etc/udev/rules.d/xen-backend.rules $RPM_BUILD_ROOT/etc/udev/rules.d/40-xen.rules
mv $RPM_BUILD_ROOT/etc/udev/rules.d/xend.rules $RPM_BUILD_ROOT/etc/udev/rules.d/40-xend.rules
#%find_lang xen-vm # po files are misnamed upstream
# xen utils
make -C tools/xen-utils-0.1 install DESTDIR=$RPM_BUILD_ROOT XEN_INTREE_BUILD=yes
# Clean up unpackaged files
@ -957,18 +1022,42 @@ rm -f $RPM_BUILD_ROOT/usr/sbin/netfix
rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{pyver}/site-packages/*.egg-info
rm -rf $RPM_BUILD_ROOT/html
rm -rf $RPM_BUILD_ROOT/usr/share/doc/xen/README.*
#rm -f $RPM_BUILD_ROOT/usr/share/xen/create.dtd
rm -f $RPM_BUILD_ROOT/%{_libdir}/xen/bin/qemu-dm.debug
rm -f $RPM_BUILD_ROOT/%{_bindir}/qemu-img-xen
rm -f $RPM_BUILD_ROOT/%{_bindir}/qemu-nbd-xen
# This is necessary because of the build of libconfig for libxl
#rm -rf $RPM_BUILD_ROOT/$RPM_BUILD_ROOT
rm -rf $RPM_BUILD_ROOT/%{_libdir}/debug
#install firewall definitions format is described here:
#/usr/share/SuSEfirewall2/services/TEMPLATE
mkdir -p $RPM_BUILD_ROOT/%{_fwdefdir}
install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
%else
# 32 bit hypervisor no longer supported. Remove dom0 tools.
rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc
rm -rf $RPM_BUILD_ROOT/%{_datadir}/man
rm -rf $RPM_BUILD_ROOT/%{_datadir}/xen
rm -rf $RPM_BUILD_ROOT/%{_datadir}/locale
rm -rf $RPM_BUILD_ROOT/%{_libdir}/xen
rm -rf $RPM_BUILD_ROOT/%{_libdir}/python*
rm -rf $RPM_BUILD_ROOT/usr/sbin
rm -rf $RPM_BUILD_ROOT/etc/bash_completion.d
rm -rf $RPM_BUILD_ROOT/etc/init.d
rm -rf $RPM_BUILD_ROOT/etc/logrotate.d
rm -rf $RPM_BUILD_ROOT/etc/pam.d
rm -rf $RPM_BUILD_ROOT/etc/sysconfig
rm -rf $RPM_BUILD_ROOT/etc/udev
rm -rf $RPM_BUILD_ROOT/etc/xen
rm -rf $RPM_BUILD_ROOT/var
rm -f $RPM_BUILD_ROOT/%{_bindir}/*store*
rm -f $RPM_BUILD_ROOT/%{_bindir}/*trace*
rm -f $RPM_BUILD_ROOT/%{_bindir}/xenalyze*
rm -f $RPM_BUILD_ROOT/%{_bindir}/qemu*
rm -f $RPM_BUILD_ROOT/%{_bindir}/pygrub
rm -f $RPM_BUILD_ROOT/%{_bindir}/remus
rm -f $RPM_BUILD_ROOT/%{_bindir}/tapdisk-ioemu
rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
%endif
%if %{?with_dom0_support}0
%files
%defattr(-,root,root)
/boot/xen-%{version}-%{release}.gz
@ -983,12 +1072,18 @@ install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
/boot/xen-syms-dbg
/boot/xen-syms-dbg-%{version}-%{release}
/boot/xen.gz
# EFI
#%ifarch x86_64
#/boot/efi/efi/SuSE/xen-%{version}-%{release}.efi
#%endif
%endif
%files libs
%defattr(-,root,root)
%{_libdir}/fs/
%{_libdir}/*.so.*
%if %{?with_dom0_support}0
%files tools
%defattr(-,root,root)
/usr/bin/xenalyze
@ -1052,6 +1147,7 @@ install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
%dir /var/lib/xen/xend-db/vnet
%dir /var/lib/xenstored
%dir /var/log/xen
%dir /var/log/xen/console
%config /etc/init.d/*
%config /etc/logrotate.d/xen
%dir %attr(700,root,root) /etc/xen
@ -1118,12 +1214,14 @@ install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
%{_libdir}/python%{pyver}/site-packages/fsimage.so
%if %{?with_stubdom}0
/usr/lib/xen/boot/ioemu-stubdom.gz
/usr/lib/xen/boot/pv-grub-x86_32.gz
%ifarch x86_64
/usr/lib/xen/boot/pv-grub-x86_64.gz
%else
/usr/lib/xen/boot/pv-grub-x86_32.gz
%endif
%endif
%config %{_fwdefdir}/xend-relocation-server
%endif
%files tools-domU
%defattr(-,root,root)
@ -1133,11 +1231,12 @@ install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
%files devel
%defattr(-,root,root)
%{_bindir}/serial-split
%{_libdir}/*.a
%{_libdir}/*.so
/usr/include/*
/usr/bin/serial-split
%if %{?with_dom0_support}0
%files doc-html
%defattr(-,root,root)
%{_defaultdocdir}/xen/html
@ -1145,7 +1244,9 @@ install -m 644 %{S:26} $RPM_BUILD_ROOT/%{_fwdefdir}/xend-relocation-server
%files doc-pdf
%defattr(-,root,root)
%{_defaultdocdir}/xen/pdf
%endif
%if %{?with_dom0_support}0
%post tools
%if %{?with_xend}0
# with_xend
@ -1205,6 +1306,7 @@ fi
if [ -f /usr/bin/qemu-nbd-xen ]; then
rm /usr/bin/qemu-nbd-xen
fi
%endif
%post libs -p /sbin/ldconfig

View File

@ -223,7 +223,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -4499,8 +4499,14 @@ class XendDomainInfo:
@@ -4513,8 +4513,14 @@ class XendDomainInfo:
# Return name of host contained in lock file.
def get_lock_host(self, path):
@ -240,7 +240,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
hostname = "unknown"
try:
@@ -4522,6 +4528,16 @@ class XendDomainInfo:
@@ -4536,6 +4542,16 @@ class XendDomainInfo:
path = xoptions.get_xend_domain_lock_path()
path = os.path.join(path, self.get_uuid())
@ -257,7 +257,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
try:
if not os.path.exists(path):
mkdir.parents(path, stat.S_IRWXU)
@@ -4529,12 +4545,7 @@ class XendDomainInfo:
@@ -4543,12 +4559,7 @@ class XendDomainInfo:
log.exception("%s could not be created." % path)
raise XendError("%s could not be created." % path)
@ -271,7 +271,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
if status != 0:
log.debug("Failed to aqcuire lock: status = %d" % status)
raise XendError("The VM is locked and appears to be running on host %s." % self.get_lock_host(path))
@@ -4551,12 +4562,18 @@ class XendDomainInfo:
@@ -4565,12 +4576,18 @@ class XendDomainInfo:
path = xoptions.get_xend_domain_lock_path()
path = os.path.join(path, self.get_uuid())

View File

@ -257,7 +257,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
XendTask.log_progress(0, 30, self._constructDomain)
XendTask.log_progress(31, 60, self._initDomain)
@@ -2984,6 +2985,11 @@ class XendDomainInfo:
@@ -2998,6 +2999,11 @@ class XendDomainInfo:
self._stateSet(DOM_STATE_HALTED)
self.domid = None # Do not push into _stateSet()!
@ -269,7 +269,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
finally:
self.refresh_shutdown_lock.release()
@@ -4491,6 +4497,74 @@ class XendDomainInfo:
@@ -4505,6 +4511,74 @@ class XendDomainInfo:
def has_device(self, dev_class, dev_uuid):
return (dev_uuid in self.info['%s_refs' % dev_class.lower()])

View File

@ -104,7 +104,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendConfig.py
'loader': str,
'display' : str,
'fda': str,
@@ -514,6 +518,14 @@ class XendConfig(dict):
@@ -516,6 +520,14 @@ class XendConfig(dict):
self['platform']['nomigrate'] = 0
if self.is_hvm():
@ -123,7 +123,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.1.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2277,6 +2277,8 @@ class XendDomainInfo:
@@ -2291,6 +2291,8 @@ class XendDomainInfo:
self.info['name_label'], self.domid, self.info['uuid'],
new_name, new_uuid)
self._unwatchVm()
@ -132,7 +132,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
self._releaseDevices()
# Remove existing vm node in xenstore
self._removeVm()
@@ -2948,6 +2950,9 @@ class XendDomainInfo:
@@ -2962,6 +2964,9 @@ class XendDomainInfo:
self._createDevices()
@ -142,7 +142,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
self.image.cleanupTmpImages()
self.info['start_time'] = time.time()
@@ -2972,6 +2977,8 @@ class XendDomainInfo:
@@ -2986,6 +2991,8 @@ class XendDomainInfo:
self.refresh_shutdown_lock.acquire()
try:
self.unwatchShutdown()
@ -151,7 +151,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
self._releaseDevices()
bootloader_tidy(self)
@@ -3056,6 +3063,7 @@ class XendDomainInfo:
@@ -3070,6 +3077,7 @@ class XendDomainInfo:
self.image = image.create(self, self.info)
if self.image:
self._createDevices(True)
@ -159,7 +159,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
self._storeDomDetails()
self._registerWatches()
self.refreshShutdown()
@@ -3196,6 +3204,8 @@ class XendDomainInfo:
@@ -3210,6 +3218,8 @@ class XendDomainInfo:
# could also fetch a parsed note from xenstore
fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0
if not fast:
@ -168,7 +168,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xend/XendDomainInfo.py
self._releaseDevices()
self.testDeviceComplete()
self.testvifsComplete()
@@ -3211,6 +3221,8 @@ class XendDomainInfo:
@@ -3225,6 +3235,8 @@ class XendDomainInfo:
self._storeDomDetails()
self._createDevices()
@ -309,7 +309,7 @@ Index: xen-4.1.1-testing/tools/python/xen/xm/create.py
gopts.var('device_model', val='FILE',
fn=set_value, default=None,
use="Path to device model program.")
@@ -1080,6 +1096,10 @@ def configure_hvm(config_image, vals):
@@ -1095,6 +1111,10 @@ def configure_hvm(config_image, vals):
args = [ 'acpi', 'apic',
'boot',
'cpuid', 'cpuid_check',