From 7554501778c95f7ec3bb47d024b48685329347b6 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 2 Nov 2006 11:11:28 +0000 Subject: [PATCH 1/6] [TOOLS] Paravirt guests have their memory allocated in the libxenguest builder function. Again, PPC and IA64 will need to do some fixing up. Signed-off-by: Keir Fraser --- tools/libxc/xc_linux_build.c | 88 ++++++++----------------- tools/libxc/xenguest.h | 32 +++++---- tools/python/xen/lowlevel/xc/xc.c | 9 +-- tools/python/xen/xend/XendDomainInfo.py | 11 +--- tools/python/xen/xend/image.py | 24 +++++-- 5 files changed, 68 insertions(+), 96 deletions(-) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 792d9dabae..af9a63cced 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -25,12 +25,6 @@ #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #endif -#ifdef __ia64__ -#define get_tot_pages xc_get_max_pages -#else -#define get_tot_pages xc_get_tot_pages -#endif - #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) #define round_pgdown(_p) ((_p)&PAGE_MASK) @@ -674,7 +668,6 @@ static int setup_guest(int xc_handle, int hypercall_page_defined; start_info_t *start_info; shared_info_t *shared_info; - xc_mmu_t *mmu = NULL; const char *p; DECLARE_DOMCTL; int rc; @@ -716,7 +709,7 @@ static int setup_guest(int xc_handle, goto error_out; } - if (!compat_check(xc_handle, &dsi)) + if ( !compat_check(xc_handle, &dsi) ) goto error_out; /* Parse and validate kernel features. */ @@ -751,9 +744,13 @@ static int setup_guest(int xc_handle, goto error_out; } - if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages ) + for ( i = 0; i < nr_pages; i++ ) + page_array[i] = i; + + if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages, + 0, 0, page_array) ) { - PERROR("Could not get the page frame list"); + PERROR("Could not allocate memory for PV guest.\n"); goto error_out; } @@ -885,9 +882,8 @@ static int setup_guest(int xc_handle, goto error_out; } - /* setup page tables */ #if defined(__i386__) - if (dsi.pae_kernel != PAEKERN_no) + if ( dsi.pae_kernel != PAEKERN_no ) rc = setup_pg_tables_pae(xc_handle, dom, ctxt, dsi.v_start, v_end, page_array, vpt_start, vpt_end, @@ -904,16 +900,16 @@ static int setup_guest(int xc_handle, page_array, vpt_start, vpt_end, shadow_mode_enabled); #endif - if (0 != rc) + if ( rc != 0 ) goto error_out; -#if defined(__i386__) /* * Pin down l2tab addr as page dir page - causes hypervisor to provide * correct protection for the page */ if ( !shadow_mode_enabled ) { +#if defined(__i386__) if ( dsi.pae_kernel != PAEKERN_no ) { if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE, @@ -926,40 +922,24 @@ static int setup_guest(int xc_handle, xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) goto error_out; } +#elif defined(__x86_64__) + /* + * Pin down l4tab addr as page dir page - causes hypervisor to provide + * correct protection for the page + */ + if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE, + xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) + goto error_out; +#endif } -#endif -#if defined(__x86_64__) - /* - * Pin down l4tab addr as page dir page - causes hypervisor to provide - * correct protection for the page - */ - if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE, - xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) - goto error_out; -#endif - - if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL ) - goto error_out; - - /* Write the phys->machine and machine->phys table entries. */ + /* Write the phys->machine table entries (machine->phys already done). */ physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT; physmap = physmap_e = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[physmap_pfn++]); - for ( count = 0; count < nr_pages; count++ ) { - if ( xc_add_mmu_update( - xc_handle, mmu, - ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, - count) ) - { - DPRINTF("m2p update failure p=%lx m=%"PRIx64"\n", - count, (uint64_t)page_array[count]); - munmap(physmap, PAGE_SIZE); - goto error_out; - } *physmap_e++ = page_array[count]; if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 ) { @@ -971,10 +951,6 @@ static int setup_guest(int xc_handle, } munmap(physmap, PAGE_SIZE); - /* Send the page update requests down to the hypervisor. */ - if ( xc_finish_mmu_updates(xc_handle, mmu) ) - goto error_out; - if ( shadow_mode_enabled ) { struct xen_add_to_physmap xatp; @@ -1081,10 +1057,6 @@ static int setup_guest(int xc_handle, munmap(shared_info, PAGE_SIZE); - /* Send the page update requests down to the hypervisor. */ - if ( xc_finish_mmu_updates(xc_handle, mmu) ) - goto error_out; - hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); if ( hypercall_page_defined ) @@ -1100,7 +1072,6 @@ static int setup_guest(int xc_handle, goto error_out; } - free(mmu); free(page_array); *pvsi = vstartinfo_start; @@ -1110,7 +1081,6 @@ static int setup_guest(int xc_handle, return 0; error_out: - free(mmu); free(page_array); return -1; } @@ -1118,6 +1088,7 @@ static int setup_guest(int xc_handle, static int xc_linux_build_internal(int xc_handle, uint32_t domid, + unsigned int mem_mb, char *image, unsigned long image_size, struct initrd_info *initrd, @@ -1132,8 +1103,7 @@ static int xc_linux_build_internal(int xc_handle, struct xen_domctl launch_domctl; DECLARE_DOMCTL; int rc, i; - vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; - unsigned long nr_pages; + struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt; unsigned long vstartinfo_start, vkern_entry, vstack_start; uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; @@ -1146,12 +1116,6 @@ static int xc_linux_build_internal(int xc_handle, } } - if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 ) - { - PERROR("Could not find total pages for domain"); - goto error_out; - } - #ifdef VALGRIND memset(&st_ctxt, 0, sizeof(st_ctxt)); #endif @@ -1175,7 +1139,7 @@ static int xc_linux_build_internal(int xc_handle, if ( setup_guest(xc_handle, domid, image, image_size, initrd, - nr_pages, + mem_mb << (20 - PAGE_SHIFT), &vstartinfo_start, &vkern_entry, &vstack_start, ctxt, cmdline, domctl.u.getdomaininfo.shared_info_frame, @@ -1271,6 +1235,7 @@ static int xc_linux_build_internal(int xc_handle, int xc_linux_build_mem(int xc_handle, uint32_t domid, + unsigned int mem_mb, const char *image_buffer, unsigned long image_size, const char *initrd, @@ -1319,7 +1284,7 @@ int xc_linux_build_mem(int xc_handle, } } - sts = xc_linux_build_internal(xc_handle, domid, img_buf, img_len, + sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len, &initrd_info, cmdline, features, flags, store_evtchn, store_mfn, console_evtchn, console_mfn); @@ -1339,6 +1304,7 @@ int xc_linux_build_mem(int xc_handle, int xc_linux_build(int xc_handle, uint32_t domid, + unsigned int mem_mb, const char *image_name, const char *initrd_name, const char *cmdline, @@ -1375,7 +1341,7 @@ int xc_linux_build(int xc_handle, } } - sts = xc_linux_build_internal(xc_handle, domid, image, image_size, + sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size, &initrd_info, cmdline, features, flags, store_evtchn, store_mfn, console_evtchn, console_mfn); diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 948c03b509..75e0c47be5 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -48,8 +48,9 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, * * @parm xc_handle a handle to an open hypervisor interface * @parm domid the id of the domain - * @param image_name name of the kernel image file - * @param ramdisk_name name of the ramdisk image file + * @parm mem_mb memory size in megabytes + * @parm image_name name of the kernel image file + * @parm ramdisk_name name of the ramdisk image file * @parm cmdline command line string * @parm flags domain creation flags * @parm store_evtchn the store event channel for this domain to use @@ -60,6 +61,7 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, */ int xc_linux_build(int xc_handle, uint32_t domid, + unsigned int mem_mb, const char *image_name, const char *ramdisk_name, const char *cmdline, @@ -74,22 +76,24 @@ int xc_linux_build(int xc_handle, * This function will create a domain for a paravirtualized Linux * using buffers for kernel and initrd * - * @param xc_handle a handle to an open hypervisor interface - * @param domid the id of the domain - * @param image_buffer buffer containing kernel image - * @param image_size size of the kernel image buffer - * @param initrd_buffer name of the ramdisk image file - * @param initrd_size size of the ramdisk buffer - * @param cmdline command line string - * @param flags domain creation flags - * @param store_evtchn the store event channel for this domain to use - * @param store_mfn returned with the mfn of the store page - * @param console_evtchn the console event channel for this domain to use - * @param conole_mfn returned with the mfn of the console page + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the id of the domain + * @parm mem_mb memory size in megabytes + * @parm image_buffer buffer containing kernel image + * @parm image_size size of the kernel image buffer + * @parm initrd_buffer name of the ramdisk image file + * @parm initrd_size size of the ramdisk buffer + * @parm cmdline command line string + * @parm flags domain creation flags + * @parm store_evtchn the store event channel for this domain to use + * @parm store_mfn returned with the mfn of the store page + * @parm console_evtchn the console event channel for this domain to use + * @parm conole_mfn returned with the mfn of the console page * @return 0 on success, -1 on failure */ int xc_linux_build_mem(int xc_handle, uint32_t domid, + unsigned int mem_mb, const char *image_buffer, unsigned long image_size, const char *initrd_buffer, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 3fe3a474f2..34cc31b311 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -334,24 +334,25 @@ static PyObject *pyxc_linux_build(XcObject *self, char *image, *ramdisk = NULL, *cmdline = "", *features = NULL; int flags = 0; int store_evtchn, console_evtchn; + unsigned int mem_mb; unsigned long store_mfn = 0; unsigned long console_mfn = 0; - static char *kwd_list[] = { "domid", "store_evtchn", + static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "console_evtchn", "image", /* optional */ "ramdisk", "cmdline", "flags", "features", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list, - &dom, &store_evtchn, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list, + &dom, &store_evtchn, &mem_mb, &console_evtchn, &image, /* optional */ &ramdisk, &cmdline, &flags, &features) ) return NULL; - if ( xc_linux_build(self->xc_handle, dom, image, + if ( xc_linux_build(self->xc_handle, dom, mem_mb, image, ramdisk, cmdline, features, flags, store_evtchn, &store_mfn, console_evtchn, &console_mfn) != 0 ) { diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 93edfa7b03..0fa3572587 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1270,10 +1270,7 @@ class XendDomainInfo: # Use architecture- and image-specific calculations to determine # the various headrooms necessary, given the raw configured - # values. - # reservation, maxmem, memory, and shadow are all in KiB. - reservation = self.image.getRequiredInitialReservation( - self.info['memory'] * 1024) + # values. maxmem, memory, and shadow are all in KiB. maxmem = self.image.getRequiredAvailableMemory( self.info['maxmem'] * 1024) memory = self.image.getRequiredAvailableMemory( @@ -1296,12 +1293,6 @@ class XendDomainInfo: shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) self.info['shadow_memory'] = shadow_cur - # Initial memory reservation - if not (self._infoIsSet('image') and - sxp.name(self.info['image']) == "hvm"): - xc.domain_memory_increase_reservation( - self.domid, reservation, 0, 0) - self._createChannels() channel_details = self.image.createImage() diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index cd380e02e1..ef01fcf6cc 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -152,13 +152,13 @@ class ImageHandler: necessary.""" return mem_kb - def getRequiredInitialReservation(self, mem_kb): + def getRequiredInitialReservation(self): """@param mem_kb The configured memory, in KiB. @return The corresponding required amount of memory to be free, also in KiB. This is normally the same as getRequiredAvailableMemory, but architecture- or image-specific code may override this to add headroom where necessary.""" - return self.getRequiredAvailableMemory(mem_kb) + return self.getRequiredAvailableMemory(self.vm.getMemoryTarget()) def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): """@param shadow_mem_kb The configured shadow memory, in KiB. @@ -189,7 +189,10 @@ class LinuxImageHandler(ImageHandler): store_evtchn = self.vm.getStorePort() console_evtchn = self.vm.getConsolePort() + mem_mb = self.getRequiredInitialReservation() / 1024 + log.debug("domid = %d", self.vm.getDomid()) + log.debug("memsize = %d", mem_mb) log.debug("image = %s", self.kernel) log.debug("store_evtchn = %d", store_evtchn) log.debug("console_evtchn = %d", console_evtchn) @@ -199,6 +202,7 @@ class LinuxImageHandler(ImageHandler): log.debug("features = %s", self.vm.getFeatures()) return xc.linux_build(domid = self.vm.getDomid(), + memsize = mem_mb, image = self.kernel, store_evtchn = store_evtchn, console_evtchn = console_evtchn, @@ -218,7 +222,10 @@ class PPC_LinuxImageHandler(LinuxImageHandler): store_evtchn = self.vm.getStorePort() console_evtchn = self.vm.getConsolePort() + mem_mb = self.getRequiredInitialReservation() / 1024 + log.debug("domid = %d", self.vm.getDomid()) + log.debug("memsize = %d", mem_mb) log.debug("image = %s", self.kernel) log.debug("store_evtchn = %d", store_evtchn) log.debug("console_evtchn = %d", console_evtchn) @@ -230,6 +237,7 @@ class PPC_LinuxImageHandler(LinuxImageHandler): devtree = FlatDeviceTree.build(self) return xc.linux_build(domid = self.vm.getDomid(), + memsize = mem_mb, image = self.kernel, store_evtchn = store_evtchn, console_evtchn = console_evtchn, @@ -272,10 +280,12 @@ class HVMImageHandler(ImageHandler): def buildDomain(self): store_evtchn = self.vm.getStorePort() + mem_mb = self.getRequiredInitialReservation() / 1024 + log.debug("domid = %d", self.vm.getDomid()) log.debug("image = %s", self.kernel) log.debug("store_evtchn = %d", store_evtchn) - log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) + log.debug("memsize = %d", mem_mb) log.debug("vcpus = %d", self.vm.getVCpuCount()) log.debug("pae = %d", self.pae) log.debug("acpi = %d", self.acpi) @@ -286,7 +296,7 @@ class HVMImageHandler(ImageHandler): return xc.hvm_build(domid = self.vm.getDomid(), image = self.kernel, store_evtchn = store_evtchn, - memsize = self.vm.getMemoryTarget() / 1024, + memsize = mem_mb, vcpus = self.vm.getVCpuCount(), pae = self.pae, acpi = self.acpi, @@ -401,7 +411,7 @@ class HVMImageHandler(ImageHandler): #todo: Error handling args = [self.device_model] args = args + ([ "-d", "%d" % self.vm.getDomid(), - "-m", "%s" % (self.vm.getMemoryTarget() / 1024)]) + "-m", "%s" % (self.getRequiredInitialReservation() / 1024)]) args = args + self.dmargs env = dict(os.environ) if self.display: @@ -480,8 +490,8 @@ class X86_HVM_ImageHandler(HVMImageHandler): # Add 8 MiB overhead for QEMU's video RAM. return mem_kb + 8192 - def getRequiredInitialReservation(self, mem_kb): - return mem_kb + def getRequiredInitialReservation(self): + return self.vm.getMemoryTarget() def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): # 256 pages (1MB) per vcpu, From 0d7658072aa628260f075d2ef45ef1b2558a577c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 2 Nov 2006 11:56:26 +0000 Subject: [PATCH 2/6] PV-on-HVM: Use ln -nsf in mkbuildtree to avoid creating a symlink loop if include/xen/interfaces already exists. Signed-off-by: Ian Campbell --- unmodified_drivers/linux-2.6/mkbuildtree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unmodified_drivers/linux-2.6/mkbuildtree b/unmodified_drivers/linux-2.6/mkbuildtree index 5b6b8643ee..ddcc13c75e 100755 --- a/unmodified_drivers/linux-2.6/mkbuildtree +++ b/unmodified_drivers/linux-2.6/mkbuildtree @@ -31,7 +31,7 @@ mkdir -p include/asm mkdir -p include/asm/xen lndir -silent ${XL}/include/xen include/xen -ln -sf ${XEN}/include/public include/xen/interface +ln -nsf ${XEN}/include/public include/xen/interface # Need to be quite careful here: we don't want the files we link in to # risk overriding the native Linux ones (in particular, system.h must From d8656aaa3e9c089e3fb49a8bcd5ecccc1d6ce1eb Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 2 Nov 2006 11:56:26 +0000 Subject: [PATCH 3/6] PV-on-HVM: Fix PV-on-HVM drivers for IA64. Thanks to Kasai Takanori and Doi Tsunehisa for testing. Signed-off-by: Ian Campbell --- linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c | 5 +++++ .../drivers/xen/xenbus/xenbus_comms.c | 7 +++++-- linux-2.6-xen-sparse/include/asm-ia64/hypercall.h | 3 +++ .../compat-include/asm-generic/pgtable-nopud.h | 1 + .../compat-include/xen/platform-compat.h | 15 +++++++++++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c b/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c index 3767e893fc..367b6b32de 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c @@ -20,6 +20,11 @@ #include #include #include + +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include +#endif + #include static int xencomm_debug = 0; diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c index ea8f3c283e..f0e42ba715 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c @@ -30,13 +30,16 @@ * IN THE SOFTWARE. */ -#include -#include #include #include #include #include +#include +#include #include + +#include + #include "xenbus_comms.h" #ifdef HAVE_XEN_PLATFORM_COMPAT_H diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h index 43f88b1930..7a522be483 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h @@ -283,6 +283,9 @@ static inline void exit_idle(void) {} #ifdef CONFIG_XEN #include #endif /* CONFIG_XEN */ +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include +#endif static inline unsigned long __HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size) diff --git a/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h index 8b23299dd0..05c9675760 100644 --- a/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h +++ b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h @@ -9,6 +9,7 @@ #define pud_offset(d, va) d #define pud_none(pud) 0 #define pud_present(pud) 1 +#define pud_bad(pud) 0 #define PTRS_PER_PUD 1 #endif /* _PGTABLE_NOPUD_H */ diff --git a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h index 4978c63610..ea0e6b308f 100644 --- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h +++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h @@ -25,6 +25,21 @@ #define NET_IP_ALIGN 0 #endif +#if defined(_LINUX_ERR_H) && !defined(IS_ERR_VALUE) +#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L) +#endif + +#if defined(_ASM_IA64_PGTABLE_H) && !defined(_PGTABLE_NOPUD_H) +#include +#endif + +/* Some kernels have this typedef backported so we cannot reliably + * detect based on version number, hence we forcibly #define it. + */ +#if defined(__LINUX_TYPES_H) || defined(__LINUX_GFP_H) +#define gfp_t unsigned +#endif + #if defined(_LINUX_FS_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) #define nonseekable_open(inode, filp) /* Nothing to do */ #endif From 4101fafcc01b226bb48576d48ea36cc505d2c288 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 2 Nov 2006 11:56:26 +0000 Subject: [PATCH 4/6] PV-on-HVM: Tweak reboot.c to be compatible with older kernels. call_usermodehelper_keys() was not available until 2.6.13 but since we pass session_keyring as NULL we may as well use call_usermodehelper() anyway. Signed-off-by: Ian Campbell --- linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 4 ++-- unmodified_drivers/linux-2.6/util/Makefile | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 unmodified_drivers/linux-2.6/util/Makefile diff --git a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c index 1f19985c61..af3fe3a15c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c @@ -30,7 +30,7 @@ static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); #ifdef CONFIG_XEN int __xen_suspend(void); #else -#define __xen_suspend() 0 +#define __xen_suspend() (void)0 #endif static int shutdown_process(void *__unused) @@ -44,7 +44,7 @@ static int shutdown_process(void *__unused) if ((shutting_down == SHUTDOWN_POWEROFF) || (shutting_down == SHUTDOWN_HALT)) { - if (call_usermodehelper_keys("/sbin/poweroff", poweroff_argv, envp, NULL, 0) < 0) { + if (call_usermodehelper("/sbin/poweroff", poweroff_argv, envp, 0) < 0) { #ifdef CONFIG_XEN sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, diff --git a/unmodified_drivers/linux-2.6/util/Makefile b/unmodified_drivers/linux-2.6/util/Makefile new file mode 100644 index 0000000000..64e7acd194 --- /dev/null +++ b/unmodified_drivers/linux-2.6/util/Makefile @@ -0,0 +1,3 @@ +ifneq ($(KERNELRELEASE),) +include $(src)/Kbuild +endif From 680c789da1c81f3fd29073abc2922feeb3764eb1 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 2 Nov 2006 11:56:26 +0000 Subject: [PATCH 5/6] PV-on-HVM: Conditionally disable checksum offload for receive on some older kernels. On some older kernels the CHECKSUM_UNNECESSARY flag on received skbuffs is not honoured by all subsystems, specifically netfilter under 2.6.9-42.EL To work around this we need to ensure that the correct checksum is calculated at some point. We can cause the backend to do this for us by advertising to the backend that we cannot support checksum offload. The correlation of this issue with the presence of NETIF_F_TSO is not 100% but it is a good first approximation. Signed-off-by: Ian Campbell --- .../drivers/xen/netfront/netfront.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 10f6d47994..e379f5f314 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -101,6 +101,14 @@ static inline void dev_disable_gso_features(struct net_device *dev) } #elif defined(NETIF_F_TSO) #define HAVE_TSO 1 + +/* Some older kernels cannot cope with incorrect checksums, + * particularly in netfilter. I'm not sure there is 100% correlation + * with the presence of NETIF_F_TSO but it appears to be a good first + * approximiation. + */ +#define HAVE_NO_CSUM_OFFLOAD 1 + #define gso_size tso_size #define gso_segs tso_segs static inline void dev_disable_gso_features(struct net_device *dev) @@ -394,6 +402,14 @@ again: goto abort_transaction; } +#ifdef HAVE_NO_CSUM_OFFLOAD + err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload", "%d", 1); + if (err) { + message = "writing feature-no-csum-offload"; + goto abort_transaction; + } +#endif + err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); if (err) { message = "writing feature-sg"; From 16a92870544084629b135e98b356f5ad7d943243 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Thu, 2 Nov 2006 13:20:32 +0000 Subject: [PATCH 6/6] [XEN] Better parameter checking for grant table copy operation. Signed-off-by: Steven Smith --- xen/common/grant_table.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index ff7a54d80f..854e479f00 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -724,10 +724,6 @@ __release_grant_for_copy( { grant_entry_t *const sha = &rd->grant_table->shared[gref]; struct active_grant_entry *const act = &rd->grant_table->active[gref]; - const unsigned long r_frame = act->frame; - - if ( !readonly ) - gnttab_mark_dirty(rd, r_frame); spin_lock(&rd->grant_table->lock); @@ -750,7 +746,8 @@ __release_grant_for_copy( /* Grab a frame number from a grant entry and update the flags and pin count as appropriate. Note that this does *not* update the page - type or reference counts. */ + type or reference counts, and does not check that the mfn is + actually valid. */ static int __acquire_grant_for_copy( struct domain *rd, unsigned long gref, int readonly, @@ -892,6 +889,9 @@ __gnttab_copy( { s_frame = gmfn_to_mfn(sd, op->source.u.gmfn); } + if ( unlikely(!mfn_valid(s_frame)) ) + PIN_FAIL(error_out, GNTST_general_error, + "source frame %lx invalid.\n", s_frame); if ( !get_page(mfn_to_page(s_frame), sd) ) PIN_FAIL(error_out, GNTST_general_error, "could not get source frame %lx.\n", s_frame); @@ -906,8 +906,11 @@ __gnttab_copy( } else { - d_frame = gmfn_to_mfn(sd, op->dest.u.gmfn); + d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn); } + if ( unlikely(!mfn_valid(d_frame)) ) + PIN_FAIL(error_out, GNTST_general_error, + "destination frame %lx invalid.\n", d_frame); if ( !get_page_and_type(mfn_to_page(d_frame), dd, PGT_writable_page) ) PIN_FAIL(error_out, GNTST_general_error, "could not get destination frame %lx.\n", d_frame); @@ -920,6 +923,8 @@ __gnttab_copy( unmap_domain_page(dp); unmap_domain_page(sp); + gnttab_mark_dirty(dd, d_frame); + put_page_and_type(mfn_to_page(d_frame)); error_out: if ( have_s_ref )