# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 5f077cd6f58cc466d0ed3845955a2084fb348a33
# Parent 6e7cc23ab18c23fdb2a8b4d0a7778c4144851818
# Parent 38f9bd7a4ce6e164bd720292fb0a75a75cad9d19
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/drivers/xen/core/skbuff.c | 7
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 70 ++++++---
tools/firmware/hvmloader/hvmloader.c | 6
tools/firmware/hvmloader/smbios.c | 146 ++++++-------------
tools/python/xen/xm/main.py | 2
tools/python/xen/xm/rmlabel.py | 3
xen/arch/ia64/xen/xensetup.c | 2
xen/arch/x86/hvm/platform.c | 31 +++-
xen/common/grant_table.c | 2
9 files changed, 145 insertions(+), 124 deletions(-)
diff -r 6e7cc23ab18c -r 5f077cd6f58c
linux-2.6-xen-sparse/drivers/xen/core/skbuff.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Mon Oct 02 21:53:07
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Tue Oct 03 08:59:22
2006 -0600
@@ -18,7 +18,12 @@
/*static*/ kmem_cache_t *skbuff_cachep;
EXPORT_SYMBOL(skbuff_cachep);
-#define MAX_SKBUFF_ORDER 4
+/* Allow up to 64kB or page-sized packets (whichever is greater). */
+#if PAGE_SHIFT < 16
+#define MAX_SKBUFF_ORDER (16 - PAGE_SHIFT)
+#else
+#define MAX_SKBUFF_ORDER 0
+#endif
static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1];
static struct {
diff -r 6e7cc23ab18c -r 5f077cd6f58c
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Oct 02
21:53:07 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Oct 03
08:59:22 2006 -0600
@@ -63,6 +63,25 @@
#include <xen/interface/grant_table.h>
#include <xen/gnttab.h>
+/*
+ * Mutually-exclusive module options to select receive data path:
+ * rx_copy : Packets are copied by network backend into local memory
+ * rx_flip : Page containing packet data is transferred to our ownership
+ * For fully-virtualised guests there is no option - copying must be used.
+ * For paravirtualised guests, flipping is the default.
+ */
+#ifdef CONFIG_XEN
+static int MODPARM_rx_copy = 0;
+module_param_named(rx_copy, MODPARM_rx_copy, bool, 0);
+MODULE_PARM_DESC(rx_copy, "Copy packets from network card (rather than flip)");
+static int MODPARM_rx_flip = 0;
+module_param_named(rx_flip, MODPARM_rx_flip, bool, 0);
+MODULE_PARM_DESC(rx_flip, "Flip packets from network card (rather than copy)");
+#else
+static const int MODPARM_rx_copy = 1;
+static const int MODPARM_rx_flip = 0;
+#endif
+
#define RX_COPY_THRESHOLD 256
/* If we don't have GSO, fake things up so that we never try to use it. */
@@ -229,8 +248,7 @@ static int __devinit netfront_probe(stru
int err;
struct net_device *netdev;
struct netfront_info *info;
- unsigned int handle;
- unsigned feature_rx_copy;
+ unsigned int handle, feature_rx_copy, feature_rx_flip, use_copy;
err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
if (err != 1) {
@@ -238,22 +256,24 @@ static int __devinit netfront_probe(stru
return err;
}
-#ifndef CONFIG_XEN
err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u",
&feature_rx_copy);
- if (err != 1) {
- xenbus_dev_fatal(dev, err, "reading feature-rx-copy");
- return err;
- }
- if (!feature_rx_copy) {
- xenbus_dev_fatal(dev, 0, "need a copy-capable backend");
- return -EINVAL;
- }
-#else
- feature_rx_copy = 0;
-#endif
-
- netdev = create_netdev(handle, feature_rx_copy, dev);
+ if (err != 1)
+ feature_rx_copy = 0;
+ err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flip", "%u",
+ &feature_rx_flip);
+ if (err != 1)
+ feature_rx_flip = 1;
+
+ /*
+ * Copy packets on receive path if:
+ * (a) This was requested by user, and the backend supports it; or
+ * (b) Flipping was requested, but this is unsupported by the backend.
+ */
+ use_copy = (MODPARM_rx_copy && feature_rx_copy) ||
+ (MODPARM_rx_flip && !feature_rx_flip);
+
+ netdev = create_netdev(handle, use_copy, dev);
if (IS_ERR(netdev)) {
err = PTR_ERR(netdev);
xenbus_dev_fatal(dev, err, "creating netdev");
@@ -270,6 +290,9 @@ static int __devinit netfront_probe(stru
err = open_netdev(info);
if (err)
goto fail_open;
+
+ IPRINTK("Created netdev %s with %sing receive path.\n",
+ netdev->name, info->copying_receiver ? "copy" : "flipp");
return 0;
@@ -742,7 +765,7 @@ no_skb:
} else {
gnttab_grant_foreign_access_ref(ref,
np->xbdev->otherend_id,
- pfn,
+ pfn_to_mfn(pfn),
0);
}
@@ -1632,7 +1655,8 @@ static void network_connect(struct net_d
} else {
gnttab_grant_foreign_access_ref(
ref, np->xbdev->otherend_id,
- page_to_pfn(skb_shinfo(skb)->frags->page),
+ pfn_to_mfn(page_to_pfn(skb_shinfo(skb)->
+ frags->page)),
0);
}
req->gref = ref;
@@ -2053,6 +2077,16 @@ static int __init netif_init(void)
if (!is_running_on_xen())
return -ENODEV;
+#ifdef CONFIG_XEN
+ if (MODPARM_rx_flip && MODPARM_rx_copy) {
+ WPRINTK("Cannot specify both rx_copy and rx_flip.\n");
+ return -EINVAL;
+ }
+
+ if (!MODPARM_rx_flip && !MODPARM_rx_copy)
+ MODPARM_rx_flip = 1; /* Default is to flip. */
+#endif
+
if (is_initial_xendomain())
return 0;
diff -r 6e7cc23ab18c -r 5f077cd6f58c tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Mon Oct 02 21:53:07 2006 -0600
+++ b/tools/firmware/hvmloader/hvmloader.c Tue Oct 03 08:59:22 2006 -0600
@@ -170,6 +170,9 @@ main(void)
init_hypercalls();
+ puts("Writing SMBIOS tables ...\n");
+ hvm_write_smbios_tables();
+
puts("Loading ROMBIOS ...\n");
memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
@@ -201,9 +204,6 @@ main(void)
}
}
- puts("Writing SMBIOS tables ...\n");
- hvm_write_smbios_tables();
-
if (check_amd()) {
/* AMD implies this is SVM */
puts("SVM go ...\n");
diff -r 6e7cc23ab18c -r 5f077cd6f58c tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Mon Oct 02 21:53:07 2006 -0600
+++ b/tools/firmware/hvmloader/smbios.c Tue Oct 03 08:59:22 2006 -0600
@@ -28,23 +28,15 @@
#include "util.h"
#include "hypercall.h"
-/* write SMBIOS tables starting at 'start', without writing more
- than 'max_size' bytes.
-
- Return the number of bytes written
-*/
static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version);
static void
get_cpu_manufacturer(char *buf, int len);
-static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
- const char *processor_manufacturer);
-static void *
+static void
smbios_entry_point_init(void *start,
uint16_t max_structure_size,
uint16_t structure_table_length,
@@ -71,7 +63,7 @@ smbios_type_20_init(void *start, uint32_
smbios_type_20_init(void *start, uint32_t memory_size_mb);
static void *
smbios_type_32_init(void *start);
-void *
+static void *
smbios_type_127_init(void *start);
static void
@@ -80,7 +72,8 @@ get_cpu_manufacturer(char *buf, int len)
char id[12];
uint32_t eax = 0;
- cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], (uint32_t
*)&id[4]);
+ cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],
+ (uint32_t *)&id[4]);
if (memcmp(id, "GenuineIntel", 12) == 0)
strncpy(buf, "Intel", len);
@@ -90,90 +83,51 @@ get_cpu_manufacturer(char *buf, int len)
strncpy(buf, "unknown", len);
}
-
-/* Calculate the size of the SMBIOS structure table.
-*/
static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
- const char *processor_manufacturer)
-{
- size_t size;
-
- /* first compute size without strings or terminating 0 bytes */
- size = sizeof(struct smbios_type_0) + sizeof(struct smbios_type_1) +
- sizeof(struct smbios_type_3) + sizeof(struct
smbios_type_4)*vcpus +
- sizeof(struct smbios_type_16) + sizeof(struct smbios_type_17) +
- sizeof(struct smbios_type_19) + sizeof(struct smbios_type_20) +
- sizeof(struct smbios_type_32) + sizeof(struct smbios_type_127);
-
- /* 5 structures with no strings, 2 null bytes each */
- size += 10;
-
- /* Need to include 1 null byte per structure with strings (first
- terminating null byte comes from the string terminator of the
- last string). */
- size += 4 + vcpus;
-
- /* type 0: "Xen", xen_version, and release_date */
- size += strlen("Xen") + strlen(xen_version) + 2;
- /* type 1: "Xen", xen_version, "HVM domU", UUID as string for
- serial number */
- size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) +
- 36 + 4;
- /* type 3: "Xen" */
- size += strlen("Xen") + 1;
- /* type 4: socket designation ("CPU n"), processor_manufacturer */
- size += vcpus * (strlen("CPU n") + strlen(processor_manufacturer) + 2);
- /* Make room for two-digit CPU numbers if necessary -- doesn't handle
- vcpus > 99 */
- if (vcpus > 9)
- size += vcpus - 9;
- /* type 17: device locator string ("DIMM 1") */
- size += strlen("DIMM 1") + 1;
-
- return size;
-}
-
-static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version)
{
- unsigned cpu_num;
- void *p = start;
+ unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
+ char *p, *q;
char cpu_manufacturer[15];
size_t structure_table_length;
get_cpu_manufacturer(cpu_manufacturer, 15);
-
- structure_table_length = smbios_table_size(vcpus, xen_version,
- cpu_manufacturer);
-
- if (structure_table_length + sizeof(struct smbios_entry_point) >
max_size)
- return 0;
-
- p = smbios_entry_point_init(p, sizeof(struct smbios_type_4),
- structure_table_length,
- (uint32_t)start +
- sizeof(struct smbios_entry_point),
- 9 + vcpus);
-
- p = smbios_type_0_init(p, xen_version, xen_major_version,
- xen_minor_version);
- p = smbios_type_1_init(p, xen_version, uuid);
- p = smbios_type_3_init(p);
- for (cpu_num = 1; cpu_num <= vcpus; ++cpu_num)
- p = smbios_type_4_init(p, cpu_num, cpu_manufacturer);
- p = smbios_type_16_init(p, memsize);
- p = smbios_type_17_init(p, memsize);
- p = smbios_type_19_init(p, memsize);
- p = smbios_type_20_init(p, memsize);
- p = smbios_type_32_init(p);
- p = smbios_type_127_init(p);
-
- return (size_t)((char*)p - (char*)start);
+ p = (char *)start + sizeof(struct smbios_entry_point);
+
+#define do_struct(fn) do { \
+ q = (fn); \
+ nr_structs++; \
+ if ((q - p) > max_struct_size) \
+ max_struct_size = q - p; \
+ p = q; \
+} while (0)
+
+ do_struct(smbios_type_0_init(p, xen_version, xen_major_version,
+ xen_minor_version));
+ do_struct(smbios_type_1_init(p, xen_version, uuid));
+ do_struct(smbios_type_3_init(p));
+ for (cpu_num = 1; cpu_num <= vcpus; cpu_num++)
+ do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
+ do_struct(smbios_type_16_init(p, memsize));
+ do_struct(smbios_type_17_init(p, memsize));
+ do_struct(smbios_type_19_init(p, memsize));
+ do_struct(smbios_type_20_init(p, memsize));
+ do_struct(smbios_type_32_init(p));
+ do_struct(smbios_type_127_init(p));
+
+#undef do_struct
+
+ smbios_entry_point_init(
+ start, max_struct_size,
+ (p - (char *)start) - sizeof(struct smbios_entry_point),
+ SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
+ nr_structs);
+
+ return (size_t)((char *)p - (char *)start);
}
/* This tries to figure out how much pseudo-physical memory (in MB)
@@ -278,10 +232,16 @@ hvm_write_smbios_tables(void)
xen_version_str[sizeof(xen_version_str)-1] = '\0';
- write_smbios_tables((void *) SMBIOS_PHYSICAL_ADDRESS,
- SMBIOS_SIZE_LIMIT, get_vcpu_nr(), get_memsize(),
- uuid, xen_version_str,
- xen_major_version, xen_minor_version);
+ /* NB. 0xC0000 is a safe large memory area for scratch. */
+ len = write_smbios_tables((void *)0xC0000,
+ get_vcpu_nr(), get_memsize(),
+ uuid, xen_version_str,
+ xen_major_version, xen_minor_version);
+ if (len > SMBIOS_SIZE_LIMIT)
+ goto error_out;
+ /* Okay, not too large: copy out of scratch to final location. */
+ memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
+
return;
error_out:
@@ -290,7 +250,7 @@ hvm_write_smbios_tables(void)
}
-static void *
+static void
smbios_entry_point_init(void *start,
uint16_t max_structure_size,
uint16_t structure_table_length,
@@ -327,8 +287,6 @@ smbios_entry_point_init(void *start,
for (i = 0x10; i < ep->length; ++i)
sum += ((int8_t *)start)[i];
ep->intermediate_checksum = -sum;
-
- return (char *)start + sizeof(struct smbios_entry_point);
}
/* Type 0 -- BIOS Information */
@@ -597,7 +555,7 @@ smbios_type_32_init(void *start)
}
/* Type 127 -- End of Table */
-void *
+static void *
smbios_type_127_init(void *start)
{
struct smbios_type_127 *p = (struct smbios_type_127 *)start;
diff -r 6e7cc23ab18c -r 5f077cd6f58c tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Mon Oct 02 21:53:07 2006 -0600
+++ b/tools/python/xen/xm/main.py Tue Oct 03 08:59:22 2006 -0600
@@ -1222,7 +1222,7 @@ def parse_block_configuration(args):
label = security.get_security_printlabel(dominfo)
else:
label = None
- security.res_security_check(args[1], label)
+ security.res_security_check(args[1], label)
return (dom, vbd)
diff -r 6e7cc23ab18c -r 5f077cd6f58c tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py Mon Oct 02 21:53:07 2006 -0600
+++ b/tools/python/xen/xm/rmlabel.py Tue Oct 03 08:59:22 2006 -0600
@@ -57,7 +57,8 @@ def rm_domain_label(configfile):
fd = None
file = None
if configfile[0] == '/':
- fd = open(configfile, "rb")
+ file = configfile
+ fd = open(file, "rb")
else:
for prefix in [".", "/etc/xen"]:
file = prefix + "/" + configfile
diff -r 6e7cc23ab18c -r 5f077cd6f58c xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Mon Oct 02 21:53:07 2006 -0600
+++ b/xen/arch/ia64/xen/xensetup.c Tue Oct 03 08:59:22 2006 -0600
@@ -18,6 +18,7 @@
#include <xen/domain.h>
#include <xen/serial.h>
#include <xen/trace.h>
+#include <xen/keyhandler.h>
#include <asm/meminit.h>
#include <asm/page.h>
#include <asm/setup.h>
@@ -25,7 +26,6 @@
#include <asm/vmx.h>
#include <linux/efi.h>
#include <asm/iosapic.h>
-#include <xen/keyhandler.h>
unsigned long xenheap_phys_end, total_pages;
diff -r 6e7cc23ab18c -r 5f077cd6f58c xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Mon Oct 02 21:53:07 2006 -0600
+++ b/xen/arch/x86/hvm/platform.c Tue Oct 03 08:59:22 2006 -0600
@@ -730,6 +730,11 @@ void send_pio_req(struct cpu_user_regs *
vcpu_iodata_t *vio;
ioreq_t *p;
+ if (size == 0 || count == 0) {
+ printf("null pio request? port %lx, count %lx, size %d, value %lx, dir
%d, pvalid %d.\n",
+ port, count, size, value, dir, pvalid);
+ }
+
vio = get_vio(v->domain, v->vcpu_id);
if (vio == NULL) {
printk("bad shared page: %lx\n", (unsigned long) vio);
@@ -768,7 +773,7 @@ void send_pio_req(struct cpu_user_regs *
hvm_send_assist_req(v);
}
-void send_mmio_req(
+static void send_mmio_req(
unsigned char type, unsigned long gpa,
unsigned long count, int size, long value, int dir, int pvalid)
{
@@ -776,6 +781,11 @@ void send_mmio_req(
vcpu_iodata_t *vio;
ioreq_t *p;
struct cpu_user_regs *regs;
+
+ if (size == 0 || count == 0) {
+ printf("null mmio request? type %d, gpa %lx, count %lx, size %d, value
%lx, dir %d, pvalid %d.\n",
+ type, gpa, count, size, value, dir, pvalid);
+ }
regs = ¤t->arch.hvm_vcpu.io_op.io_context;
@@ -917,6 +927,8 @@ void handle_mmio(unsigned long va, unsig
int sign = regs->eflags & EF_DF ? -1 : 1;
unsigned long addr = 0;
int dir;
+
+ ASSERT(count);
/* determine non-MMIO address */
if (realmode) {
@@ -940,6 +952,9 @@ void handle_mmio(unsigned long va, unsig
mmio_opp->flags = mmio_inst.flags;
mmio_opp->instr = mmio_inst.instr;
+ if (addr & (size - 1))
+ DPRINTK("Unaligned ioport access: %lx, %ld\n", addr, size);
+
/*
* In case of a movs spanning multiple pages, we break the accesses
* up into multiple pages (the device model works with non-continguous
@@ -953,6 +968,7 @@ void handle_mmio(unsigned long va, unsig
if ((addr & PAGE_MASK) != ((addr + sign * (size - 1)) & PAGE_MASK)) {
unsigned long value = 0;
+ DPRINTK("Single io request in a movs crossing page boundary.\n");
mmio_opp->flags |= OVERLAP;
regs->eip -= inst_len; /* do not advance %eip */
@@ -964,12 +980,19 @@ void handle_mmio(unsigned long va, unsig
if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) &
PAGE_MASK)) {
regs->eip -= inst_len; /* do not advance %eip */
- if (sign > 0)
+ if (sign > 0) {
count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
- else
- count = (addr & ~PAGE_MASK) / size;
+ } else {
+ /* We need to make sure we advance to the point
+ where the next request will be on a different
+ page. If we're going down, that means
+ advancing until one byte before the start of
+ the page, hence +1. */
+ count = ((addr + 1) & ~PAGE_MASK) / size;
+ }
}
+ ASSERT(count);
send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
}
break;
diff -r 6e7cc23ab18c -r 5f077cd6f58c xen/common/grant_table.c
--- a/xen/common/grant_table.c Mon Oct 02 21:53:07 2006 -0600
+++ b/xen/common/grant_table.c Tue Oct 03 08:59:22 2006 -0600
@@ -903,7 +903,7 @@ __gnttab_copy(
}
if ( !get_page_and_type(mfn_to_page(d_frame), dd, PGT_writable_page) )
PIN_FAIL(error_out, GNTST_general_error,
- "could not get source frame %lx.\n", d_frame);
+ "could not get destination frame %lx.\n", d_frame);
sp = map_domain_page(s_frame);
dp = map_domain_page(d_frame);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|