ia64/linux-2.6.18-xen.hg

changeset 121:e57b5bec937f

merge with linux-2.6.18-xen.hg
author Alex Williamson <alex.williamson@hp.com>
date Tue Jul 10 08:40:03 2007 -0600 (2007-07-10)
parents 56e84a427523 e9c0b1c11587
children 86ac3059ab67
files arch/ia64/xen/hypervisor.c
line diff
     1.1 --- a/arch/i386/kernel/pci-dma-xen.c	Mon Jul 09 09:24:03 2007 -0600
     1.2 +++ b/arch/i386/kernel/pci-dma-xen.c	Tue Jul 10 08:40:03 2007 -0600
     1.3 @@ -97,6 +97,9 @@ dma_map_sg(struct device *hwdev, struct 
     1.4  			BUG_ON(!sg[i].page);
     1.5  			IOMMU_BUG_ON(address_needs_mapping(
     1.6  				hwdev, sg[i].dma_address));
     1.7 +			IOMMU_BUG_ON(range_straddles_page_boundary(
     1.8 +				page_to_pseudophys(sg[i].page) + sg[i].offset,
     1.9 +				sg[i].length));
    1.10  		}
    1.11  		rc = nents;
    1.12  	}
    1.13 @@ -338,7 +341,7 @@ dma_map_single(struct device *dev, void 
    1.14  	} else {
    1.15  		dma = gnttab_dma_map_page(virt_to_page(ptr)) +
    1.16  		      offset_in_page(ptr);
    1.17 -		IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size));
    1.18 +		IOMMU_BUG_ON(range_straddles_page_boundary(__pa(ptr), size));
    1.19  		IOMMU_BUG_ON(address_needs_mapping(dev, dma));
    1.20  	}
    1.21  
     2.1 --- a/arch/i386/kernel/swiotlb.c	Mon Jul 09 09:24:03 2007 -0600
     2.2 +++ b/arch/i386/kernel/swiotlb.c	Tue Jul 10 08:40:03 2007 -0600
     2.3 @@ -304,6 +304,7 @@ map_single(struct device *hwdev, struct 
     2.4  	unsigned long flags;
     2.5  	char *dma_addr;
     2.6  	unsigned int nslots, stride, index, wrap;
     2.7 +	struct phys_addr slot_buf;
     2.8  	int i;
     2.9  
    2.10  	/*
    2.11 @@ -375,13 +376,29 @@ map_single(struct device *hwdev, struct 
    2.12  	 * This is needed when we sync the memory.  Then we sync the buffer if
    2.13  	 * needed.
    2.14  	 */
    2.15 -	io_tlb_orig_addr[index] = buffer;
    2.16 +	slot_buf = buffer;
    2.17 +	for (i = 0; i < nslots; i++) {
    2.18 +		slot_buf.page += slot_buf.offset >> PAGE_SHIFT;
    2.19 +		slot_buf.offset &= PAGE_SIZE - 1;
    2.20 +		io_tlb_orig_addr[index+i] = slot_buf;
    2.21 +		slot_buf.offset += 1 << IO_TLB_SHIFT;
    2.22 +	}
    2.23  	if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL))
    2.24  		__sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
    2.25  
    2.26  	return dma_addr;
    2.27  }
    2.28  
    2.29 +struct phys_addr dma_addr_to_phys_addr(char *dma_addr)
    2.30 +{
    2.31 +	int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
    2.32 +	struct phys_addr buffer = io_tlb_orig_addr[index];
    2.33 +	buffer.offset += (long)dma_addr & ((1 << IO_TLB_SHIFT) - 1);
    2.34 +	buffer.page += buffer.offset >> PAGE_SHIFT;
    2.35 +	buffer.offset &= PAGE_SIZE - 1;
    2.36 +	return buffer;
    2.37 +}
    2.38 +
    2.39  /*
    2.40   * dma_addr is the kernel virtual address of the bounce buffer to unmap.
    2.41   */
    2.42 @@ -391,7 +408,7 @@ unmap_single(struct device *hwdev, char 
    2.43  	unsigned long flags;
    2.44  	int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
    2.45  	int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
    2.46 -	struct phys_addr buffer = io_tlb_orig_addr[index];
    2.47 +	struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
    2.48  
    2.49  	/*
    2.50  	 * First, sync the memory before unmapping the entry
    2.51 @@ -431,8 +448,7 @@ unmap_single(struct device *hwdev, char 
    2.52  static void
    2.53  sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
    2.54  {
    2.55 -	int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
    2.56 -	struct phys_addr buffer = io_tlb_orig_addr[index];
    2.57 +	struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
    2.58  	BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
    2.59  	__sync_single(buffer, dma_addr, size, dir);
    2.60  }
    2.61 @@ -480,7 +496,7 @@ swiotlb_map_single(struct device *hwdev,
    2.62  	 * we can safely return the device addr and not worry about bounce
    2.63  	 * buffering it.
    2.64  	 */
    2.65 -	if (!range_straddles_page_boundary(ptr, size) &&
    2.66 +	if (!range_straddles_page_boundary(__pa(ptr), size) &&
    2.67  	    !address_needs_mapping(hwdev, dev_addr))
    2.68  		return dev_addr;
    2.69  
    2.70 @@ -577,7 +593,9 @@ swiotlb_map_sg(struct device *hwdev, str
    2.71  	for (i = 0; i < nelems; i++, sg++) {
    2.72  		dev_addr = gnttab_dma_map_page(sg->page) + sg->offset;
    2.73  
    2.74 -		if (address_needs_mapping(hwdev, dev_addr)) {
    2.75 +		if (range_straddles_page_boundary(page_to_pseudophys(sg->page)
    2.76 +						  + sg->offset, sg->length)
    2.77 +		    || address_needs_mapping(hwdev, dev_addr)) {
    2.78  			gnttab_dma_unmap_page(dev_addr);
    2.79  			buffer.page   = sg->page;
    2.80  			buffer.offset = sg->offset;
     3.1 --- a/arch/i386/kernel/time-xen.c	Mon Jul 09 09:24:03 2007 -0600
     3.2 +++ b/arch/i386/kernel/time-xen.c	Tue Jul 10 08:40:03 2007 -0600
     3.3 @@ -130,6 +130,12 @@ static DEFINE_PER_CPU(struct vcpu_runsta
     3.4  /* Must be signed, as it's compared with s64 quantities which can be -ve. */
     3.5  #define NS_PER_TICK (1000000000LL/HZ)
     3.6  
     3.7 +static void __clock_was_set(void *unused)
     3.8 +{
     3.9 +	clock_was_set();
    3.10 +}
    3.11 +static DECLARE_WORK(clock_was_set_work, __clock_was_set, NULL);
    3.12 +
    3.13  static inline void __normalize_time(time_t *sec, s64 *nsec)
    3.14  {
    3.15  	while (*nsec >= NSEC_PER_SEC) {
    3.16 @@ -365,7 +371,6 @@ void do_gettimeofday(struct timeval *tv)
    3.17  {
    3.18  	unsigned long seq;
    3.19  	unsigned long usec, sec;
    3.20 -	unsigned long max_ntp_tick;
    3.21  	unsigned long flags;
    3.22  	s64 nsec;
    3.23  	unsigned int cpu;
    3.24 @@ -677,7 +682,8 @@ irqreturn_t timer_interrupt(int irq, voi
    3.25  
    3.26  	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
    3.27  		update_wallclock();
    3.28 -		clock_was_set();
    3.29 +		if (keventd_up())
    3.30 +			schedule_work(&clock_was_set_work);
    3.31  	}
    3.32  
    3.33  	write_sequnlock(&xtime_lock);
     4.1 --- a/arch/ia64/xen/hypervisor.c	Mon Jul 09 09:24:03 2007 -0600
     4.2 +++ b/arch/ia64/xen/hypervisor.c	Tue Jul 10 08:40:03 2007 -0600
     4.3 @@ -408,6 +408,11 @@ void
     4.4  #include <xen/interface/xen.h>
     4.5  #include <xen/gnttab.h>
     4.6  
     4.7 +void *arch_gnttab_alloc_shared(unsigned long *frames)
     4.8 +{
     4.9 +	return __va(frames[0] << PAGE_SHIFT);
    4.10 +}
    4.11 +
    4.12  static void
    4.13  gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
    4.14  {
     5.1 --- a/arch/powerpc/Kconfig	Mon Jul 09 09:24:03 2007 -0600
     5.2 +++ b/arch/powerpc/Kconfig	Tue Jul 10 08:40:03 2007 -0600
     5.3 @@ -439,6 +439,17 @@ config UDBG_RTAS_CONSOLE
     5.4  	bool
     5.5  	default n
     5.6  
     5.7 +config PPC_XEN
     5.8 +       bool "Enable Xen compatible kernel"
     5.9 +       depends on PPC_MULTIPLATFORM && PPC64 && PPC_MAPLE && PPC_PSERIES && SMP
    5.10 +       select XEN
    5.11 +       select XEN_PRIVILEGED_GUEST
    5.12 +       select XEN_UNPRIVILEGED_GUEST
    5.13 +       select XEN_XENCOMM
    5.14 +       
    5.15 +       help
    5.16 +	  This option will compile a kernel compatible with Xen hypervisor
    5.17 +
    5.18  config XICS
    5.19  	depends on PPC_PSERIES
    5.20  	bool
    5.21 @@ -1071,6 +1082,8 @@ source "arch/powerpc/Kconfig.debug"
    5.22  
    5.23  source "security/Kconfig"
    5.24  
    5.25 +source "drivers/xen/Kconfig"
    5.26 +
    5.27  config KEYS_COMPAT
    5.28  	bool
    5.29  	depends on COMPAT && KEYS
     6.1 --- a/arch/powerpc/Kconfig.debug	Mon Jul 09 09:24:03 2007 -0600
     6.2 +++ b/arch/powerpc/Kconfig.debug	Tue Jul 10 08:40:03 2007 -0600
     6.3 @@ -160,6 +160,20 @@ config PPC_EARLY_DEBUG_ISERIES
     6.4  	  Select this to enable early debugging for legacy iSeries. You need
     6.5  	  to hit "Ctrl-x Ctrl-x" to see the messages on the console.
     6.6  
     6.7 +config PPC_EARLY_DEBUG_XEN_DOM0
     6.8 +	bool "Xen Dom0 Console"
     6.9 +	depends on PPC_XEN
    6.10 +	help
    6.11 +	  Select this to enable early debugging for Xen Dom0. Setting
    6.12 +	  this will result in a kernel that may not work as a DomU.
    6.13 +
    6.14 +config PPC_EARLY_DEBUG_XEN_DOMU
    6.15 +	bool "Xen DomU Console"
    6.16 +	depends on PPC_XEN && XEN_UNPRIVILEGED_GUEST
    6.17 +	help
    6.18 +	  Select this to enable early debugging for Xen DomU. Setting
    6.19 +	  this will result in a kernel that may not work as a Dom0.
    6.20 +
    6.21  endchoice
    6.22  
    6.23  endmenu
     7.1 --- a/arch/powerpc/Makefile	Mon Jul 09 09:24:03 2007 -0600
     7.2 +++ b/arch/powerpc/Makefile	Tue Jul 10 08:40:03 2007 -0600
     7.3 @@ -65,6 +65,7 @@ CPPFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARC
     7.4  AFLAGS-$(CONFIG_PPC32)	:= -Iarch/$(ARCH)
     7.5  CFLAGS-$(CONFIG_PPC64)	:= -mminimal-toc -mtraceback=none  -mcall-aixdesc
     7.6  CFLAGS-$(CONFIG_PPC32)	:= -Iarch/$(ARCH) -ffixed-r2 -mmultiple
     7.7 +CFLAGS-$(CONFIG_PPC_XEN) += -Iinclude/asm-$(ARCH)/xen
     7.8  CPPFLAGS	+= $(CPPFLAGS-y)
     7.9  AFLAGS		+= $(AFLAGS-y)
    7.10  CFLAGS		+= -msoft-float -pipe $(CFLAGS-y)
     8.1 --- a/arch/powerpc/boot/Makefile	Mon Jul 09 09:24:03 2007 -0600
     8.2 +++ b/arch/powerpc/boot/Makefile	Tue Jul 10 08:40:03 2007 -0600
     8.3 @@ -36,8 +36,11 @@ zliblinuxheader := zlib.h zconf.h zutil.
     8.4  $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
     8.5  #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
     8.6  
     8.7 +xen_guest-y = xen_guest.S
     8.8 +
     8.9  src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
    8.10  src-boot += $(zlib)
    8.11 +src-boot += $(xen_guest-$(CONFIG_XEN))
    8.12  src-boot := $(addprefix $(obj)/, $(src-boot))
    8.13  obj-boot := $(addsuffix .o, $(basename $(src-boot)))
    8.14  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/arch/powerpc/boot/xen_guest.S	Tue Jul 10 08:40:03 2007 -0600
     9.3 @@ -0,0 +1,7 @@
     9.4 +	.section __xen_guest
     9.5 +	.ascii	"GUEST_OS=linux"
     9.6 +	.ascii  ",GUEST_VER=xen-3.0"
     9.7 +	.ascii	",XEN_VER=xen-3.0"
     9.8 +	.ascii	",VIRT_BASE=0x0"
     9.9 +	.ascii	",LOADER=generic"
    9.10 +	.byte	0
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/arch/powerpc/configs/xen_maple_defconfig	Tue Jul 10 08:40:03 2007 -0600
    10.3 @@ -0,0 +1,1342 @@
    10.4 +#
    10.5 +# Automatically generated make config: don't edit
    10.6 +# Linux kernel version: 2.6.17
    10.7 +# Mon Jan 15 23:48:47 2007
    10.8 +#
    10.9 +CONFIG_PPC64=y
   10.10 +CONFIG_64BIT=y
   10.11 +CONFIG_PPC_MERGE=y
   10.12 +CONFIG_MMU=y
   10.13 +CONFIG_GENERIC_HARDIRQS=y
   10.14 +CONFIG_IRQ_PER_CPU=y
   10.15 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
   10.16 +CONFIG_GENERIC_HWEIGHT=y
   10.17 +CONFIG_GENERIC_CALIBRATE_DELAY=y
   10.18 +CONFIG_GENERIC_FIND_NEXT_BIT=y
   10.19 +CONFIG_PPC=y
   10.20 +CONFIG_EARLY_PRINTK=y
   10.21 +CONFIG_COMPAT=y
   10.22 +CONFIG_SYSVIPC_COMPAT=y
   10.23 +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
   10.24 +CONFIG_ARCH_MAY_HAVE_PC_FDC=y
   10.25 +CONFIG_PPC_OF=y
   10.26 +CONFIG_PPC_UDBG_16550=y
   10.27 +CONFIG_GENERIC_TBSYNC=y
   10.28 +# CONFIG_DEFAULT_UIMAGE is not set
   10.29 +
   10.30 +#
   10.31 +# Processor support
   10.32 +#
   10.33 +CONFIG_POWER4_ONLY=y
   10.34 +CONFIG_POWER4=y
   10.35 +CONFIG_PPC_FPU=y
   10.36 +CONFIG_ALTIVEC=y
   10.37 +CONFIG_PPC_STD_MMU=y
   10.38 +CONFIG_VIRT_CPU_ACCOUNTING=y
   10.39 +CONFIG_SMP=y
   10.40 +CONFIG_NR_CPUS=32
   10.41 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
   10.42 +
   10.43 +#
   10.44 +# Code maturity level options
   10.45 +#
   10.46 +CONFIG_EXPERIMENTAL=y
   10.47 +CONFIG_LOCK_KERNEL=y
   10.48 +CONFIG_INIT_ENV_ARG_LIMIT=32
   10.49 +
   10.50 +#
   10.51 +# General setup
   10.52 +#
   10.53 +CONFIG_LOCALVERSION="-Xen"
   10.54 +CONFIG_LOCALVERSION_AUTO=y
   10.55 +CONFIG_SWAP=y
   10.56 +CONFIG_SYSVIPC=y
   10.57 +# CONFIG_POSIX_MQUEUE is not set
   10.58 +# CONFIG_BSD_PROCESS_ACCT is not set
   10.59 +CONFIG_SYSCTL=y
   10.60 +# CONFIG_AUDIT is not set
   10.61 +CONFIG_IKCONFIG=y
   10.62 +CONFIG_IKCONFIG_PROC=y
   10.63 +# CONFIG_CPUSETS is not set
   10.64 +# CONFIG_RELAY is not set
   10.65 +CONFIG_INITRAMFS_SOURCE=""
   10.66 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
   10.67 +# CONFIG_EMBEDDED is not set
   10.68 +CONFIG_KALLSYMS=y
   10.69 +# CONFIG_KALLSYMS_ALL is not set
   10.70 +# CONFIG_KALLSYMS_EXTRA_PASS is not set
   10.71 +CONFIG_HOTPLUG=y
   10.72 +CONFIG_PRINTK=y
   10.73 +CONFIG_BUG=y
   10.74 +CONFIG_ELF_CORE=y
   10.75 +CONFIG_BASE_FULL=y
   10.76 +CONFIG_RT_MUTEXES=y
   10.77 +CONFIG_FUTEX=y
   10.78 +CONFIG_EPOLL=y
   10.79 +CONFIG_SHMEM=y
   10.80 +CONFIG_SLAB=y
   10.81 +# CONFIG_TINY_SHMEM is not set
   10.82 +CONFIG_BASE_SMALL=0
   10.83 +# CONFIG_SLOB is not set
   10.84 +
   10.85 +#
   10.86 +# Loadable module support
   10.87 +#
   10.88 +CONFIG_MODULES=y
   10.89 +CONFIG_MODULE_UNLOAD=y
   10.90 +# CONFIG_MODULE_FORCE_UNLOAD is not set
   10.91 +CONFIG_MODVERSIONS=y
   10.92 +CONFIG_MODULE_SRCVERSION_ALL=y
   10.93 +CONFIG_KMOD=y
   10.94 +CONFIG_STOP_MACHINE=y
   10.95 +
   10.96 +#
   10.97 +# Block layer
   10.98 +#
   10.99 +# CONFIG_BLK_DEV_IO_TRACE is not set
  10.100 +
  10.101 +#
  10.102 +# IO Schedulers
  10.103 +#
  10.104 +CONFIG_IOSCHED_NOOP=y
  10.105 +# CONFIG_IOSCHED_AS is not set
  10.106 +CONFIG_IOSCHED_DEADLINE=y
  10.107 +# CONFIG_IOSCHED_CFQ is not set
  10.108 +# CONFIG_DEFAULT_AS is not set
  10.109 +CONFIG_DEFAULT_DEADLINE=y
  10.110 +# CONFIG_DEFAULT_CFQ is not set
  10.111 +# CONFIG_DEFAULT_NOOP is not set
  10.112 +CONFIG_DEFAULT_IOSCHED="deadline"
  10.113 +
  10.114 +#
  10.115 +# Platform support
  10.116 +#
  10.117 +CONFIG_PPC_MULTIPLATFORM=y
  10.118 +# CONFIG_PPC_ISERIES is not set
  10.119 +# CONFIG_EMBEDDED6xx is not set
  10.120 +# CONFIG_APUS is not set
  10.121 +CONFIG_PPC_PSERIES=y
  10.122 +# CONFIG_PPC_PMAC is not set
  10.123 +CONFIG_PPC_MAPLE=y
  10.124 +# CONFIG_PPC_CELL is not set
  10.125 +# CONFIG_PPC_CELL_NATIVE is not set
  10.126 +# CONFIG_PPC_IBM_CELL_BLADE is not set
  10.127 +# CONFIG_UDBG_RTAS_CONSOLE is not set
  10.128 +CONFIG_PPC_XEN=y
  10.129 +CONFIG_XICS=y
  10.130 +CONFIG_U3_DART=y
  10.131 +CONFIG_MPIC=y
  10.132 +CONFIG_PPC_RTAS=y
  10.133 +CONFIG_RTAS_ERROR_LOGGING=y
  10.134 +CONFIG_RTAS_PROC=y
  10.135 +CONFIG_RTAS_FLASH=y
  10.136 +# CONFIG_MMIO_NVRAM is not set
  10.137 +CONFIG_MPIC_BROKEN_U3=y
  10.138 +CONFIG_IBMVIO=y
  10.139 +# CONFIG_IBMEBUS is not set
  10.140 +# CONFIG_PPC_MPC106 is not set
  10.141 +CONFIG_PPC_970_NAP=y
  10.142 +# CONFIG_CPU_FREQ is not set
  10.143 +# CONFIG_WANT_EARLY_SERIAL is not set
  10.144 +
  10.145 +#
  10.146 +# Kernel options
  10.147 +#
  10.148 +CONFIG_HZ_100=y
  10.149 +# CONFIG_HZ_250 is not set
  10.150 +# CONFIG_HZ_1000 is not set
  10.151 +CONFIG_HZ=100
  10.152 +CONFIG_PREEMPT_NONE=y
  10.153 +# CONFIG_PREEMPT_VOLUNTARY is not set
  10.154 +# CONFIG_PREEMPT is not set
  10.155 +# CONFIG_PREEMPT_BKL is not set
  10.156 +CONFIG_BINFMT_ELF=y
  10.157 +# CONFIG_BINFMT_MISC is not set
  10.158 +CONFIG_FORCE_MAX_ZONEORDER=13
  10.159 +CONFIG_IOMMU_VMERGE=y
  10.160 +# CONFIG_HOTPLUG_CPU is not set
  10.161 +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
  10.162 +# CONFIG_KEXEC is not set
  10.163 +# CONFIG_CRASH_DUMP is not set
  10.164 +CONFIG_IRQ_ALL_CPUS=y
  10.165 +# CONFIG_PPC_SPLPAR is not set
  10.166 +CONFIG_EEH=y
  10.167 +CONFIG_SCANLOG=y
  10.168 +CONFIG_LPARCFG=y
  10.169 +CONFIG_NUMA=y
  10.170 +CONFIG_NODES_SHIFT=4
  10.171 +CONFIG_ARCH_SELECT_MEMORY_MODEL=y
  10.172 +CONFIG_ARCH_SPARSEMEM_ENABLE=y
  10.173 +CONFIG_ARCH_SPARSEMEM_DEFAULT=y
  10.174 +CONFIG_SELECT_MEMORY_MODEL=y
  10.175 +# CONFIG_FLATMEM_MANUAL is not set
  10.176 +# CONFIG_DISCONTIGMEM_MANUAL is not set
  10.177 +CONFIG_SPARSEMEM_MANUAL=y
  10.178 +CONFIG_SPARSEMEM=y
  10.179 +CONFIG_NEED_MULTIPLE_NODES=y
  10.180 +CONFIG_HAVE_MEMORY_PRESENT=y
  10.181 +# CONFIG_SPARSEMEM_STATIC is not set
  10.182 +CONFIG_SPARSEMEM_EXTREME=y
  10.183 +CONFIG_MEMORY_HOTPLUG=y
  10.184 +CONFIG_SPLIT_PTLOCK_CPUS=4
  10.185 +CONFIG_MIGRATION=y
  10.186 +CONFIG_RESOURCES_64BIT=y
  10.187 +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
  10.188 +CONFIG_ARCH_MEMORY_PROBE=y
  10.189 +# CONFIG_PPC_64K_PAGES is not set
  10.190 +# CONFIG_SCHED_SMT is not set
  10.191 +CONFIG_PROC_DEVICETREE=y
  10.192 +# CONFIG_CMDLINE_BOOL is not set
  10.193 +# CONFIG_PM is not set
  10.194 +CONFIG_SECCOMP=y
  10.195 +CONFIG_ISA_DMA_API=y
  10.196 +
  10.197 +#
  10.198 +# Bus options
  10.199 +#
  10.200 +CONFIG_GENERIC_ISA_DMA=y
  10.201 +CONFIG_PPC_I8259=y
  10.202 +# CONFIG_PPC_INDIRECT_PCI is not set
  10.203 +CONFIG_PCI=y
  10.204 +CONFIG_PCI_DOMAINS=y
  10.205 +# CONFIG_PCIEPORTBUS is not set
  10.206 +# CONFIG_PCI_DEBUG is not set
  10.207 +
  10.208 +#
  10.209 +# PCCARD (PCMCIA/CardBus) support
  10.210 +#
  10.211 +# CONFIG_PCCARD is not set
  10.212 +
  10.213 +#
  10.214 +# PCI Hotplug Support
  10.215 +#
  10.216 +# CONFIG_HOTPLUG_PCI is not set
  10.217 +CONFIG_KERNEL_START=0xc000000000000000
  10.218 +
  10.219 +#
  10.220 +# Networking
  10.221 +#
  10.222 +CONFIG_NET=y
  10.223 +
  10.224 +#
  10.225 +# Networking options
  10.226 +#
  10.227 +# CONFIG_NETDEBUG is not set
  10.228 +CONFIG_PACKET=y
  10.229 +CONFIG_PACKET_MMAP=y
  10.230 +CONFIG_UNIX=y
  10.231 +CONFIG_XFRM=y
  10.232 +# CONFIG_XFRM_USER is not set
  10.233 +# CONFIG_NET_KEY is not set
  10.234 +CONFIG_INET=y
  10.235 +CONFIG_IP_MULTICAST=y
  10.236 +CONFIG_IP_ADVANCED_ROUTER=y
  10.237 +CONFIG_ASK_IP_FIB_HASH=y
  10.238 +# CONFIG_IP_FIB_TRIE is not set
  10.239 +CONFIG_IP_FIB_HASH=y
  10.240 +CONFIG_IP_MULTIPLE_TABLES=y
  10.241 +CONFIG_IP_ROUTE_FWMARK=y
  10.242 +CONFIG_IP_ROUTE_MULTIPATH=y
  10.243 +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
  10.244 +# CONFIG_IP_ROUTE_VERBOSE is not set
  10.245 +CONFIG_IP_PNP=y
  10.246 +CONFIG_IP_PNP_DHCP=y
  10.247 +CONFIG_IP_PNP_BOOTP=y
  10.248 +CONFIG_IP_PNP_RARP=y
  10.249 +CONFIG_NET_IPIP=y
  10.250 +# CONFIG_NET_IPGRE is not set
  10.251 +CONFIG_IP_MROUTE=y
  10.252 +CONFIG_IP_PIMSM_V1=y
  10.253 +CONFIG_IP_PIMSM_V2=y
  10.254 +# CONFIG_ARPD is not set
  10.255 +CONFIG_SYN_COOKIES=y
  10.256 +# CONFIG_INET_AH is not set
  10.257 +# CONFIG_INET_ESP is not set
  10.258 +# CONFIG_INET_IPCOMP is not set
  10.259 +# CONFIG_INET_XFRM_TUNNEL is not set
  10.260 +CONFIG_INET_TUNNEL=y
  10.261 +CONFIG_INET_XFRM_MODE_TRANSPORT=y
  10.262 +CONFIG_INET_XFRM_MODE_TUNNEL=y
  10.263 +CONFIG_INET_DIAG=y
  10.264 +CONFIG_INET_TCP_DIAG=y
  10.265 +# CONFIG_TCP_CONG_ADVANCED is not set
  10.266 +CONFIG_TCP_CONG_BIC=y
  10.267 +
  10.268 +#
  10.269 +# IP: Virtual Server Configuration
  10.270 +#
  10.271 +# CONFIG_IP_VS is not set
  10.272 +CONFIG_IPV6=y
  10.273 +CONFIG_IPV6_PRIVACY=y
  10.274 +CONFIG_IPV6_ROUTER_PREF=y
  10.275 +CONFIG_IPV6_ROUTE_INFO=y
  10.276 +CONFIG_INET6_AH=y
  10.277 +CONFIG_INET6_ESP=y
  10.278 +CONFIG_INET6_IPCOMP=y
  10.279 +CONFIG_INET6_XFRM_TUNNEL=y
  10.280 +CONFIG_INET6_TUNNEL=y
  10.281 +CONFIG_INET6_XFRM_MODE_TRANSPORT=y
  10.282 +CONFIG_INET6_XFRM_MODE_TUNNEL=y
  10.283 +CONFIG_IPV6_TUNNEL=y
  10.284 +# CONFIG_NETWORK_SECMARK is not set
  10.285 +CONFIG_NETFILTER=y
  10.286 +# CONFIG_NETFILTER_DEBUG is not set
  10.287 +CONFIG_BRIDGE_NETFILTER=y
  10.288 +
  10.289 +#
  10.290 +# Core Netfilter Configuration
  10.291 +#
  10.292 +CONFIG_NETFILTER_NETLINK=y
  10.293 +CONFIG_NETFILTER_NETLINK_QUEUE=y
  10.294 +CONFIG_NETFILTER_NETLINK_LOG=y
  10.295 +CONFIG_NETFILTER_XTABLES=y
  10.296 +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
  10.297 +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
  10.298 +CONFIG_NETFILTER_XT_TARGET_MARK=y
  10.299 +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
  10.300 +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
  10.301 +CONFIG_NETFILTER_XT_MATCH_COMMENT=y
  10.302 +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
  10.303 +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
  10.304 +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
  10.305 +CONFIG_NETFILTER_XT_MATCH_DCCP=y
  10.306 +CONFIG_NETFILTER_XT_MATCH_ESP=y
  10.307 +CONFIG_NETFILTER_XT_MATCH_HELPER=y
  10.308 +CONFIG_NETFILTER_XT_MATCH_LENGTH=y
  10.309 +CONFIG_NETFILTER_XT_MATCH_LIMIT=y
  10.310 +CONFIG_NETFILTER_XT_MATCH_MAC=y
  10.311 +CONFIG_NETFILTER_XT_MATCH_MARK=y
  10.312 +CONFIG_NETFILTER_XT_MATCH_POLICY=y
  10.313 +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
  10.314 +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
  10.315 +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
  10.316 +CONFIG_NETFILTER_XT_MATCH_QUOTA=y
  10.317 +CONFIG_NETFILTER_XT_MATCH_REALM=y
  10.318 +CONFIG_NETFILTER_XT_MATCH_SCTP=y
  10.319 +CONFIG_NETFILTER_XT_MATCH_STATE=y
  10.320 +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
  10.321 +CONFIG_NETFILTER_XT_MATCH_STRING=y
  10.322 +CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
  10.323 +
  10.324 +#
  10.325 +# IP: Netfilter Configuration
  10.326 +#
  10.327 +CONFIG_IP_NF_CONNTRACK=y
  10.328 +CONFIG_IP_NF_CT_ACCT=y
  10.329 +CONFIG_IP_NF_CONNTRACK_MARK=y
  10.330 +CONFIG_IP_NF_CONNTRACK_EVENTS=y
  10.331 +CONFIG_IP_NF_CONNTRACK_NETLINK=y
  10.332 +CONFIG_IP_NF_CT_PROTO_SCTP=y
  10.333 +CONFIG_IP_NF_FTP=y
  10.334 +CONFIG_IP_NF_IRC=y
  10.335 +# CONFIG_IP_NF_NETBIOS_NS is not set
  10.336 +CONFIG_IP_NF_TFTP=y
  10.337 +CONFIG_IP_NF_AMANDA=y
  10.338 +CONFIG_IP_NF_PPTP=y
  10.339 +# CONFIG_IP_NF_H323 is not set
  10.340 +# CONFIG_IP_NF_SIP is not set
  10.341 +# CONFIG_IP_NF_QUEUE is not set
  10.342 +CONFIG_IP_NF_IPTABLES=y
  10.343 +CONFIG_IP_NF_MATCH_IPRANGE=y
  10.344 +CONFIG_IP_NF_MATCH_TOS=y
  10.345 +CONFIG_IP_NF_MATCH_RECENT=y
  10.346 +CONFIG_IP_NF_MATCH_ECN=y
  10.347 +CONFIG_IP_NF_MATCH_DSCP=y
  10.348 +CONFIG_IP_NF_MATCH_AH=y
  10.349 +CONFIG_IP_NF_MATCH_TTL=y
  10.350 +CONFIG_IP_NF_MATCH_OWNER=y
  10.351 +CONFIG_IP_NF_MATCH_ADDRTYPE=y
  10.352 +CONFIG_IP_NF_MATCH_HASHLIMIT=y
  10.353 +CONFIG_IP_NF_FILTER=y
  10.354 +CONFIG_IP_NF_TARGET_REJECT=y
  10.355 +CONFIG_IP_NF_TARGET_LOG=y
  10.356 +CONFIG_IP_NF_TARGET_ULOG=y
  10.357 +CONFIG_IP_NF_TARGET_TCPMSS=y
  10.358 +CONFIG_IP_NF_NAT=y
  10.359 +CONFIG_IP_NF_NAT_NEEDED=y
  10.360 +CONFIG_IP_NF_TARGET_MASQUERADE=y
  10.361 +CONFIG_IP_NF_TARGET_REDIRECT=y
  10.362 +CONFIG_IP_NF_TARGET_NETMAP=y
  10.363 +CONFIG_IP_NF_TARGET_SAME=y
  10.364 +CONFIG_IP_NF_NAT_SNMP_BASIC=y
  10.365 +CONFIG_IP_NF_NAT_IRC=y
  10.366 +CONFIG_IP_NF_NAT_FTP=y
  10.367 +CONFIG_IP_NF_NAT_TFTP=y
  10.368 +CONFIG_IP_NF_NAT_AMANDA=y
  10.369 +CONFIG_IP_NF_NAT_PPTP=y
  10.370 +CONFIG_IP_NF_MANGLE=y
  10.371 +CONFIG_IP_NF_TARGET_TOS=y
  10.372 +CONFIG_IP_NF_TARGET_ECN=y
  10.373 +CONFIG_IP_NF_TARGET_DSCP=y
  10.374 +CONFIG_IP_NF_TARGET_TTL=y
  10.375 +CONFIG_IP_NF_TARGET_CLUSTERIP=y
  10.376 +CONFIG_IP_NF_RAW=y
  10.377 +CONFIG_IP_NF_ARPTABLES=y
  10.378 +CONFIG_IP_NF_ARPFILTER=y
  10.379 +CONFIG_IP_NF_ARP_MANGLE=y
  10.380 +
  10.381 +#
  10.382 +# IPv6: Netfilter Configuration (EXPERIMENTAL)
  10.383 +#
  10.384 +# CONFIG_IP6_NF_QUEUE is not set
  10.385 +CONFIG_IP6_NF_IPTABLES=y
  10.386 +CONFIG_IP6_NF_MATCH_RT=y
  10.387 +CONFIG_IP6_NF_MATCH_OPTS=y
  10.388 +CONFIG_IP6_NF_MATCH_FRAG=y
  10.389 +CONFIG_IP6_NF_MATCH_HL=y
  10.390 +CONFIG_IP6_NF_MATCH_OWNER=y
  10.391 +CONFIG_IP6_NF_MATCH_IPV6HEADER=y
  10.392 +CONFIG_IP6_NF_MATCH_AH=y
  10.393 +CONFIG_IP6_NF_MATCH_EUI64=y
  10.394 +CONFIG_IP6_NF_FILTER=y
  10.395 +CONFIG_IP6_NF_TARGET_LOG=y
  10.396 +CONFIG_IP6_NF_TARGET_REJECT=y
  10.397 +CONFIG_IP6_NF_MANGLE=y
  10.398 +CONFIG_IP6_NF_TARGET_HL=y
  10.399 +CONFIG_IP6_NF_RAW=y
  10.400 +
  10.401 +#
  10.402 +# Bridge: Netfilter Configuration
  10.403 +#
  10.404 +CONFIG_BRIDGE_NF_EBTABLES=y
  10.405 +CONFIG_BRIDGE_EBT_BROUTE=y
  10.406 +CONFIG_BRIDGE_EBT_T_FILTER=y
  10.407 +CONFIG_BRIDGE_EBT_T_NAT=y
  10.408 +CONFIG_BRIDGE_EBT_802_3=y
  10.409 +CONFIG_BRIDGE_EBT_AMONG=y
  10.410 +CONFIG_BRIDGE_EBT_ARP=y
  10.411 +CONFIG_BRIDGE_EBT_IP=y
  10.412 +CONFIG_BRIDGE_EBT_LIMIT=y
  10.413 +CONFIG_BRIDGE_EBT_MARK=y
  10.414 +CONFIG_BRIDGE_EBT_PKTTYPE=y
  10.415 +CONFIG_BRIDGE_EBT_STP=y
  10.416 +CONFIG_BRIDGE_EBT_VLAN=y
  10.417 +CONFIG_BRIDGE_EBT_ARPREPLY=y
  10.418 +CONFIG_BRIDGE_EBT_DNAT=y
  10.419 +CONFIG_BRIDGE_EBT_MARK_T=y
  10.420 +CONFIG_BRIDGE_EBT_REDIRECT=y
  10.421 +CONFIG_BRIDGE_EBT_SNAT=y
  10.422 +CONFIG_BRIDGE_EBT_LOG=y
  10.423 +CONFIG_BRIDGE_EBT_ULOG=y
  10.424 +
  10.425 +#
  10.426 +# DCCP Configuration (EXPERIMENTAL)
  10.427 +#
  10.428 +# CONFIG_IP_DCCP is not set
  10.429 +
  10.430 +#
  10.431 +# SCTP Configuration (EXPERIMENTAL)
  10.432 +#
  10.433 +# CONFIG_IP_SCTP is not set
  10.434 +
  10.435 +#
  10.436 +# TIPC Configuration (EXPERIMENTAL)
  10.437 +#
  10.438 +# CONFIG_TIPC is not set
  10.439 +# CONFIG_ATM is not set
  10.440 +CONFIG_BRIDGE=y
  10.441 +CONFIG_VLAN_8021Q=y
  10.442 +# CONFIG_DECNET is not set
  10.443 +CONFIG_LLC=y
  10.444 +# CONFIG_LLC2 is not set
  10.445 +# CONFIG_IPX is not set
  10.446 +# CONFIG_ATALK is not set
  10.447 +# CONFIG_X25 is not set
  10.448 +# CONFIG_LAPB is not set
  10.449 +# CONFIG_NET_DIVERT is not set
  10.450 +# CONFIG_ECONET is not set
  10.451 +# CONFIG_WAN_ROUTER is not set
  10.452 +
  10.453 +#
  10.454 +# QoS and/or fair queueing
  10.455 +#
  10.456 +# CONFIG_NET_SCHED is not set
  10.457 +CONFIG_NET_CLS_ROUTE=y
  10.458 +
  10.459 +#
  10.460 +# Network testing
  10.461 +#
  10.462 +# CONFIG_NET_PKTGEN is not set
  10.463 +# CONFIG_HAMRADIO is not set
  10.464 +# CONFIG_IRDA is not set
  10.465 +# CONFIG_BT is not set
  10.466 +# CONFIG_IEEE80211 is not set
  10.467 +
  10.468 +#
  10.469 +# Device Drivers
  10.470 +#
  10.471 +
  10.472 +#
  10.473 +# Generic Driver Options
  10.474 +#
  10.475 +CONFIG_STANDALONE=y
  10.476 +CONFIG_PREVENT_FIRMWARE_BUILD=y
  10.477 +CONFIG_FW_LOADER=y
  10.478 +# CONFIG_DEBUG_DRIVER is not set
  10.479 +# CONFIG_SYS_HYPERVISOR is not set
  10.480 +
  10.481 +#
  10.482 +# Connector - unified userspace <-> kernelspace linker
  10.483 +#
  10.484 +# CONFIG_CONNECTOR is not set
  10.485 +
  10.486 +#
  10.487 +# Memory Technology Devices (MTD)
  10.488 +#
  10.489 +# CONFIG_MTD is not set
  10.490 +
  10.491 +#
  10.492 +# Parallel port support
  10.493 +#
  10.494 +# CONFIG_PARPORT is not set
  10.495 +
  10.496 +#
  10.497 +# Plug and Play support
  10.498 +#
  10.499 +
  10.500 +#
  10.501 +# Block devices
  10.502 +#
  10.503 +# CONFIG_BLK_DEV_FD is not set
  10.504 +# CONFIG_BLK_CPQ_DA is not set
  10.505 +# CONFIG_BLK_CPQ_CISS_DA is not set
  10.506 +# CONFIG_BLK_DEV_DAC960 is not set
  10.507 +# CONFIG_BLK_DEV_UMEM is not set
  10.508 +# CONFIG_BLK_DEV_COW_COMMON is not set
  10.509 +CONFIG_BLK_DEV_LOOP=y
  10.510 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  10.511 +# CONFIG_BLK_DEV_NBD is not set
  10.512 +# CONFIG_BLK_DEV_SX8 is not set
  10.513 +CONFIG_BLK_DEV_RAM=y
  10.514 +CONFIG_BLK_DEV_RAM_COUNT=16
  10.515 +CONFIG_BLK_DEV_RAM_SIZE=10240
  10.516 +CONFIG_BLK_DEV_INITRD=y
  10.517 +# CONFIG_CDROM_PKTCDVD is not set
  10.518 +# CONFIG_ATA_OVER_ETH is not set
  10.519 +
  10.520 +#
  10.521 +# ATA/ATAPI/MFM/RLL support
  10.522 +#
  10.523 +CONFIG_IDE=y
  10.524 +CONFIG_BLK_DEV_IDE=y
  10.525 +
  10.526 +#
  10.527 +# Please see Documentation/ide.txt for help/info on IDE drives
  10.528 +#
  10.529 +# CONFIG_BLK_DEV_IDE_SATA is not set
  10.530 +CONFIG_BLK_DEV_IDEDISK=y
  10.531 +# CONFIG_IDEDISK_MULTI_MODE is not set
  10.532 +CONFIG_BLK_DEV_IDECD=y
  10.533 +# CONFIG_BLK_DEV_IDETAPE is not set
  10.534 +# CONFIG_BLK_DEV_IDEFLOPPY is not set
  10.535 +# CONFIG_BLK_DEV_IDESCSI is not set
  10.536 +CONFIG_IDE_TASK_IOCTL=y
  10.537 +
  10.538 +#
  10.539 +# IDE chipset support/bugfixes
  10.540 +#
  10.541 +CONFIG_IDE_GENERIC=y
  10.542 +CONFIG_BLK_DEV_IDEPCI=y
  10.543 +CONFIG_IDEPCI_SHARE_IRQ=y
  10.544 +# CONFIG_BLK_DEV_OFFBOARD is not set
  10.545 +CONFIG_BLK_DEV_GENERIC=y
  10.546 +# CONFIG_BLK_DEV_OPTI621 is not set
  10.547 +# CONFIG_BLK_DEV_SL82C105 is not set
  10.548 +CONFIG_BLK_DEV_IDEDMA_PCI=y
  10.549 +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
  10.550 +CONFIG_IDEDMA_PCI_AUTO=y
  10.551 +# CONFIG_IDEDMA_ONLYDISK is not set
  10.552 +# CONFIG_BLK_DEV_AEC62XX is not set
  10.553 +# CONFIG_BLK_DEV_ALI15X3 is not set
  10.554 +CONFIG_BLK_DEV_AMD74XX=y
  10.555 +# CONFIG_BLK_DEV_CMD64X is not set
  10.556 +# CONFIG_BLK_DEV_TRIFLEX is not set
  10.557 +# CONFIG_BLK_DEV_CY82C693 is not set
  10.558 +# CONFIG_BLK_DEV_CS5520 is not set
  10.559 +# CONFIG_BLK_DEV_CS5530 is not set
  10.560 +# CONFIG_BLK_DEV_HPT34X is not set
  10.561 +# CONFIG_BLK_DEV_HPT366 is not set
  10.562 +# CONFIG_BLK_DEV_SC1200 is not set
  10.563 +# CONFIG_BLK_DEV_PIIX is not set
  10.564 +# CONFIG_BLK_DEV_IT821X is not set
  10.565 +# CONFIG_BLK_DEV_NS87415 is not set
  10.566 +# CONFIG_BLK_DEV_PDC202XX_OLD is not set
  10.567 +# CONFIG_BLK_DEV_PDC202XX_NEW is not set
  10.568 +# CONFIG_BLK_DEV_SVWKS is not set
  10.569 +# CONFIG_BLK_DEV_SIIMAGE is not set
  10.570 +# CONFIG_BLK_DEV_SLC90E66 is not set
  10.571 +# CONFIG_BLK_DEV_TRM290 is not set
  10.572 +# CONFIG_BLK_DEV_VIA82CXXX is not set
  10.573 +# CONFIG_IDE_ARM is not set
  10.574 +CONFIG_BLK_DEV_IDEDMA=y
  10.575 +# CONFIG_IDEDMA_IVB is not set
  10.576 +CONFIG_IDEDMA_AUTO=y
  10.577 +# CONFIG_BLK_DEV_HD is not set
  10.578 +
  10.579 +#
  10.580 +# SCSI device support
  10.581 +#
  10.582 +# CONFIG_RAID_ATTRS is not set
  10.583 +CONFIG_SCSI=y
  10.584 +# CONFIG_SCSI_PROC_FS is not set
  10.585 +
  10.586 +#
  10.587 +# SCSI support type (disk, tape, CD-ROM)
  10.588 +#
  10.589 +CONFIG_BLK_DEV_SD=y
  10.590 +# CONFIG_CHR_DEV_ST is not set
  10.591 +# CONFIG_CHR_DEV_OSST is not set
  10.592 +CONFIG_BLK_DEV_SR=y
  10.593 +# CONFIG_BLK_DEV_SR_VENDOR is not set
  10.594 +CONFIG_CHR_DEV_SG=y
  10.595 +# CONFIG_CHR_DEV_SCH is not set
  10.596 +
  10.597 +#
  10.598 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
  10.599 +#
  10.600 +# CONFIG_SCSI_MULTI_LUN is not set
  10.601 +# CONFIG_SCSI_CONSTANTS is not set
  10.602 +# CONFIG_SCSI_LOGGING is not set
  10.603 +
  10.604 +#
  10.605 +# SCSI Transport Attributes
  10.606 +#
  10.607 +CONFIG_SCSI_SPI_ATTRS=y
  10.608 +CONFIG_SCSI_FC_ATTRS=y
  10.609 +CONFIG_SCSI_ISCSI_ATTRS=y
  10.610 +CONFIG_SCSI_SAS_ATTRS=y
  10.611 +
  10.612 +#
  10.613 +# SCSI low-level drivers
  10.614 +#
  10.615 +# CONFIG_ISCSI_TCP is not set
  10.616 +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
  10.617 +# CONFIG_SCSI_3W_9XXX is not set
  10.618 +# CONFIG_SCSI_ACARD is not set
  10.619 +# CONFIG_SCSI_AACRAID is not set
  10.620 +# CONFIG_SCSI_AIC7XXX is not set
  10.621 +# CONFIG_SCSI_AIC7XXX_OLD is not set
  10.622 +# CONFIG_SCSI_AIC79XX is not set
  10.623 +# CONFIG_MEGARAID_NEWGEN is not set
  10.624 +# CONFIG_MEGARAID_LEGACY is not set
  10.625 +# CONFIG_MEGARAID_SAS is not set
  10.626 +# CONFIG_SCSI_SATA is not set
  10.627 +# CONFIG_SCSI_HPTIOP is not set
  10.628 +# CONFIG_SCSI_BUSLOGIC is not set
  10.629 +# CONFIG_SCSI_DMX3191D is not set
  10.630 +# CONFIG_SCSI_EATA is not set
  10.631 +# CONFIG_SCSI_FUTURE_DOMAIN is not set
  10.632 +# CONFIG_SCSI_GDTH is not set
  10.633 +# CONFIG_SCSI_IPS is not set
  10.634 +# CONFIG_SCSI_IBMVSCSI is not set
  10.635 +# CONFIG_SCSI_INITIO is not set
  10.636 +# CONFIG_SCSI_INIA100 is not set
  10.637 +# CONFIG_SCSI_SYM53C8XX_2 is not set
  10.638 +CONFIG_SCSI_IPR=y
  10.639 +# CONFIG_SCSI_IPR_TRACE is not set
  10.640 +# CONFIG_SCSI_IPR_DUMP is not set
  10.641 +# CONFIG_SCSI_QLOGIC_1280 is not set
  10.642 +# CONFIG_SCSI_QLA_FC is not set
  10.643 +# CONFIG_SCSI_LPFC is not set
  10.644 +# CONFIG_SCSI_DC395x is not set
  10.645 +# CONFIG_SCSI_DC390T is not set
  10.646 +# CONFIG_SCSI_DEBUG is not set
  10.647 +
  10.648 +#
  10.649 +# Multi-device support (RAID and LVM)
  10.650 +#
  10.651 +# CONFIG_MD is not set
  10.652 +
  10.653 +#
  10.654 +# Fusion MPT device support
  10.655 +#
  10.656 +# CONFIG_FUSION is not set
  10.657 +# CONFIG_FUSION_SPI is not set
  10.658 +# CONFIG_FUSION_FC is not set
  10.659 +# CONFIG_FUSION_SAS is not set
  10.660 +
  10.661 +#
  10.662 +# IEEE 1394 (FireWire) support
  10.663 +#
  10.664 +# CONFIG_IEEE1394 is not set
  10.665 +
  10.666 +#
  10.667 +# I2O device support
  10.668 +#
  10.669 +# CONFIG_I2O is not set
  10.670 +
  10.671 +#
  10.672 +# Macintosh device drivers
  10.673 +#
  10.674 +# CONFIG_WINDFARM is not set
  10.675 +
  10.676 +#
  10.677 +# Network device support
  10.678 +#
  10.679 +CONFIG_NETDEVICES=y
  10.680 +# CONFIG_DUMMY is not set
  10.681 +# CONFIG_BONDING is not set
  10.682 +# CONFIG_EQUALIZER is not set
  10.683 +# CONFIG_TUN is not set
  10.684 +
  10.685 +#
  10.686 +# ARCnet devices
  10.687 +#
  10.688 +# CONFIG_ARCNET is not set
  10.689 +
  10.690 +#
  10.691 +# PHY device support
  10.692 +#
  10.693 +# CONFIG_PHYLIB is not set
  10.694 +
  10.695 +#
  10.696 +# Ethernet (10 or 100Mbit)
  10.697 +#
  10.698 +CONFIG_NET_ETHERNET=y
  10.699 +CONFIG_MII=y
  10.700 +# CONFIG_HAPPYMEAL is not set
  10.701 +# CONFIG_SUNGEM is not set
  10.702 +# CONFIG_CASSINI is not set
  10.703 +# CONFIG_NET_VENDOR_3COM is not set
  10.704 +
  10.705 +#
  10.706 +# Tulip family network device support
  10.707 +#
  10.708 +# CONFIG_NET_TULIP is not set
  10.709 +# CONFIG_HP100 is not set
  10.710 +CONFIG_IBMVETH=y
  10.711 +CONFIG_NET_PCI=y
  10.712 +# CONFIG_PCNET32 is not set
  10.713 +CONFIG_AMD8111_ETH=y
  10.714 +# CONFIG_AMD8111E_NAPI is not set
  10.715 +# CONFIG_ADAPTEC_STARFIRE is not set
  10.716 +# CONFIG_B44 is not set
  10.717 +# CONFIG_FORCEDETH is not set
  10.718 +# CONFIG_DGRS is not set
  10.719 +# CONFIG_EEPRO100 is not set
  10.720 +# CONFIG_E100 is not set
  10.721 +# CONFIG_FEALNX is not set
  10.722 +# CONFIG_NATSEMI is not set
  10.723 +# CONFIG_NE2K_PCI is not set
  10.724 +# CONFIG_8139CP is not set
  10.725 +# CONFIG_8139TOO is not set
  10.726 +# CONFIG_SIS900 is not set
  10.727 +# CONFIG_EPIC100 is not set
  10.728 +# CONFIG_SUNDANCE is not set
  10.729 +# CONFIG_VIA_RHINE is not set
  10.730 +
  10.731 +#
  10.732 +# Ethernet (1000 Mbit)
  10.733 +#
  10.734 +# CONFIG_ACENIC is not set
  10.735 +# CONFIG_DL2K is not set
  10.736 +CONFIG_E1000=y
  10.737 +# CONFIG_E1000_NAPI is not set
  10.738 +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
  10.739 +# CONFIG_NS83820 is not set
  10.740 +# CONFIG_HAMACHI is not set
  10.741 +# CONFIG_YELLOWFIN is not set
  10.742 +# CONFIG_R8169 is not set
  10.743 +# CONFIG_SIS190 is not set
  10.744 +# CONFIG_SKGE is not set
  10.745 +CONFIG_SKY2=y
  10.746 +CONFIG_SK98LIN=y
  10.747 +# CONFIG_VIA_VELOCITY is not set
  10.748 +CONFIG_TIGON3=y
  10.749 +CONFIG_BNX2=y
  10.750 +# CONFIG_MV643XX_ETH is not set
  10.751 +
  10.752 +#
  10.753 +# Ethernet (10000 Mbit)
  10.754 +#
  10.755 +# CONFIG_CHELSIO_T1 is not set
  10.756 +# CONFIG_IXGB is not set
  10.757 +# CONFIG_S2IO is not set
  10.758 +# CONFIG_MYRI10GE is not set
  10.759 +
  10.760 +#
  10.761 +# Token Ring devices
  10.762 +#
  10.763 +# CONFIG_TR is not set
  10.764 +
  10.765 +#
  10.766 +# Wireless LAN (non-hamradio)
  10.767 +#
  10.768 +# CONFIG_NET_RADIO is not set
  10.769 +
  10.770 +#
  10.771 +# Wan interfaces
  10.772 +#
  10.773 +# CONFIG_WAN is not set
  10.774 +# CONFIG_FDDI is not set
  10.775 +# CONFIG_HIPPI is not set
  10.776 +# CONFIG_PPP is not set
  10.777 +# CONFIG_SLIP is not set
  10.778 +# CONFIG_NET_FC is not set
  10.779 +# CONFIG_SHAPER is not set
  10.780 +# CONFIG_NETCONSOLE is not set
  10.781 +# CONFIG_NETPOLL is not set
  10.782 +# CONFIG_NET_POLL_CONTROLLER is not set
  10.783 +
  10.784 +#
  10.785 +# ISDN subsystem
  10.786 +#
  10.787 +# CONFIG_ISDN is not set
  10.788 +
  10.789 +#
  10.790 +# Telephony Support
  10.791 +#
  10.792 +# CONFIG_PHONE is not set
  10.793 +
  10.794 +#
  10.795 +# Input device support
  10.796 +#
  10.797 +CONFIG_INPUT=y
  10.798 +
  10.799 +#
  10.800 +# Userland interfaces
  10.801 +#
  10.802 +CONFIG_INPUT_MOUSEDEV=y
  10.803 +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  10.804 +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600
  10.805 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
  10.806 +# CONFIG_INPUT_JOYDEV is not set
  10.807 +# CONFIG_INPUT_TSDEV is not set
  10.808 +# CONFIG_INPUT_EVDEV is not set
  10.809 +# CONFIG_INPUT_EVBUG is not set
  10.810 +
  10.811 +#
  10.812 +# Input Device Drivers
  10.813 +#
  10.814 +# CONFIG_INPUT_KEYBOARD is not set
  10.815 +# CONFIG_INPUT_MOUSE is not set
  10.816 +# CONFIG_INPUT_JOYSTICK is not set
  10.817 +# CONFIG_INPUT_TOUCHSCREEN is not set
  10.818 +# CONFIG_INPUT_MISC is not set
  10.819 +
  10.820 +#
  10.821 +# Hardware I/O ports
  10.822 +#
  10.823 +# CONFIG_SERIO is not set
  10.824 +# CONFIG_GAMEPORT is not set
  10.825 +
  10.826 +#
  10.827 +# Character devices
  10.828 +#
  10.829 +CONFIG_VT=y
  10.830 +CONFIG_VT_CONSOLE=y
  10.831 +CONFIG_HW_CONSOLE=y
  10.832 +# CONFIG_VT_HW_CONSOLE_BINDING is not set
  10.833 +# CONFIG_SERIAL_NONSTANDARD is not set
  10.834 +
  10.835 +#
  10.836 +# Serial drivers
  10.837 +#
  10.838 +
  10.839 +#
  10.840 +# Non-8250 serial port support
  10.841 +#
  10.842 +# CONFIG_SERIAL_ICOM is not set
  10.843 +# CONFIG_SERIAL_JSM is not set
  10.844 +CONFIG_UNIX98_PTYS=y
  10.845 +CONFIG_LEGACY_PTYS=y
  10.846 +CONFIG_LEGACY_PTY_COUNT=256
  10.847 +CONFIG_HVC_DRIVER=y
  10.848 +CONFIG_HVC_CONSOLE=y
  10.849 +# CONFIG_HVC_RTAS is not set
  10.850 +# CONFIG_HVCS is not set
  10.851 +
  10.852 +#
  10.853 +# IPMI
  10.854 +#
  10.855 +# CONFIG_IPMI_HANDLER is not set
  10.856 +
  10.857 +#
  10.858 +# Watchdog Cards
  10.859 +#
  10.860 +# CONFIG_WATCHDOG is not set
  10.861 +CONFIG_HW_RANDOM=y
  10.862 +CONFIG_GEN_RTC=y
  10.863 +# CONFIG_GEN_RTC_X is not set
  10.864 +# CONFIG_DTLK is not set
  10.865 +# CONFIG_R3964 is not set
  10.866 +# CONFIG_APPLICOM is not set
  10.867 +
  10.868 +#
  10.869 +# Ftape, the floppy tape device driver
  10.870 +#
  10.871 +# CONFIG_AGP is not set
  10.872 +# CONFIG_DRM is not set
  10.873 +# CONFIG_RAW_DRIVER is not set
  10.874 +# CONFIG_HANGCHECK_TIMER is not set
  10.875 +
  10.876 +#
  10.877 +# TPM devices
  10.878 +#
  10.879 +# CONFIG_TCG_TPM is not set
  10.880 +# CONFIG_TELCLOCK is not set
  10.881 +
  10.882 +#
  10.883 +# I2C support
  10.884 +#
  10.885 +CONFIG_I2C=y
  10.886 +CONFIG_I2C_CHARDEV=y
  10.887 +
  10.888 +#
  10.889 +# I2C Algorithms
  10.890 +#
  10.891 +CONFIG_I2C_ALGOBIT=y
  10.892 +# CONFIG_I2C_ALGOPCF is not set
  10.893 +# CONFIG_I2C_ALGOPCA is not set
  10.894 +
  10.895 +#
  10.896 +# I2C Hardware Bus support
  10.897 +#
  10.898 +# CONFIG_I2C_ALI1535 is not set
  10.899 +# CONFIG_I2C_ALI1563 is not set
  10.900 +# CONFIG_I2C_ALI15X3 is not set
  10.901 +# CONFIG_I2C_AMD756 is not set
  10.902 +CONFIG_I2C_AMD8111=y
  10.903 +# CONFIG_I2C_I801 is not set
  10.904 +# CONFIG_I2C_I810 is not set
  10.905 +# CONFIG_I2C_PIIX4 is not set
  10.906 +# CONFIG_I2C_NFORCE2 is not set
  10.907 +# CONFIG_I2C_OCORES is not set
  10.908 +# CONFIG_I2C_PARPORT_LIGHT is not set
  10.909 +# CONFIG_I2C_PROSAVAGE is not set
  10.910 +# CONFIG_I2C_SAVAGE4 is not set
  10.911 +# CONFIG_I2C_SIS5595 is not set
  10.912 +# CONFIG_I2C_SIS630 is not set
  10.913 +# CONFIG_I2C_SIS96X is not set
  10.914 +# CONFIG_I2C_STUB is not set
  10.915 +# CONFIG_I2C_VIA is not set
  10.916 +# CONFIG_I2C_VIAPRO is not set
  10.917 +# CONFIG_I2C_VOODOO3 is not set
  10.918 +# CONFIG_I2C_PCA_ISA is not set
  10.919 +
  10.920 +#
  10.921 +# Miscellaneous I2C Chip support
  10.922 +#
  10.923 +# CONFIG_SENSORS_DS1337 is not set
  10.924 +# CONFIG_SENSORS_DS1374 is not set
  10.925 +# CONFIG_SENSORS_EEPROM is not set
  10.926 +# CONFIG_SENSORS_PCF8574 is not set
  10.927 +# CONFIG_SENSORS_PCA9539 is not set
  10.928 +# CONFIG_SENSORS_PCF8591 is not set
  10.929 +# CONFIG_SENSORS_MAX6875 is not set
  10.930 +# CONFIG_I2C_DEBUG_CORE is not set
  10.931 +# CONFIG_I2C_DEBUG_ALGO is not set
  10.932 +# CONFIG_I2C_DEBUG_BUS is not set
  10.933 +# CONFIG_I2C_DEBUG_CHIP is not set
  10.934 +
  10.935 +#
  10.936 +# SPI support
  10.937 +#
  10.938 +# CONFIG_SPI is not set
  10.939 +# CONFIG_SPI_MASTER is not set
  10.940 +
  10.941 +#
  10.942 +# Dallas's 1-wire bus
  10.943 +#
  10.944 +
  10.945 +#
  10.946 +# Hardware Monitoring support
  10.947 +#
  10.948 +# CONFIG_HWMON is not set
  10.949 +# CONFIG_HWMON_VID is not set
  10.950 +
  10.951 +#
  10.952 +# Misc devices
  10.953 +#
  10.954 +
  10.955 +#
  10.956 +# Multimedia devices
  10.957 +#
  10.958 +# CONFIG_VIDEO_DEV is not set
  10.959 +CONFIG_VIDEO_V4L2=y
  10.960 +
  10.961 +#
  10.962 +# Digital Video Broadcasting Devices
  10.963 +#
  10.964 +# CONFIG_DVB is not set
  10.965 +
  10.966 +#
  10.967 +# Graphics support
  10.968 +#
  10.969 +CONFIG_FIRMWARE_EDID=y
  10.970 +# CONFIG_FB is not set
  10.971 +
  10.972 +#
  10.973 +# Console display driver support
  10.974 +#
  10.975 +# CONFIG_VGA_CONSOLE is not set
  10.976 +CONFIG_DUMMY_CONSOLE=y
  10.977 +
  10.978 +#
  10.979 +# Sound
  10.980 +#
  10.981 +# CONFIG_SOUND is not set
  10.982 +
  10.983 +#
  10.984 +# USB support
  10.985 +#
  10.986 +CONFIG_USB_ARCH_HAS_HCD=y
  10.987 +CONFIG_USB_ARCH_HAS_OHCI=y
  10.988 +CONFIG_USB_ARCH_HAS_EHCI=y
  10.989 +# CONFIG_USB is not set
  10.990 +
  10.991 +#
  10.992 +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
  10.993 +#
  10.994 +
  10.995 +#
  10.996 +# USB Gadget Support
  10.997 +#
  10.998 +# CONFIG_USB_GADGET is not set
  10.999 +
 10.1000 +#
 10.1001 +# MMC/SD Card support
 10.1002 +#
 10.1003 +# CONFIG_MMC is not set
 10.1004 +
 10.1005 +#
 10.1006 +# LED devices
 10.1007 +#
 10.1008 +# CONFIG_NEW_LEDS is not set
 10.1009 +
 10.1010 +#
 10.1011 +# LED drivers
 10.1012 +#
 10.1013 +
 10.1014 +#
 10.1015 +# LED Triggers
 10.1016 +#
 10.1017 +
 10.1018 +#
 10.1019 +# InfiniBand support
 10.1020 +#
 10.1021 +CONFIG_INFINIBAND=y
 10.1022 +CONFIG_INFINIBAND_USER_MAD=y
 10.1023 +CONFIG_INFINIBAND_USER_ACCESS=y
 10.1024 +CONFIG_INFINIBAND_ADDR_TRANS=y
 10.1025 +CONFIG_INFINIBAND_MTHCA=y
 10.1026 +CONFIG_INFINIBAND_MTHCA_DEBUG=y
 10.1027 +CONFIG_INFINIBAND_IPOIB=y
 10.1028 +CONFIG_INFINIBAND_IPOIB_DEBUG=y
 10.1029 +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
 10.1030 +CONFIG_INFINIBAND_SRP=y
 10.1031 +# CONFIG_INFINIBAND_ISER is not set
 10.1032 +
 10.1033 +#
 10.1034 +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 10.1035 +#
 10.1036 +
 10.1037 +#
 10.1038 +# Real Time Clock
 10.1039 +#
 10.1040 +# CONFIG_RTC_CLASS is not set
 10.1041 +
 10.1042 +#
 10.1043 +# DMA Engine support
 10.1044 +#
 10.1045 +# CONFIG_DMA_ENGINE is not set
 10.1046 +
 10.1047 +#
 10.1048 +# DMA Clients
 10.1049 +#
 10.1050 +
 10.1051 +#
 10.1052 +# DMA Devices
 10.1053 +#
 10.1054 +
 10.1055 +#
 10.1056 +# File systems
 10.1057 +#
 10.1058 +CONFIG_EXT2_FS=y
 10.1059 +# CONFIG_EXT2_FS_XATTR is not set
 10.1060 +CONFIG_EXT2_FS_XIP=y
 10.1061 +CONFIG_FS_XIP=y
 10.1062 +CONFIG_EXT3_FS=y
 10.1063 +# CONFIG_EXT3_FS_XATTR is not set
 10.1064 +CONFIG_JBD=y
 10.1065 +# CONFIG_JBD_DEBUG is not set
 10.1066 +CONFIG_REISERFS_FS=y
 10.1067 +# CONFIG_REISERFS_CHECK is not set
 10.1068 +CONFIG_REISERFS_PROC_INFO=y
 10.1069 +CONFIG_REISERFS_FS_XATTR=y
 10.1070 +CONFIG_REISERFS_FS_POSIX_ACL=y
 10.1071 +CONFIG_REISERFS_FS_SECURITY=y
 10.1072 +# CONFIG_JFS_FS is not set
 10.1073 +CONFIG_FS_POSIX_ACL=y
 10.1074 +# CONFIG_XFS_FS is not set
 10.1075 +# CONFIG_OCFS2_FS is not set
 10.1076 +# CONFIG_MINIX_FS is not set
 10.1077 +# CONFIG_ROMFS_FS is not set
 10.1078 +CONFIG_INOTIFY=y
 10.1079 +CONFIG_INOTIFY_USER=y
 10.1080 +# CONFIG_QUOTA is not set
 10.1081 +CONFIG_DNOTIFY=y
 10.1082 +CONFIG_AUTOFS_FS=y
 10.1083 +# CONFIG_AUTOFS4_FS is not set
 10.1084 +# CONFIG_FUSE_FS is not set
 10.1085 +
 10.1086 +#
 10.1087 +# CD-ROM/DVD Filesystems
 10.1088 +#
 10.1089 +CONFIG_ISO9660_FS=y
 10.1090 +# CONFIG_JOLIET is not set
 10.1091 +# CONFIG_ZISOFS is not set
 10.1092 +# CONFIG_UDF_FS is not set
 10.1093 +
 10.1094 +#
 10.1095 +# DOS/FAT/NT Filesystems
 10.1096 +#
 10.1097 +CONFIG_FAT_FS=y
 10.1098 +CONFIG_MSDOS_FS=y
 10.1099 +CONFIG_VFAT_FS=y
 10.1100 +CONFIG_FAT_DEFAULT_CODEPAGE=437
 10.1101 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 10.1102 +# CONFIG_NTFS_FS is not set
 10.1103 +
 10.1104 +#
 10.1105 +# Pseudo filesystems
 10.1106 +#
 10.1107 +CONFIG_PROC_FS=y
 10.1108 +CONFIG_PROC_KCORE=y
 10.1109 +CONFIG_SYSFS=y
 10.1110 +CONFIG_TMPFS=y
 10.1111 +# CONFIG_HUGETLB_PAGE is not set
 10.1112 +CONFIG_RAMFS=y
 10.1113 +# CONFIG_CONFIGFS_FS is not set
 10.1114 +
 10.1115 +#
 10.1116 +# Miscellaneous filesystems
 10.1117 +#
 10.1118 +# CONFIG_ADFS_FS is not set
 10.1119 +# CONFIG_AFFS_FS is not set
 10.1120 +# CONFIG_HFS_FS is not set
 10.1121 +# CONFIG_HFSPLUS_FS is not set
 10.1122 +# CONFIG_BEFS_FS is not set
 10.1123 +# CONFIG_BFS_FS is not set
 10.1124 +# CONFIG_EFS_FS is not set
 10.1125 +CONFIG_CRAMFS=y
 10.1126 +# CONFIG_VXFS_FS is not set
 10.1127 +# CONFIG_HPFS_FS is not set
 10.1128 +# CONFIG_QNX4FS_FS is not set
 10.1129 +# CONFIG_SYSV_FS is not set
 10.1130 +# CONFIG_UFS_FS is not set
 10.1131 +
 10.1132 +#
 10.1133 +# Network File Systems
 10.1134 +#
 10.1135 +CONFIG_NFS_FS=y
 10.1136 +CONFIG_NFS_V3=y
 10.1137 +CONFIG_NFS_V3_ACL=y
 10.1138 +CONFIG_NFS_V4=y
 10.1139 +# CONFIG_NFS_DIRECTIO is not set
 10.1140 +# CONFIG_NFSD is not set
 10.1141 +CONFIG_ROOT_NFS=y
 10.1142 +CONFIG_LOCKD=y
 10.1143 +CONFIG_LOCKD_V4=y
 10.1144 +CONFIG_NFS_ACL_SUPPORT=y
 10.1145 +CONFIG_NFS_COMMON=y
 10.1146 +CONFIG_SUNRPC=y
 10.1147 +CONFIG_SUNRPC_GSS=y
 10.1148 +CONFIG_RPCSEC_GSS_KRB5=y
 10.1149 +# CONFIG_RPCSEC_GSS_SPKM3 is not set
 10.1150 +# CONFIG_SMB_FS is not set
 10.1151 +# CONFIG_CIFS is not set
 10.1152 +# CONFIG_CIFS_DEBUG2 is not set
 10.1153 +# CONFIG_NCP_FS is not set
 10.1154 +# CONFIG_CODA_FS is not set
 10.1155 +# CONFIG_AFS_FS is not set
 10.1156 +# CONFIG_9P_FS is not set
 10.1157 +
 10.1158 +#
 10.1159 +# Partition Types
 10.1160 +#
 10.1161 +CONFIG_PARTITION_ADVANCED=y
 10.1162 +# CONFIG_ACORN_PARTITION is not set
 10.1163 +# CONFIG_OSF_PARTITION is not set
 10.1164 +# CONFIG_AMIGA_PARTITION is not set
 10.1165 +# CONFIG_ATARI_PARTITION is not set
 10.1166 +CONFIG_MAC_PARTITION=y
 10.1167 +CONFIG_MSDOS_PARTITION=y
 10.1168 +# CONFIG_BSD_DISKLABEL is not set
 10.1169 +# CONFIG_MINIX_SUBPARTITION is not set
 10.1170 +# CONFIG_SOLARIS_X86_PARTITION is not set
 10.1171 +# CONFIG_UNIXWARE_DISKLABEL is not set
 10.1172 +# CONFIG_LDM_PARTITION is not set
 10.1173 +# CONFIG_SGI_PARTITION is not set
 10.1174 +# CONFIG_ULTRIX_PARTITION is not set
 10.1175 +# CONFIG_SUN_PARTITION is not set
 10.1176 +# CONFIG_KARMA_PARTITION is not set
 10.1177 +# CONFIG_EFI_PARTITION is not set
 10.1178 +
 10.1179 +#
 10.1180 +# Native Language Support
 10.1181 +#
 10.1182 +CONFIG_NLS=y
 10.1183 +CONFIG_NLS_DEFAULT="utf-8"
 10.1184 +# CONFIG_NLS_CODEPAGE_437 is not set
 10.1185 +# CONFIG_NLS_CODEPAGE_737 is not set
 10.1186 +# CONFIG_NLS_CODEPAGE_775 is not set
 10.1187 +# CONFIG_NLS_CODEPAGE_850 is not set
 10.1188 +# CONFIG_NLS_CODEPAGE_852 is not set
 10.1189 +# CONFIG_NLS_CODEPAGE_855 is not set
 10.1190 +# CONFIG_NLS_CODEPAGE_857 is not set
 10.1191 +# CONFIG_NLS_CODEPAGE_860 is not set
 10.1192 +# CONFIG_NLS_CODEPAGE_861 is not set
 10.1193 +# CONFIG_NLS_CODEPAGE_862 is not set
 10.1194 +# CONFIG_NLS_CODEPAGE_863 is not set
 10.1195 +# CONFIG_NLS_CODEPAGE_864 is not set
 10.1196 +# CONFIG_NLS_CODEPAGE_865 is not set
 10.1197 +# CONFIG_NLS_CODEPAGE_866 is not set
 10.1198 +# CONFIG_NLS_CODEPAGE_869 is not set
 10.1199 +# CONFIG_NLS_CODEPAGE_936 is not set
 10.1200 +# CONFIG_NLS_CODEPAGE_950 is not set
 10.1201 +# CONFIG_NLS_CODEPAGE_932 is not set
 10.1202 +# CONFIG_NLS_CODEPAGE_949 is not set
 10.1203 +# CONFIG_NLS_CODEPAGE_874 is not set
 10.1204 +# CONFIG_NLS_ISO8859_8 is not set
 10.1205 +# CONFIG_NLS_CODEPAGE_1250 is not set
 10.1206 +# CONFIG_NLS_CODEPAGE_1251 is not set
 10.1207 +# CONFIG_NLS_ASCII is not set
 10.1208 +# CONFIG_NLS_ISO8859_1 is not set
 10.1209 +# CONFIG_NLS_ISO8859_2 is not set
 10.1210 +# CONFIG_NLS_ISO8859_3 is not set
 10.1211 +# CONFIG_NLS_ISO8859_4 is not set
 10.1212 +# CONFIG_NLS_ISO8859_5 is not set
 10.1213 +# CONFIG_NLS_ISO8859_6 is not set
 10.1214 +# CONFIG_NLS_ISO8859_7 is not set
 10.1215 +# CONFIG_NLS_ISO8859_9 is not set
 10.1216 +# CONFIG_NLS_ISO8859_13 is not set
 10.1217 +# CONFIG_NLS_ISO8859_14 is not set
 10.1218 +# CONFIG_NLS_ISO8859_15 is not set
 10.1219 +# CONFIG_NLS_KOI8_R is not set
 10.1220 +# CONFIG_NLS_KOI8_U is not set
 10.1221 +CONFIG_NLS_UTF8=y
 10.1222 +
 10.1223 +#
 10.1224 +# Library routines
 10.1225 +#
 10.1226 +CONFIG_CRC_CCITT=y
 10.1227 +# CONFIG_CRC16 is not set
 10.1228 +CONFIG_CRC32=y
 10.1229 +# CONFIG_LIBCRC32C is not set
 10.1230 +CONFIG_ZLIB_INFLATE=y
 10.1231 +CONFIG_ZLIB_DEFLATE=y
 10.1232 +CONFIG_TEXTSEARCH=y
 10.1233 +CONFIG_TEXTSEARCH_KMP=y
 10.1234 +CONFIG_TEXTSEARCH_BM=y
 10.1235 +CONFIG_TEXTSEARCH_FSM=y
 10.1236 +CONFIG_PLIST=y
 10.1237 +
 10.1238 +#
 10.1239 +# Instrumentation Support
 10.1240 +#
 10.1241 +# CONFIG_PROFILING is not set
 10.1242 +# CONFIG_KPROBES is not set
 10.1243 +
 10.1244 +#
 10.1245 +# Kernel hacking
 10.1246 +#
 10.1247 +# CONFIG_PRINTK_TIME is not set
 10.1248 +CONFIG_MAGIC_SYSRQ=y
 10.1249 +# CONFIG_UNUSED_SYMBOLS is not set
 10.1250 +CONFIG_DEBUG_KERNEL=y
 10.1251 +CONFIG_LOG_BUF_SHIFT=17
 10.1252 +CONFIG_DETECT_SOFTLOCKUP=y
 10.1253 +# CONFIG_SCHEDSTATS is not set
 10.1254 +CONFIG_DEBUG_SLAB=y
 10.1255 +CONFIG_DEBUG_MUTEXES=y
 10.1256 +# CONFIG_DEBUG_RT_MUTEXES is not set
 10.1257 +# CONFIG_RT_MUTEX_TESTER is not set
 10.1258 +# CONFIG_DEBUG_SPINLOCK is not set
 10.1259 +CONFIG_DEBUG_SPINLOCK_SLEEP=y
 10.1260 +# CONFIG_DEBUG_KOBJECT is not set
 10.1261 +CONFIG_DEBUG_INFO=y
 10.1262 +CONFIG_DEBUG_FS=y
 10.1263 +# CONFIG_DEBUG_VM is not set
 10.1264 +CONFIG_FORCED_INLINING=y
 10.1265 +# CONFIG_RCU_TORTURE_TEST is not set
 10.1266 +CONFIG_DEBUG_STACKOVERFLOW=y
 10.1267 +CONFIG_DEBUG_STACK_USAGE=y
 10.1268 +CONFIG_DEBUGGER=y
 10.1269 +CONFIG_XMON=y
 10.1270 +CONFIG_XMON_DEFAULT=y
 10.1271 +# CONFIG_IRQSTACKS is not set
 10.1272 +CONFIG_BOOTX_TEXT=y
 10.1273 +# CONFIG_PPC_EARLY_DEBUG is not set
 10.1274 +
 10.1275 +#
 10.1276 +# Security options
 10.1277 +#
 10.1278 +# CONFIG_KEYS is not set
 10.1279 +# CONFIG_SECURITY is not set
 10.1280 +CONFIG_XEN=y
 10.1281 +CONFIG_XEN_INTERFACE_VERSION=0x00030202
 10.1282 +
 10.1283 +#
 10.1284 +# XEN
 10.1285 +#
 10.1286 +CONFIG_XEN_PRIVILEGED_GUEST=y
 10.1287 +CONFIG_XEN_UNPRIVILEGED_GUEST=y
 10.1288 +CONFIG_XEN_PRIVCMD=y
 10.1289 +CONFIG_XEN_BACKEND=y
 10.1290 +# CONFIG_XEN_PCIDEV_BACKEND is not set
 10.1291 +CONFIG_XEN_BLKDEV_BACKEND=y
 10.1292 +CONFIG_XEN_XENBUS_DEV=y
 10.1293 +CONFIG_XEN_NETDEV_BACKEND=y
 10.1294 +# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 10.1295 +CONFIG_XEN_NETDEV_LOOPBACK=y
 10.1296 +# CONFIG_XEN_TPMDEV_BACKEND is not set
 10.1297 +CONFIG_XEN_BLKDEV_FRONTEND=y
 10.1298 +CONFIG_XEN_NETDEV_FRONTEND=y
 10.1299 +CONFIG_XEN_SCRUB_PAGES=y
 10.1300 +CONFIG_XEN_DISABLE_SERIAL=y
 10.1301 +CONFIG_XEN_SYSFS=y
 10.1302 +# CONFIG_XEN_COMPAT_030002_AND_LATER is not set
 10.1303 +CONFIG_XEN_COMPAT_LATEST_ONLY=y
 10.1304 +# CONFIG_XEN_COMPAT_030002 is not set
 10.1305 +CONFIG_HAVE_ARCH_ALLOC_SKB=y
 10.1306 +CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
 10.1307 +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 10.1308 +CONFIG_NO_IDLE_HZ=y
 10.1309 +CONFIG_XEN_DEVMEM=y
 10.1310 +CONFIG_XEN_SKBUFF=y
 10.1311 +CONFIG_XEN_REBOOT=y
 10.1312 +CONFIG_XEN_XENCOMM=y
 10.1313 +
 10.1314 +#
 10.1315 +# Cryptographic options
 10.1316 +#
 10.1317 +CONFIG_CRYPTO=y
 10.1318 +CONFIG_CRYPTO_HMAC=y
 10.1319 +# CONFIG_CRYPTO_NULL is not set
 10.1320 +# CONFIG_CRYPTO_MD4 is not set
 10.1321 +CONFIG_CRYPTO_MD5=y
 10.1322 +CONFIG_CRYPTO_SHA1=y
 10.1323 +# CONFIG_CRYPTO_SHA256 is not set
 10.1324 +# CONFIG_CRYPTO_SHA512 is not set
 10.1325 +# CONFIG_CRYPTO_WP512 is not set
 10.1326 +# CONFIG_CRYPTO_TGR192 is not set
 10.1327 +CONFIG_CRYPTO_DES=y
 10.1328 +# CONFIG_CRYPTO_BLOWFISH is not set
 10.1329 +# CONFIG_CRYPTO_TWOFISH is not set
 10.1330 +# CONFIG_CRYPTO_SERPENT is not set
 10.1331 +# CONFIG_CRYPTO_AES is not set
 10.1332 +# CONFIG_CRYPTO_CAST5 is not set
 10.1333 +# CONFIG_CRYPTO_CAST6 is not set
 10.1334 +# CONFIG_CRYPTO_TEA is not set
 10.1335 +# CONFIG_CRYPTO_ARC4 is not set
 10.1336 +# CONFIG_CRYPTO_KHAZAD is not set
 10.1337 +# CONFIG_CRYPTO_ANUBIS is not set
 10.1338 +CONFIG_CRYPTO_DEFLATE=y
 10.1339 +# CONFIG_CRYPTO_MICHAEL_MIC is not set
 10.1340 +# CONFIG_CRYPTO_CRC32C is not set
 10.1341 +# CONFIG_CRYPTO_TEST is not set
 10.1342 +
 10.1343 +#
 10.1344 +# Hardware crypto devices
 10.1345 +#
    11.1 --- a/arch/powerpc/kernel/cpu_setup_power4.S	Mon Jul 09 09:24:03 2007 -0600
    11.2 +++ b/arch/powerpc/kernel/cpu_setup_power4.S	Tue Jul 10 08:40:03 2007 -0600
    11.3 @@ -73,6 +73,13 @@ 1:
    11.4  	blr
    11.5  
    11.6  _GLOBAL(__setup_cpu_ppc970)
    11.7 +	/*
    11.8 +	 * Do nothing if not running in HV mode
    11.9 +	 */
   11.10 +	mfmsr	r0
   11.11 +	rldicl.	r0,r0,4,63
   11.12 +	beqlr
   11.13 +
   11.14  	mfspr	r0,SPRN_HID0
   11.15  	li	r11,5			/* clear DOZE and SLEEP */
   11.16  	rldimi	r0,r11,52,8		/* set NAP and DPM */
    12.1 --- a/arch/powerpc/kernel/prom_init.c	Mon Jul 09 09:24:03 2007 -0600
    12.2 +++ b/arch/powerpc/kernel/prom_init.c	Tue Jul 10 08:40:03 2007 -0600
    12.3 @@ -188,6 +188,7 @@ static unsigned long __initdata prom_tce
    12.4  #define PLATFORM_LPAR		0x0001
    12.5  #define PLATFORM_POWERMAC	0x0400
    12.6  #define PLATFORM_GENERIC	0x0500
    12.7 +#define PLATFORM_GENERIC_XEN	(PLATFORM_GENERIC | PLATFORM_LPAR)
    12.8  
    12.9  static int __initdata of_platform;
   12.10  
   12.11 @@ -1529,6 +1530,14 @@ static int __init prom_find_machine_type
   12.12  	phandle rtas;
   12.13  	int x;
   12.14  #endif
   12.15 +#ifdef CONFIG_PPC_XEN
   12.16 +	phandle xen;
   12.17 +
   12.18 +	xen = call_prom("finddevice", 1, 1, ADDR("/xen"));
   12.19 +	if (PHANDLE_VALID(xen)) {
   12.20 +		return PLATFORM_GENERIC_XEN;
   12.21 +	}
   12.22 +#endif
   12.23  
   12.24  	/* Look for a PowerMac */
   12.25  	len = prom_getprop(_prom->root, "compatible",
   12.26 @@ -2262,6 +2271,31 @@ unsigned long __init prom_init(unsigned 
   12.27  	if (RELOC(of_platform) == PLATFORM_PSERIES)
   12.28  		prom_initialize_tce_table();
   12.29  #endif
   12.30 +#ifdef CONFIG_PPC_XEN
   12.31 +	if (RELOC(of_platform) & PLATFORM_LPAR) {
   12.32 +		phandle xen;
   12.33 +
   12.34 +		prom_debug("XXX:checking for Xen OF package\n");
   12.35 +
   12.36 +		xen = call_prom("finddevice", 1, 1, ADDR("/xen"));
   12.37 +		if (PHANDLE_VALID(xen)) {
   12.38 +			u64 res[2];
   12.39 +			int l;
   12.40 +			ulong base;
   12.41 +
   12.42 +			l = prom_getprop(xen, "reserved", res, sizeof (res));
   12.43 +			if (l != sizeof(res)) {
   12.44 +				prom_panic("Xen reserved prop not exist\n");
   12.45 +			}
   12.46 +			
   12.47 +			base = alloc_down(res[1], PAGE_SIZE, 0);
   12.48 +			if (base != res[0]) {
   12.49 +				prom_panic("XSI != alloc_down()\n");
   12.50 +			}
   12.51 +			reserve_mem(res[0], res[1]);
   12.52 +		}
   12.53 +	}	
   12.54 +#endif
   12.55  
   12.56  	/*
   12.57  	 * On non-powermacs, try to instantiate RTAS and puts all CPUs
    13.1 --- a/arch/powerpc/kernel/setup-common.c	Mon Jul 09 09:24:03 2007 -0600
    13.2 +++ b/arch/powerpc/kernel/setup-common.c	Tue Jul 10 08:40:03 2007 -0600
    13.3 @@ -387,6 +387,12 @@ void __init smp_setup_cpu_maps(void)
    13.4  		}
    13.5  	}
    13.6  
    13.7 +	if (machine_is(xen)) {
    13.8 +		/* something more inteligent perhaps? */
    13.9 +		for (cpu = 0; cpu < NR_CPUS; cpu++)
   13.10 +			cpu_set(cpu, cpu_possible_map);
   13.11 +	}
   13.12 +
   13.13  #ifdef CONFIG_PPC64
   13.14  	/*
   13.15  	 * On pSeries LPAR, we need to know how many cpus
    14.1 --- a/arch/powerpc/kernel/udbg.c	Mon Jul 09 09:24:03 2007 -0600
    14.2 +++ b/arch/powerpc/kernel/udbg.c	Tue Jul 10 08:40:03 2007 -0600
    14.3 @@ -45,6 +45,9 @@ void __init udbg_early_init(void)
    14.4  #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES)
    14.5  	/* For iSeries - hit Ctrl-x Ctrl-x to see the output */
    14.6  	udbg_init_iseries();
    14.7 +#elif defined(CONFIG_PPC_EARLY_DEBUG_XEN_DOM0) || \
    14.8 +	defined(CONFIG_PPC_EARLY_DEBUG_XEN_DOMU)
    14.9 +	udbg_init_xen();
   14.10  #endif
   14.11  }
   14.12  
    15.1 --- a/arch/powerpc/mm/slb_low.S	Mon Jul 09 09:24:03 2007 -0600
    15.2 +++ b/arch/powerpc/mm/slb_low.S	Tue Jul 10 08:40:03 2007 -0600
    15.3 @@ -51,6 +51,23 @@
    15.4  	*/
    15.5  	bne	cr7,1f
    15.6  
    15.7 +#ifdef CONFIG_PPC_XEN
    15.8 +_GLOBAL(slb_miss_kernel_load_xen_nop)
    15.9 +	b 3f
   15.10 +	/* Need to check if it is in the part of our XEN Foreign Map */
   15.11 +	rldicl	r9,r3,30,63		/* get Xen region */
   15.12 +	cmpldi	cr7,r9,1		/* cmp this bit set to 1 */
   15.13 +	bne	cr7,3f
   15.14 +	/* Xen Linear mapping encoding bits, the "li" instruction below
   15.15 +	 * could be patched below (like the other pages of the linear map)
   15.16 +	 * if we ever wish to map anything other that 4K pages in 
   15.17 +	 * this region, right now it is fine as zero.
   15.18 +	 */
   15.19 +_GLOBAL(slb_miss_kernel_load_xen_linear)
   15.20 +	li	r11,0
   15.21 +	b	slb_finish_load
   15.22 +3:
   15.23 +#endif
   15.24  	/* Linear mapping encoding bits, the "li" instruction below will
   15.25  	 * be patched by the kernel at boot
   15.26  	 */
    16.1 --- a/arch/powerpc/platforms/Makefile	Mon Jul 09 09:24:03 2007 -0600
    16.2 +++ b/arch/powerpc/platforms/Makefile	Tue Jul 10 08:40:03 2007 -0600
    16.3 @@ -12,6 +12,8 @@ obj-$(CONFIG_PPC_85xx)		+= 85xx/
    16.4  obj-$(CONFIG_PPC_86xx)		+= 86xx/
    16.5  obj-$(CONFIG_PPC_PSERIES)	+= pseries/
    16.6  obj-$(CONFIG_PPC_ISERIES)	+= iseries/
    16.7 +# must occur before xen hosting platforms
    16.8 +obj-$(CONFIG_PPC_XEN)		+= xen/
    16.9  obj-$(CONFIG_PPC_MAPLE)		+= maple/
   16.10  obj-$(CONFIG_PPC_CELL)		+= cell/
   16.11  obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
    17.1 --- a/arch/powerpc/platforms/pseries/iommu.c	Mon Jul 09 09:24:03 2007 -0600
    17.2 +++ b/arch/powerpc/platforms/pseries/iommu.c	Tue Jul 10 08:40:03 2007 -0600
    17.3 @@ -531,6 +531,17 @@ static void iommu_dev_setup_pSeriesLP(st
    17.4  	 * already allocated.
    17.5  	 */
    17.6  	dn = pci_device_to_OF_node(dev);
    17.7 +	if (dn == NULL) {
    17.8 +#ifdef CONFIG_PPC_XEN
    17.9 +		/* this becomes possible for Xen Dom0 */
   17.10 +		DBG("%s, dev %p (%s) has no OF devtree entree\n", __func__,
   17.11 +		    dev, pci_name(dev));
   17.12 +		return;
   17.13 +#else
   17.14 +		panic("%s, dev %p (%s) has no OF devtree entree\n", __func__,
   17.15 +		      dev, pci_name(dev));
   17.16 +#endif
   17.17 +	}
   17.18  
   17.19  	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
   17.20  	     pdn = pdn->parent) {
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/arch/powerpc/platforms/xen/Makefile	Tue Jul 10 08:40:03 2007 -0600
    18.3 @@ -0,0 +1,20 @@
    18.4 +obj-y	+= gnttab.o
    18.5 +obj-y	+= hcall.o
    18.6 +obj-y	+= reboot.o
    18.7 +obj-y	+= setup.o
    18.8 +obj-y	+= smp.o
    18.9 +obj-y	+= time.o
   18.10 +obj-y	+= udbg_xen.o
   18.11 +obj-y	+= xen_guest.o
   18.12 +obj-y	+= xencomm.o
   18.13 +
   18.14 +# we need the latest __XEN_INTERFACE_VERSION__ (see xen-compat.h)
   18.15 +CFLAGS_hcall.o += -D__XEN_TOOLS__
   18.16 +
   18.17 +ifndef CONFIG_XEN_BALLOON
   18.18 +obj-y += balloon.o
   18.19 +endif
   18.20 +
   18.21 +ifndef CONFIG_XEN_UTIL
   18.22 +obj-y	+= util.o
   18.23 +endif
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/arch/powerpc/platforms/xen/balloon.c	Tue Jul 10 08:40:03 2007 -0600
    19.3 @@ -0,0 +1,82 @@
    19.4 +/*
    19.5 + * This program is free software; you can redistribute it and/or modify
    19.6 + * it under the terms of the GNU General Public License as published by
    19.7 + * the Free Software Foundation; either version 2 of the License, or
    19.8 + * (at your option) any later version.
    19.9 + *
   19.10 + * This program is distributed in the hope that it will be useful,
   19.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.13 + * GNU General Public License for more details.
   19.14 + *
   19.15 + * You should have received a copy of the GNU General Public License
   19.16 + * along with this program; if not, write to the Free Software
   19.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   19.18 + *
   19.19 + * Copyright (C) IBM Corp. 2006
   19.20 + *
   19.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   19.22 + */
   19.23 +
   19.24 +#include <linux/module.h>
   19.25 +#include <linux/mm.h>
   19.26 +#include <asm/hypervisor.h>
   19.27 +#include "setup.h"
   19.28 +
   19.29 +/*
   19.30 + * FIXME: Port balloon driver, if ever
   19.31 + */
   19.32 +
   19.33 +struct page **alloc_empty_pages_and_pagevec(int nr_pages)
   19.34 +{
   19.35 +	struct page *page, **pagevec;
   19.36 +	int i;
   19.37 +
   19.38 +	pagevec = kmalloc(sizeof(*pagevec) * nr_pages, GFP_KERNEL);
   19.39 +	if (pagevec == NULL)
   19.40 +		return  NULL;
   19.41 +
   19.42 +	for (i = 0; i < nr_pages; i++) {
   19.43 +		page = alloc_foreign_page();
   19.44 +		BUG_ON(page == NULL);
   19.45 +		pagevec[i] = page;
   19.46 +		/* There is no real page backing us yet so it cannot
   19.47 +		 * be scrubbed */
   19.48 +	}
   19.49 +
   19.50 +	return pagevec;
   19.51 +}
   19.52 +
   19.53 +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
   19.54 +{
   19.55 +	int i;
   19.56 +
   19.57 +	if (pagevec == NULL)
   19.58 +		return;
   19.59 +
   19.60 +	for (i = 0; i < nr_pages; i++) {
   19.61 +		free_foreign_page(pagevec[i]);
   19.62 +	}
   19.63 +	
   19.64 +	kfree(pagevec);
   19.65 +}
   19.66 +
   19.67 +void balloon_dealloc_empty_page_range(
   19.68 +	struct page *page, unsigned long nr_pages)
   19.69 +{
   19.70 +	__free_pages(page, get_order(nr_pages * PAGE_SIZE));
   19.71 +}
   19.72 +
   19.73 +void balloon_update_driver_allowance(long delta)
   19.74 +{
   19.75 +}
   19.76 +
   19.77 +void balloon_release_driver_page(struct page *page)
   19.78 +{
   19.79 +	BUG();
   19.80 +}
   19.81 +
   19.82 +EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
   19.83 +EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
   19.84 +EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
   19.85 +EXPORT_SYMBOL_GPL(balloon_release_driver_page);
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/arch/powerpc/platforms/xen/gnttab.c	Tue Jul 10 08:40:03 2007 -0600
    20.3 @@ -0,0 +1,468 @@
    20.4 +/*
    20.5 + * This program is free software; you can redistribute it and/or modify
    20.6 + * it under the terms of the GNU General Public License as published by
    20.7 + * the Free Software Foundation; either version 2 of the License, or
    20.8 + * (at your option) any later version.
    20.9 + *
   20.10 + * This program is distributed in the hope that it will be useful,
   20.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.13 + * GNU General Public License for more details.
   20.14 + *
   20.15 + * You should have received a copy of the GNU General Public License
   20.16 + * along with this program; if not, write to the Free Software
   20.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   20.18 + *
   20.19 + * Copyright (C) IBM Corp. 2006
   20.20 + *
   20.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   20.22 + */
   20.23 +
   20.24 +#include <linux/config.h>
   20.25 +#include <linux/vmalloc.h>
   20.26 +#include <linux/memory_hotplug.h>
   20.27 +#include <xen/gnttab.h>
   20.28 +#include <asm/hypervisor.h>
   20.29 +#include <xen/interface/grant_table.h>
   20.30 +#include <asm/pgtable.h>
   20.31 +#include <asm/sections.h>
   20.32 +#include <asm/io.h>
   20.33 +#include <asm/machdep.h>
   20.34 +#include <asm/prom.h>
   20.35 +#include <asm/cacheflush.h>
   20.36 +#include "setup.h"
   20.37 +#include "../pseries/plpar_wrappers.h"
   20.38 +
   20.39 +#undef DEBUG
   20.40 +
   20.41 +#ifdef DEBUG
   20.42 +#define DBG(fmt...) printk(KERN_EMERG fmt)
   20.43 +#else
   20.44 +#define DBG(fmt...)
   20.45 +#endif
   20.46 +
   20.47 +#define NR_GRANT_FRAMES 4
   20.48 +
   20.49 +struct address_space xen_foreign_dummy_mapping;
   20.50 +
   20.51 +static ulong foreign_map_pfn;
   20.52 +static ulong foreign_map_pgs;
   20.53 +static unsigned long *foreign_map_bitmap;
   20.54 +
   20.55 +
   20.56 +/* hijack _mapcount */
   20.57 +static inline int gnt_mapcount(struct page *page)
   20.58 +{
   20.59 +	return atomic_read(&(page)->_mapcount) + 1;
   20.60 +}
   20.61 +
   20.62 +static inline int gnt_map(struct page *page)
   20.63 +{
   20.64 +	/* return true is transition from -1 to 0 */
   20.65 +	return atomic_inc_and_test(&page->_mapcount);
   20.66 +}
   20.67 +
   20.68 +static inline int gnt_unmap(struct page *page)
   20.69 +{
   20.70 +	int val;
   20.71 +
   20.72 +	val = atomic_dec_return(&page->_mapcount);
   20.73 +	if (val < -1) {
   20.74 +		atomic_inc(&page->_mapcount);
   20.75 +		printk(KERN_EMERG "%s: %d\n", __func__, val);
   20.76 +	}
   20.77 +
   20.78 +	return (val == -1);
   20.79 +}
   20.80 +
   20.81 +
   20.82 +static long map_to_linear(ulong paddr)
   20.83 +{
   20.84 +	unsigned long vaddr;
   20.85 +	int psize;
   20.86 +	unsigned long mode;
   20.87 +	int slot;
   20.88 +	uint shift;
   20.89 +	unsigned long tmp_mode;
   20.90 +
   20.91 +	psize = MMU_PAGE_4K;
   20.92 +	shift = mmu_psize_defs[psize].shift;
   20.93 +	mode = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
   20.94 +	vaddr = (ulong)__va(paddr);
   20.95 +
   20.96 +	{
   20.97 +		unsigned long vpn, hash, hpteg;
   20.98 +		unsigned long vsid = get_kernel_vsid(vaddr);
   20.99 +		unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff);
  20.100 +
  20.101 +		vpn = va >> shift;
  20.102 +		tmp_mode = mode;
  20.103 +		
  20.104 +		/* Make non-kernel text non-executable */
  20.105 +		if (!in_kernel_text(vaddr))
  20.106 +			tmp_mode = mode | HPTE_R_N;
  20.107 +
  20.108 +		hash = hpt_hash(va, shift);
  20.109 +		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
  20.110 +
  20.111 +		BUG_ON(!ppc_md.hpte_insert);
  20.112 +		slot = ppc_md.hpte_insert(hpteg, va, paddr,
  20.113 +					  tmp_mode, HPTE_V_BOLTED, psize);
  20.114 +		if (slot < 0)
  20.115 +			printk(KERN_EMERG
  20.116 +			       "%s: no more bolted entries "
  20.117 +			       "HTAB[0x%lx]: 0x%lx\n",
  20.118 +			       __func__, hpteg, paddr);
  20.119 +	}
  20.120 +	return slot;
  20.121 +}
  20.122 +
  20.123 +static unsigned long get_hpte_vsid(ulong slot)
  20.124 +{
  20.125 + 	unsigned long dword0;
  20.126 +	unsigned long lpar_rc;
  20.127 +	unsigned long dummy_word1;
  20.128 +	unsigned long flags;
  20.129 +
  20.130 +	/* Read 1 pte at a time                        */
  20.131 +	/* Do not need RPN to logical page translation */
  20.132 +	/* No cross CEC PFT access                     */
  20.133 +	flags = 0;
  20.134 +
  20.135 +	lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
  20.136 +
  20.137 +	BUG_ON(lpar_rc != H_SUCCESS);
  20.138 +
  20.139 +	return dword0;
  20.140 +}
  20.141 +
  20.142 +static long find_hpte_slot(unsigned long va, int psize)
  20.143 +{
  20.144 +	unsigned long hash;
  20.145 +	unsigned long i, j;
  20.146 +	long slot;
  20.147 +	unsigned long want_v, hpte_v;
  20.148 +
  20.149 +	hash = hpt_hash(va, mmu_psize_defs[psize].shift);
  20.150 +	want_v = hpte_encode_v(va, psize);
  20.151 +
  20.152 +	for (j = 0; j < 2; j++) {
  20.153 +		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
  20.154 +		for (i = 0; i < HPTES_PER_GROUP; i++) {
  20.155 +			hpte_v = get_hpte_vsid(slot);
  20.156 +
  20.157 +			if (HPTE_V_COMPARE(hpte_v, want_v)
  20.158 +			    && (hpte_v & HPTE_V_VALID)
  20.159 +			    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
  20.160 +				/* HPTE matches */
  20.161 +				if (j)
  20.162 +					slot = -slot;
  20.163 +				return slot;
  20.164 +			}
  20.165 +			++slot;
  20.166 +		}
  20.167 +		hash = ~hash;
  20.168 +	}
  20.169 +
  20.170 +	return -1;
  20.171 +} 
  20.172 +
  20.173 +static long find_map_slot(ulong ea)
  20.174 +{
  20.175 +	int psize = MMU_PAGE_4K;
  20.176 +	ulong vsid;
  20.177 +	ulong va;
  20.178 +
  20.179 +	vsid = get_kernel_vsid(ea);
  20.180 +	va = (vsid << 28) | (ea & 0x0fffffff);
  20.181 +	
  20.182 +	return find_hpte_slot(va, psize);
  20.183 +}
  20.184 +
  20.185 +
  20.186 +static void gnttab_pre_unmap_grant_ref(
  20.187 +	struct gnttab_unmap_grant_ref *unmap, int count)
  20.188 +{
  20.189 +	long slot;
  20.190 +	int i;
  20.191 +	ulong ea;
  20.192 +	unsigned long dummy1, dummy2;
  20.193 +	ulong flags;
  20.194 +
  20.195 +	/* paranoia */
  20.196 +	local_irq_save(flags);
  20.197 +
  20.198 +	for (i = 0 ; i < count; i++) {
  20.199 +		struct page *page;
  20.200 +
  20.201 +		ea = (ulong)__va(unmap[i].host_addr);
  20.202 +		page = virt_to_page(ea);
  20.203 +		
  20.204 +		if (!gnt_unmap(page)) {
  20.205 +			DBG("%s[0x%x]: skip: 0x%lx, mapcount 0x%x\n",
  20.206 +			    __func__, i, ea, gnt_mapcount(page));
  20.207 +			continue;
  20.208 +		}
  20.209 +		slot = find_map_slot(ea);
  20.210 +		if (slot < 0) {
  20.211 +			printk(KERN_EMERG "%s: PTE not found: 0x%lx\n",
  20.212 +			       __func__, ea);
  20.213 +			continue;
  20.214 +		}
  20.215 +
  20.216 +		DBG("%s[0x%x]: 0x%lx: mapcount: 0x%x\n",
  20.217 +		    __func__, i, ea, gnt_mapcount(page));
  20.218 +		plpar_pte_remove(0, slot, 0, &dummy1, &dummy2);
  20.219 +	}
  20.220 +	local_irq_restore(flags);
  20.221 +}
  20.222 +
  20.223 +static void gnttab_post_map_grant_ref(
  20.224 +	struct gnttab_map_grant_ref *map, int count)
  20.225 +{
  20.226 +	int i;
  20.227 +	long slot;
  20.228 +	ulong flags;
  20.229 +
  20.230 +	/* paranoia */
  20.231 +	local_irq_save(flags);
  20.232 +
  20.233 +	for (i = 0 ; i < count; i++) {
  20.234 +		ulong pa = map[i].host_addr;
  20.235 +		struct page *page;
  20.236 +
  20.237 +		if (map[i].status != GNTST_okay) {
  20.238 +			printk(KERN_EMERG "%s: status, skip\n", __func__);
  20.239 +			continue;
  20.240 +		}
  20.241 +
  20.242 +		BUG_ON(pa < (foreign_map_pfn << PAGE_SHIFT));
  20.243 +		BUG_ON(pa >= (foreign_map_pfn << PAGE_SHIFT) + 
  20.244 +		       (foreign_map_pgs << PAGE_SHIFT));
  20.245 +
  20.246 +		page = virt_to_page(__va(pa));
  20.247 +
  20.248 +		if (gnt_map(page)) {
  20.249 +#ifdef DEBUG			
  20.250 +			/* we need to get smarted than this */
  20.251 +			slot = find_map_slot((ulong)__va(pa));
  20.252 +			if (slot >= 0) {
  20.253 +				DBG("%s: redundant 0x%lx\n", __func__, pa);
  20.254 +				continue;
  20.255 +			}
  20.256 +#endif
  20.257 +			slot = map_to_linear(pa);
  20.258 +			DBG("%s[0x%x]: 0x%lx, mapcount:0x%x\n",
  20.259 +			    __func__, i, pa, gnt_mapcount(page));
  20.260 +
  20.261 +		} else {
  20.262 +			DBG("%s[0x%x] skip 0x%lx, mapcount:0x%x\n",
  20.263 +			    __func__, i, pa, gnt_mapcount(page));
  20.264 +		}
  20.265 +	}
  20.266 +	local_irq_restore(flags);
  20.267 +}
  20.268 +
  20.269 +int HYPERVISOR_grant_table_op(unsigned int cmd, void *op, unsigned int count)
  20.270 +{
  20.271 +	void *desc;
  20.272 +	void *frame_list = NULL;
  20.273 +	int argsize;
  20.274 +	int ret = -ENOMEM;
  20.275 +
  20.276 +	switch (cmd) {
  20.277 +	case GNTTABOP_map_grant_ref:
  20.278 +		argsize = sizeof(struct gnttab_map_grant_ref);
  20.279 +		break;
  20.280 +	case GNTTABOP_unmap_grant_ref:
  20.281 +		gnttab_pre_unmap_grant_ref(op, count);
  20.282 +		argsize = sizeof(struct gnttab_unmap_grant_ref);
  20.283 +		break;
  20.284 +	case GNTTABOP_setup_table: {
  20.285 +		struct gnttab_setup_table setup;
  20.286 +
  20.287 +		memcpy(&setup, op, sizeof(setup));
  20.288 +		argsize = sizeof(setup);
  20.289 +
  20.290 +		frame_list = xencomm_map(
  20.291 +			xen_guest_handle(setup.frame_list),
  20.292 +			(sizeof(*xen_guest_handle(setup.frame_list)) 
  20.293 +			* setup.nr_frames));
  20.294 +
  20.295 +		if (frame_list == NULL)
  20.296 +			return -ENOMEM;
  20.297 +
  20.298 +		set_xen_guest_handle(setup.frame_list, frame_list);
  20.299 +		memcpy(op, &setup, sizeof(setup));
  20.300 +		}
  20.301 +		break;
  20.302 +	case GNTTABOP_dump_table:
  20.303 +		argsize = sizeof(struct gnttab_dump_table);
  20.304 +		break;
  20.305 +	case GNTTABOP_transfer:
  20.306 +		BUG();
  20.307 +		argsize = sizeof(struct gnttab_transfer);
  20.308 +		break;
  20.309 +	case GNTTABOP_copy:
  20.310 +		argsize = sizeof(struct gnttab_transfer);
  20.311 +		break;
  20.312 +	case GNTTABOP_query_size:
  20.313 +		argsize = sizeof(struct gnttab_query_size);
  20.314 +		break;
  20.315 +	default:
  20.316 +		printk(KERN_EMERG "%s: unknown grant table op %d\n",
  20.317 +		       __func__, cmd);
  20.318 +		return -ENOSYS;
  20.319 +	}
  20.320 +
  20.321 +	desc = xencomm_map_no_alloc(op, argsize);
  20.322 +	if (desc) {
  20.323 +		ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_grant_table_op),
  20.324 +					 cmd, desc, count);
  20.325 +		if (!ret && cmd == GNTTABOP_map_grant_ref)
  20.326 +			gnttab_post_map_grant_ref(op, count);
  20.327 +		xencomm_free(desc);
  20.328 +	}
  20.329 +	xencomm_free(frame_list);
  20.330 +
  20.331 +	return ret;
  20.332 +}
  20.333 +EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
  20.334 +
  20.335 +static ulong find_grant_maps(void)
  20.336 +{
  20.337 +	struct device_node *xen;
  20.338 +	u64 *gm;
  20.339 +	u64 _gm[2];
  20.340 +	u64 expect;
  20.341 +
  20.342 +	/* This value is currently hardcoded into the SLB logic that
  20.343 +	 * it written in assempler, See
  20.344 +	 * slb_miss_kernel_load_xen_linear for more information.
  20.345 +	 * Anything else and we can not run. */
  20.346 +	expect = 34 - PAGE_SHIFT;
  20.347 +
  20.348 +	xen = of_find_node_by_path("/xen");
  20.349 +
  20.350 +	/* 
  20.351 +	 * The foreign is 2x2 Cells.
  20.352 +	 * The first entry is log2 of the base page frame.
  20.353 +	 * The second is the number of pages
  20.354 +	 */
  20.355 +	gm = (u64 *)get_property(xen, "foreign-map", NULL);
  20.356 +	if (gm == NULL) {
  20.357 +		if (!is_initial_xendomain()) {
  20.358 +			printk("OF: /xen/foreign-map not present\n");
  20.359 +			_gm[0] = expect;
  20.360 +			_gm[1] = 2048;
  20.361 +			gm = _gm;
  20.362 +		} else
  20.363 +			panic("OF: /xen/foreign-map must be present\n");
  20.364 +	}
  20.365 +
  20.366 +	if (gm[0] != expect)
  20.367 +		panic("foreign-map is 0x%lx, expect 0x%lx\n",
  20.368 +		      gm[0], expect);
  20.369 +
  20.370 +	foreign_map_pfn = 1UL << gm[0];
  20.371 +	return gm[1];
  20.372 +}
  20.373 +
  20.374 +static void setup_foreign_segment(void)
  20.375 +{
  20.376 +	extern int *slb_miss_kernel_load_xen_nop;
  20.377 +	ulong iaddr = (ulong)slb_miss_kernel_load_xen_nop;
  20.378 +
  20.379 +	/* By default Linux will branch around this logic we replace
  20.380 +	 * the branch with a NOP to turn the logic on */
  20.381 +	*slb_miss_kernel_load_xen_nop = 0x60000000;
  20.382 +	flush_icache_range(iaddr, iaddr + 4);
  20.383 +}
  20.384 +
  20.385 +struct page *alloc_foreign_page(void)
  20.386 +{
  20.387 +	ulong bit;
  20.388 +	do {
  20.389 +		bit = find_first_zero_bit(foreign_map_bitmap,
  20.390 +					  foreign_map_pgs);
  20.391 +		if (bit >= foreign_map_pgs)
  20.392 +			return NULL;
  20.393 +	} while (test_and_set_bit(bit, foreign_map_bitmap) == 1);
  20.394 +
  20.395 +	return pfn_to_page(foreign_map_pfn + bit);
  20.396 +}
  20.397 +
  20.398 +void free_foreign_page(struct page *page)
  20.399 +{
  20.400 +	ulong bit = page_to_pfn(page) - foreign_map_pfn;
  20.401 +
  20.402 +	BUG_ON(bit >= foreign_map_pgs);
  20.403 +	BUG_ON(!test_bit(bit, foreign_map_bitmap));
  20.404 +
  20.405 +	clear_bit(bit, foreign_map_bitmap);
  20.406 +}
  20.407 +
  20.408 +static void setup_grant_area(void)
  20.409 +{
  20.410 +	ulong pgs;
  20.411 +	int err;
  20.412 +	struct zone *zone;
  20.413 +	struct pglist_data *pgdata;
  20.414 +	int nid;
  20.415 +
  20.416 +	pgs = find_grant_maps();
  20.417 +	setup_foreign_segment();
  20.418 +
  20.419 +	printk("%s: Xen VIO will use a foreign address space of 0x%lx pages\n",
  20.420 +	       __func__, pgs);
  20.421 +
  20.422 +	/* add pages to the zone */
  20.423 +	nid = 0;
  20.424 +	pgdata = NODE_DATA(nid);
  20.425 +	zone = pgdata->node_zones;
  20.426 +
  20.427 +	err = __add_pages(zone, foreign_map_pfn, pgs);
  20.428 +
  20.429 +	if (err < 0) {
  20.430 +		printk(KERN_EMERG "%s: add_pages(0x%lx, 0x%lx) = %d\n",
  20.431 +		       __func__, foreign_map_pfn, pgs, err);
  20.432 +		BUG();
  20.433 +	}
  20.434 +
  20.435 +	/* create a bitmap to manage these pages */
  20.436 +	foreign_map_bitmap = kmalloc(BITS_TO_LONGS(pgs) * sizeof(long),
  20.437 +				     GFP_KERNEL);
  20.438 +	if (foreign_map_bitmap == NULL) {
  20.439 +		printk(KERN_EMERG 
  20.440 +		       "%s: could not allocate foreign_map_bitmap to "
  20.441 +		       "manage 0x%lx foreign pages\n", __func__, pgs);
  20.442 +		BUG();
  20.443 +	}
  20.444 +	/* I'm paranoid so make sure we assign the top bits so we
  20.445 +	 * don't give them away */
  20.446 +	bitmap_fill(&foreign_map_bitmap[BITS_TO_LONGS(pgs) - 1],
  20.447 +		    BITS_PER_LONG);
  20.448 +	/* now clear all the real bits */
  20.449 +	bitmap_zero(foreign_map_bitmap, pgs);
  20.450 +
  20.451 +	foreign_map_pgs = pgs;
  20.452 +}
  20.453 +
  20.454 +void *arch_gnttab_alloc_shared(unsigned long *frames)
  20.455 +{
  20.456 +	void *shared;
  20.457 +	ulong pa = frames[0] << PAGE_SHIFT;
  20.458 +	static int resume;
  20.459 +
  20.460 +	shared = ioremap(pa, PAGE_SIZE * NR_GRANT_FRAMES);
  20.461 +	BUG_ON(shared == NULL);
  20.462 +	printk("%s: grant table at %p\n", __func__, shared);
  20.463 +
  20.464 +	/* no need to do the rest of this if we are resuming */
  20.465 +	if (!resume)
  20.466 +		setup_grant_area();
  20.467 +
  20.468 +	resume = 1;
  20.469 +
  20.470 +	return shared;
  20.471 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/arch/powerpc/platforms/xen/hcall.c	Tue Jul 10 08:40:03 2007 -0600
    21.3 @@ -0,0 +1,749 @@
    21.4 +/*
    21.5 + * This program is free software; you can redistribute it and/or modify
    21.6 + * it under the terms of the GNU General Public License as published by
    21.7 + * the Free Software Foundation; either version 2 of the License, or
    21.8 + * (at your option) any later version.
    21.9 + *
   21.10 + * This program is distributed in the hope that it will be useful,
   21.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.13 + * GNU General Public License for more details.
   21.14 + *
   21.15 + * You should have received a copy of the GNU General Public License
   21.16 + * along with this program; if not, write to the Free Software
   21.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   21.18 + *
   21.19 + * Copyright (C) IBM Corp. 2006, 2007
   21.20 + *
   21.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   21.22 + */
   21.23 +
   21.24 +#include <linux/types.h>
   21.25 +#include <linux/errno.h>
   21.26 +#include <linux/kernel.h>
   21.27 +#include <linux/gfp.h>
   21.28 +#include <linux/module.h>
   21.29 +#include <xen/interface/xen.h>
   21.30 +#include <xen/interface/domctl.h>
   21.31 +#include <xen/interface/sysctl.h>
   21.32 +#include <xen/interface/platform.h>
   21.33 +#include <xen/interface/memory.h>
   21.34 +#include <xen/interface/xencomm.h>
   21.35 +#include <xen/interface/version.h>
   21.36 +#include <xen/interface/sched.h>
   21.37 +#include <xen/interface/event_channel.h>
   21.38 +#include <xen/interface/physdev.h>
   21.39 +#include <xen/interface/vcpu.h>
   21.40 +#include <xen/interface/kexec.h>
   21.41 +#include <xen/public/privcmd.h>
   21.42 +#include <asm/hypercall.h>
   21.43 +#include <asm/page.h>
   21.44 +#include <asm/uaccess.h>
   21.45 +#include <asm/hvcall.h>
   21.46 +#include "setup.h"
   21.47 +
   21.48 +/* Xencomm notes:
   21.49 + *
   21.50 + * For kernel memory, we assume that virtually contiguous pages are also
   21.51 + * physically contiguous. This allows us to avoid creating descriptors for
   21.52 + * kernel hypercalls, such as console and event channel operations.
   21.53 + *
   21.54 + * In general, we need a xencomm descriptor to cover the top-level data
   21.55 + * structure (e.g. the domctl op), plus another for every embedded pointer to
   21.56 + * another data structure (i.e. for every GUEST_HANDLE).
   21.57 + */
   21.58 +
   21.59 +int HYPERVISOR_console_io(int cmd, int count, char *str)
   21.60 +{
   21.61 +	void *desc;
   21.62 +	int rc;
   21.63 +
   21.64 +	desc = xencomm_map_no_alloc(str, count);
   21.65 +	if (desc == NULL)
   21.66 +		return -EINVAL;
   21.67 +
   21.68 +	rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io),
   21.69 +				  cmd, count, desc);
   21.70 +
   21.71 +	xencomm_free(desc);
   21.72 +
   21.73 +	return rc;
   21.74 +}
   21.75 +EXPORT_SYMBOL(HYPERVISOR_console_io);
   21.76 +
   21.77 +int HYPERVISOR_event_channel_op(int cmd, void *op)
   21.78 +{
   21.79 +	int rc;
   21.80 +
   21.81 +	void *desc = xencomm_map_no_alloc(op, sizeof(evtchn_op_t));
   21.82 +	if (desc == NULL)
   21.83 +		return -EINVAL;
   21.84 +
   21.85 +	rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op),
   21.86 +				cmd, desc);
   21.87 +
   21.88 +	xencomm_free(desc);
   21.89 +
   21.90 +	return rc;
   21.91 +
   21.92 +}
   21.93 +EXPORT_SYMBOL(HYPERVISOR_event_channel_op);
   21.94 +
   21.95 +int HYPERVISOR_xen_version(int cmd, void *arg)
   21.96 +{
   21.97 +	void *desc;
   21.98 +	const unsigned long hcall = __HYPERVISOR_xen_version;
   21.99 +	int argsize;
  21.100 +	int rc;
  21.101 +
  21.102 +	switch (cmd) {
  21.103 +	case XENVER_version:
  21.104 +		/* do not actually pass an argument */
  21.105 +		return plpar_hcall_norets(XEN_MARK(hcall), cmd, 0);
  21.106 +	case XENVER_extraversion:
  21.107 +		argsize = sizeof(xen_extraversion_t);
  21.108 +		break;
  21.109 +	case XENVER_compile_info:
  21.110 +		argsize = sizeof(xen_compile_info_t);
  21.111 +		break;
  21.112 +	case XENVER_capabilities:
  21.113 +		argsize = sizeof(xen_capabilities_info_t);
  21.114 +		break;
  21.115 +	case XENVER_changeset:
  21.116 +		argsize = sizeof(xen_changeset_info_t);
  21.117 +		break;
  21.118 +	case XENVER_platform_parameters:
  21.119 +		argsize = sizeof(xen_platform_parameters_t);
  21.120 +		break;
  21.121 +	case XENVER_pagesize:
  21.122 +		if (arg == NULL)
  21.123 +			argsize = 0;
  21.124 +		else
  21.125 +			argsize = sizeof(void *);
  21.126 +		break;
  21.127 +	case XENVER_get_features:
  21.128 +		argsize = sizeof(xen_feature_info_t);
  21.129 +		break;
  21.130 +	default:
  21.131 +		printk(KERN_ERR "%s: unknown version cmd %d\n", __func__, cmd);
  21.132 +		return -ENOSYS;
  21.133 +	}
  21.134 +
  21.135 +	/* desc could be NULL in the case of XENVER_pagesize with NULL arg */
  21.136 +	desc = xencomm_map(arg, argsize);
  21.137 +
  21.138 +	rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, desc);
  21.139 +
  21.140 +	xencomm_free(desc);
  21.141 +
  21.142 +	return rc;
  21.143 +}
  21.144 +EXPORT_SYMBOL(HYPERVISOR_xen_version);
  21.145 +
  21.146 +
  21.147 +int HYPERVISOR_physdev_op(int cmd, void *op)
  21.148 +{
  21.149 +	void *desc = xencomm_map_no_alloc(op, sizeof(physdev_op_t));
  21.150 +	int rc;
  21.151 +
  21.152 +	if (desc == NULL)
  21.153 +		return -EINVAL;
  21.154 +
  21.155 +	rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op),
  21.156 +				cmd, desc);
  21.157 +
  21.158 +	xencomm_free(desc);
  21.159 +
  21.160 +	return rc;
  21.161 +}
  21.162 +EXPORT_SYMBOL(HYPERVISOR_physdev_op);
  21.163 +
  21.164 +int HYPERVISOR_sched_op(int cmd, void *arg)
  21.165 +{
  21.166 +	int argsize = 0;
  21.167 +	int rc = -EINVAL;
  21.168 +	void *desc;
  21.169 +	evtchn_port_t *ports = NULL;
  21.170 +
  21.171 +	switch (cmd) {
  21.172 +	case SCHEDOP_yield:
  21.173 +	case SCHEDOP_block:
  21.174 +		return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
  21.175 +					  cmd, 0);
  21.176 +		break;
  21.177 +
  21.178 +	case SCHEDOP_poll: {
  21.179 +		struct sched_poll sched_poll;
  21.180 +
  21.181 +		argsize = sizeof(struct sched_poll);
  21.182 +
  21.183 +		memcpy(&sched_poll, arg, sizeof(sched_poll));
  21.184 +
  21.185 +		ports = xencomm_map(
  21.186 +				xen_guest_handle(sched_poll.ports),
  21.187 +				(sizeof(evtchn_port_t) * sched_poll.nr_ports));
  21.188 +
  21.189 +		if (ports == NULL)
  21.190 +			return -ENOMEM;
  21.191 +
  21.192 +		set_xen_guest_handle(sched_poll.ports, ports);
  21.193 +		memcpy(arg, &sched_poll, sizeof(sched_poll));
  21.194 +
  21.195 +		}
  21.196 +		break;
  21.197 +	case SCHEDOP_shutdown:
  21.198 +		argsize = sizeof(struct sched_shutdown);
  21.199 +		break;
  21.200 +	case SCHEDOP_remote_shutdown:
  21.201 +		argsize = sizeof(struct sched_remote_shutdown);
  21.202 +		break;
  21.203 +	default:
  21.204 +		printk(KERN_ERR "%s: unknown sched op %d\n", __func__, cmd);
  21.205 +		return -ENOSYS;
  21.206 +	}
  21.207 +
  21.208 +	desc = xencomm_map_no_alloc(arg, argsize);
  21.209 +	if (desc) {
  21.210 +		rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
  21.211 +					cmd, desc);
  21.212 +		xencomm_free(desc);
  21.213 +	}
  21.214 +
  21.215 +	xencomm_free(ports);
  21.216 +
  21.217 +	return rc;
  21.218 +}
  21.219 +EXPORT_SYMBOL(HYPERVISOR_sched_op);
  21.220 +
  21.221 +int HYPERVISOR_suspend(unsigned long srec)
  21.222 +{
  21.223 +	int cmd = SCHEDOP_shutdown;
  21.224 +	struct sched_shutdown sched_shutdown = {
  21.225 +		.reason = SHUTDOWN_suspend,
  21.226 +	};
  21.227 +	void *desc;
  21.228 +
  21.229 +	desc = xencomm_map_no_alloc(&sched_shutdown, sizeof(struct sched_shutdown));
  21.230 +
  21.231 +	return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
  21.232 +				  cmd, desc, srec);
  21.233 +}
  21.234 +EXPORT_SYMBOL(HYPERVISOR_suspend);
  21.235 +
  21.236 +int HYPERVISOR_kexec_op(unsigned long op, void *args)
  21.237 +{
  21.238 +	unsigned long argsize;
  21.239 +	void *desc;
  21.240 +
  21.241 +	switch (op) {
  21.242 +		case KEXEC_CMD_kexec_get_range:
  21.243 +			argsize = sizeof(struct xen_kexec_range);
  21.244 +			break;
  21.245 +		case KEXEC_CMD_kexec_load:
  21.246 +			argsize = sizeof(struct xen_kexec_load);
  21.247 +			break;
  21.248 +		case KEXEC_CMD_kexec_unload:
  21.249 +			argsize = sizeof(struct xen_kexec_load);
  21.250 +			break;
  21.251 +		case KEXEC_CMD_kexec:
  21.252 +			argsize = sizeof(struct xen_kexec_exec);
  21.253 +			break;
  21.254 +		default:
  21.255 +			return -ENOSYS;
  21.256 +	}
  21.257 +	desc = xencomm_map_no_alloc(args, argsize);
  21.258 +
  21.259 +	return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_kexec_op),
  21.260 +				  op, desc);
  21.261 +}
  21.262 +EXPORT_SYMBOL(HYPERVISOR_kexec_op);
  21.263 +
  21.264 +int HYPERVISOR_poll(
  21.265 +	evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
  21.266 +{
  21.267 +	struct sched_poll sched_poll = {
  21.268 +		.nr_ports = nr_ports,
  21.269 +		.timeout = jiffies_to_ns(timeout)
  21.270 +	};
  21.271 +	set_xen_guest_handle(sched_poll.ports, ports);
  21.272 +
  21.273 +	return HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
  21.274 +}
  21.275 +EXPORT_SYMBOL(HYPERVISOR_poll);
  21.276 +
  21.277 +typedef ulong (mf_t)(ulong arg0, ...);
  21.278 +
  21.279 +static mf_t *multicall_funcs[] = {
  21.280 +	[__HYPERVISOR_grant_table_op] = (mf_t *)HYPERVISOR_grant_table_op,
  21.281 +};
  21.282 +
  21.283 +int HYPERVISOR_multicall(void *call_list, int nr_calls)
  21.284 +{
  21.285 +	/* we blow out the multicall because the xencomm stuff is jsut
  21.286 +	 * too tricky */
  21.287 +	multicall_entry_t *mcl = (multicall_entry_t *)call_list;
  21.288 +	multicall_entry_t *c;
  21.289 +	int i;
  21.290 +	mf_t *mf;
  21.291 +	int res;
  21.292 +	ulong flags;
  21.293 +
  21.294 +	/* let make sure all the calls are supported */
  21.295 +	for (i = 0; i < nr_calls; i++) {
  21.296 +		mf = multicall_funcs[mcl[i].op];
  21.297 +		BUG_ON(mf == NULL);
  21.298 +	}
  21.299 +	/* disable interrupts until we are done all calls */
  21.300 +	local_irq_save(flags);
  21.301 +	for (i = 0; i < nr_calls; i++) {
  21.302 +		/* lookup supported multicalls */
  21.303 +		c = &mcl[i];
  21.304 +		mf = multicall_funcs[c->op];
  21.305 +		res = mf(c->args[0], c->args[1], c->args[2],
  21.306 +			 c->args[3], c->args[4], c->args[5]);
  21.307 +		c->result = res;
  21.308 +	}
  21.309 +	local_irq_restore(flags);
  21.310 +	return 0;
  21.311 +}
  21.312 +EXPORT_SYMBOL(HYPERVISOR_multicall);
  21.313 +
  21.314 +
  21.315 +/* privcmd operations: */
  21.316 +
  21.317 +static int xenppc_privcmd_domctl(privcmd_hypercall_t *hypercall)
  21.318 +{
  21.319 +	xen_domctl_t kern_op;
  21.320 +	xen_domctl_t __user *user_op = (xen_domctl_t __user *)hypercall->arg[0];
  21.321 +	void *op_desc;
  21.322 +	void *desc = NULL;
  21.323 +	int ret = 0;
  21.324 +
  21.325 +	if (copy_from_user(&kern_op, user_op, sizeof(xen_domctl_t)))
  21.326 +		return -EFAULT;
  21.327 +
  21.328 +	if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION) {
  21.329 +		printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
  21.330 +				kern_op.interface_version, XEN_DOMCTL_INTERFACE_VERSION);
  21.331 +		return -EACCES;
  21.332 +	}
  21.333 +
  21.334 +	op_desc = xencomm_map(&kern_op, sizeof(xen_domctl_t));
  21.335 +	if (op_desc == NULL)
  21.336 +		return -ENOMEM;
  21.337 +
  21.338 +	switch (kern_op.cmd) {
  21.339 +	case XEN_DOMCTL_createdomain:
  21.340 +	case XEN_DOMCTL_destroydomain:
  21.341 +	case XEN_DOMCTL_pausedomain:
  21.342 +	case XEN_DOMCTL_unpausedomain:
  21.343 +	case XEN_DOMCTL_getdomaininfo:
  21.344 +		break;
  21.345 +	case XEN_DOMCTL_getmemlist:
  21.346 +		desc = xencomm_map(
  21.347 +			xen_guest_handle(kern_op.u.getmemlist.buffer),
  21.348 +			kern_op.u.getmemlist.max_pfns * sizeof(unsigned long));
  21.349 +
  21.350 +		if (desc == NULL)
  21.351 +			ret = -ENOMEM;
  21.352 +
  21.353 +		set_xen_guest_handle(kern_op.u.getmemlist.buffer,
  21.354 +				     desc);
  21.355 +		break;
  21.356 +	case XEN_DOMCTL_getpageframeinfo:
  21.357 +		break;
  21.358 +	case XEN_DOMCTL_getpageframeinfo2:
  21.359 +		desc = xencomm_map(
  21.360 +			xen_guest_handle(kern_op.u.getpageframeinfo2.array),
  21.361 +			kern_op.u.getpageframeinfo2.num);
  21.362 +
  21.363 +		if (desc == NULL)
  21.364 +			ret = -ENOMEM;
  21.365 +
  21.366 +		set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
  21.367 +				     desc);
  21.368 +		break;
  21.369 +	case XEN_DOMCTL_shadow_op:
  21.370 +
  21.371 +		if (xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap))
  21.372 +		{
  21.373 +			desc = xencomm_map(
  21.374 +				xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
  21.375 +				kern_op.u.shadow_op.pages * sizeof(unsigned long));
  21.376 +
  21.377 +			if (desc == NULL)
  21.378 +				ret = -ENOMEM;
  21.379 +
  21.380 +			set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
  21.381 +				    	 desc);
  21.382 +		}
  21.383 +		break;
  21.384 +	case XEN_DOMCTL_max_mem:
  21.385 +		break;
  21.386 +	case XEN_DOMCTL_setvcpucontext:
  21.387 +	case XEN_DOMCTL_getvcpucontext:
  21.388 +		desc = xencomm_map(
  21.389 +			xen_guest_handle(kern_op.u.vcpucontext.ctxt),
  21.390 +			sizeof(vcpu_guest_context_t));
  21.391 +
  21.392 +		if (desc == NULL)
  21.393 +			ret = -ENOMEM;
  21.394 +
  21.395 +		set_xen_guest_handle(kern_op.u.vcpucontext.ctxt,
  21.396 +				     desc);
  21.397 +		break;
  21.398 +	case XEN_DOMCTL_getvcpuinfo:
  21.399 +		break;
  21.400 +	case XEN_DOMCTL_setvcpuaffinity:
  21.401 +	case XEN_DOMCTL_getvcpuaffinity:
  21.402 +		desc = xencomm_map(
  21.403 +			xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
  21.404 +			(kern_op.u.vcpuaffinity.cpumap.nr_cpus + 7) / 8);
  21.405 +
  21.406 +		if (desc == NULL)
  21.407 +			ret = -ENOMEM;
  21.408 +
  21.409 +		set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
  21.410 +				     desc);
  21.411 +		break;
  21.412 +	case XEN_DOMCTL_max_vcpus:
  21.413 +	case XEN_DOMCTL_scheduler_op:
  21.414 +	case XEN_DOMCTL_setdomainhandle:
  21.415 +	case XEN_DOMCTL_setdebugging:
  21.416 +	case XEN_DOMCTL_irq_permission:
  21.417 +	case XEN_DOMCTL_iomem_permission:
  21.418 +	case XEN_DOMCTL_ioport_permission:
  21.419 +	case XEN_DOMCTL_hypercall_init:
  21.420 +	case XEN_DOMCTL_arch_setup:
  21.421 +	case XEN_DOMCTL_settimeoffset:
  21.422 +	case XEN_DOMCTL_real_mode_area:
  21.423 +		break;
  21.424 +	default:
  21.425 +		printk(KERN_ERR "%s: unknown domctl cmd %d\n", __func__, kern_op.cmd);
  21.426 +		return -ENOSYS;
  21.427 +	}
  21.428 +
  21.429 +	if (ret)
  21.430 +		goto out; /* error mapping the nested pointer */
  21.431 +
  21.432 +	ret = plpar_hcall_norets(XEN_MARK(hypercall->op),op_desc);
  21.433 +
  21.434 +	if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
  21.435 +		ret = -EFAULT;
  21.436 +
  21.437 +out:
  21.438 +	xencomm_free(desc);
  21.439 +	xencomm_free(op_desc);
  21.440 +	return ret;
  21.441 +}
  21.442 +
  21.443 +static int xenppc_privcmd_sysctl(privcmd_hypercall_t *hypercall)
  21.444 +{
  21.445 +	xen_sysctl_t kern_op;
  21.446 +	xen_sysctl_t __user *user_op = (xen_sysctl_t __user *)hypercall->arg[0];
  21.447 +	struct xencomm_desc *op_desc;
  21.448 +	void *desc = NULL;
  21.449 +	int ret = 0;
  21.450 +
  21.451 +	if (copy_from_user(&kern_op, user_op, sizeof(xen_sysctl_t)))
  21.452 +		return -EFAULT;
  21.453 +
  21.454 +	if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION) {
  21.455 +		printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
  21.456 +				kern_op.interface_version, XEN_SYSCTL_INTERFACE_VERSION);
  21.457 +		return -EACCES;
  21.458 +	}
  21.459 +
  21.460 +	op_desc = xencomm_map(&kern_op, sizeof(xen_sysctl_t));
  21.461 +
  21.462 +	if (op_desc == NULL)
  21.463 +		return -ENOMEM;
  21.464 +
  21.465 +	switch (kern_op.cmd) {
  21.466 +	case XEN_SYSCTL_readconsole:
  21.467 +		desc = xencomm_map(
  21.468 +			xen_guest_handle(kern_op.u.readconsole.buffer),
  21.469 +			kern_op.u.readconsole.count);
  21.470 +
  21.471 +		if (desc == NULL)
  21.472 +			ret = -ENOMEM;
  21.473 +
  21.474 +		set_xen_guest_handle(kern_op.u.readconsole.buffer,
  21.475 +				     desc);
  21.476 +		break;
  21.477 +	case XEN_SYSCTL_tbuf_op:
  21.478 +	case XEN_SYSCTL_physinfo:
  21.479 +	case XEN_SYSCTL_sched_id:
  21.480 +		break;
  21.481 +	case XEN_SYSCTL_perfc_op:
  21.482 +		/* XXX this requires *two* embedded xencomm mappings (desc and val),
  21.483 +		 * and I don't feel like it right now. */
  21.484 +		printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
  21.485 +		return -ENOSYS;
  21.486 +	case XEN_SYSCTL_getdomaininfolist:
  21.487 +		desc = xencomm_map(
  21.488 +			xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
  21.489 +			kern_op.u.getdomaininfolist.max_domains *
  21.490 +					sizeof(xen_domctl_getdomaininfo_t));
  21.491 +
  21.492 +		if (desc == NULL)
  21.493 +			ret = -ENOMEM;
  21.494 +
  21.495 +		set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
  21.496 +				     desc);
  21.497 +		break;
  21.498 +	default:
  21.499 +		printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
  21.500 +		return -ENOSYS;
  21.501 +	}
  21.502 +
  21.503 +	if (ret)
  21.504 +		goto out; /* error mapping the nested pointer */
  21.505 +
  21.506 +	ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
  21.507 +
  21.508 +	if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
  21.509 +		ret = -EFAULT;
  21.510 +
  21.511 +out:
  21.512 +	xencomm_free(desc);
  21.513 +	xencomm_free(op_desc);
  21.514 +	return ret;
  21.515 +}
  21.516 +
  21.517 +static int xenppc_privcmd_platform_op(privcmd_hypercall_t *hypercall)
  21.518 +{
  21.519 +	xen_platform_op_t kern_op;
  21.520 +	xen_platform_op_t __user *user_op =
  21.521 +			(xen_platform_op_t __user *)hypercall->arg[0];
  21.522 +	void *op_desc;
  21.523 +	void *desc = NULL;
  21.524 +	int ret = 0;
  21.525 +
  21.526 +	if (copy_from_user(&kern_op, user_op, sizeof(xen_platform_op_t)))
  21.527 +		return -EFAULT;
  21.528 +
  21.529 +	if (kern_op.interface_version != XENPF_INTERFACE_VERSION) {
  21.530 +		printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
  21.531 +				kern_op.interface_version, XENPF_INTERFACE_VERSION);
  21.532 +		return -EACCES;
  21.533 +	}
  21.534 +
  21.535 +	op_desc = xencomm_map(&kern_op, sizeof(xen_platform_op_t));
  21.536 +
  21.537 +	if (op_desc == NULL)
  21.538 +		return -ENOMEM;
  21.539 +
  21.540 +	switch (kern_op.cmd) {
  21.541 +	case XENPF_settime:
  21.542 +	case XENPF_add_memtype:
  21.543 +	case XENPF_del_memtype:
  21.544 +	case XENPF_read_memtype:
  21.545 +	case XENPF_microcode_update:
  21.546 +	case XENPF_platform_quirk:
  21.547 +		break;
  21.548 +	default:
  21.549 +		printk(KERN_ERR "%s: unknown platform_op cmd %d\n", __func__,
  21.550 +				kern_op.cmd);
  21.551 +		return -ENOSYS;
  21.552 +	}
  21.553 +
  21.554 +	if (ret)
  21.555 +		goto out; /* error mapping the nested pointer */
  21.556 +
  21.557 +	ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
  21.558 +
  21.559 +	if (copy_to_user(user_op, &kern_op, sizeof(xen_platform_op_t)))
  21.560 +		ret = -EFAULT;
  21.561 +
  21.562 +out:
  21.563 +	xencomm_free(desc);
  21.564 +	xencomm_free(op_desc);
  21.565 +	return ret;
  21.566 +}
  21.567 +
  21.568 +int HYPERVISOR_memory_op(unsigned int cmd, void *arg)
  21.569 +{
  21.570 +	int ret;
  21.571 +	void *op_desc;
  21.572 +	xen_memory_reservation_t *mop;
  21.573 +
  21.574 +
  21.575 +	mop = (xen_memory_reservation_t *)arg;
  21.576 +
  21.577 +	op_desc = xencomm_map(mop, sizeof(xen_memory_reservation_t));
  21.578 +
  21.579 +	if (op_desc == NULL)
  21.580 +		return -ENOMEM;
  21.581 +
  21.582 +	switch (cmd) {
  21.583 +	case XENMEM_increase_reservation:
  21.584 +	case XENMEM_decrease_reservation:
  21.585 +	case XENMEM_populate_physmap: {
  21.586 +		void *desc = NULL;
  21.587 +
  21.588 +		if (xen_guest_handle(mop->extent_start)) {
  21.589 +			desc = xencomm_map(
  21.590 +				xen_guest_handle(mop->extent_start),
  21.591 +				mop->nr_extents *
  21.592 +				sizeof(*xen_guest_handle(mop->extent_start)));
  21.593 +
  21.594 +			if (desc == NULL) {
  21.595 +				ret = -ENOMEM;
  21.596 +				goto out;
  21.597 +			}
  21.598 +
  21.599 +			set_xen_guest_handle(mop->extent_start,
  21.600 +					     desc);
  21.601 +		}
  21.602 +
  21.603 +		ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_memory_op),
  21.604 +					cmd, op_desc);
  21.605 +
  21.606 +		xencomm_free(desc);
  21.607 +		}
  21.608 +		break;
  21.609 +
  21.610 +	case XENMEM_maximum_ram_page:
  21.611 +		/* arg is NULL so we can call thru here */
  21.612 +		ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_memory_op),
  21.613 +					cmd, NULL);
  21.614 +		break;
  21.615 +	default:
  21.616 +		printk(KERN_ERR "%s: unknown memory op %d\n", __func__, cmd);
  21.617 +		ret = -ENOSYS;
  21.618 +	}
  21.619 +
  21.620 +out:
  21.621 +	xencomm_free(op_desc);
  21.622 +	return ret;
  21.623 +}
  21.624 +EXPORT_SYMBOL(HYPERVISOR_memory_op);
  21.625 +
  21.626 +static int xenppc_privcmd_memory_op(privcmd_hypercall_t *hypercall)
  21.627 +{
  21.628 +	xen_memory_reservation_t kern_op;
  21.629 +	xen_memory_reservation_t __user *user_op;
  21.630 +	const unsigned long cmd = hypercall->arg[0];
  21.631 +	int ret = 0;
  21.632 +
  21.633 +	user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
  21.634 +	if (copy_from_user(&kern_op, user_op,
  21.635 +			   sizeof(xen_memory_reservation_t)))
  21.636 +		return -EFAULT;
  21.637 +
  21.638 +	ret = HYPERVISOR_memory_op(cmd, &kern_op);
  21.639 +	if (ret >= 0) {
  21.640 +		if (copy_to_user(user_op, &kern_op,
  21.641 +				 sizeof(xen_memory_reservation_t)))
  21.642 +			return -EFAULT;
  21.643 +	}
  21.644 +	return ret;
  21.645 +}
  21.646 +
  21.647 +static int xenppc_privcmd_version(privcmd_hypercall_t *hypercall)
  21.648 +{
  21.649 +	return HYPERVISOR_xen_version(hypercall->arg[0],
  21.650 +			(void *)hypercall->arg[1]);
  21.651 +}
  21.652 +
  21.653 +static int xenppc_privcmd_event_channel_op(privcmd_hypercall_t *hypercall)
  21.654 +{
  21.655 +	struct xencomm_desc *desc;
  21.656 +	unsigned int argsize;
  21.657 +	int ret;
  21.658 +
  21.659 +	switch (hypercall->arg[0]) {
  21.660 +	case EVTCHNOP_alloc_unbound:
  21.661 +		argsize = sizeof(evtchn_alloc_unbound_t);
  21.662 +		break;
  21.663 +
  21.664 +	case EVTCHNOP_status:
  21.665 +		argsize = sizeof(evtchn_status_t);
  21.666 +		break;
  21.667 +
  21.668 +	default:
  21.669 +		printk(KERN_ERR "%s: unknown EVTCHNOP (%ld)\n",
  21.670 +		       __func__, hypercall->arg[0]);
  21.671 +		return -EINVAL;
  21.672 +	}
  21.673 +
  21.674 +	desc = xencomm_map((void *)hypercall->arg[1], argsize);
  21.675 +
  21.676 +	if (desc == NULL)
  21.677 +		return -ENOMEM;
  21.678 +
  21.679 +	ret = plpar_hcall_norets(XEN_MARK(hypercall->op), hypercall->arg[0],
  21.680 +				desc);
  21.681 +
  21.682 +	xencomm_free(desc);
  21.683 +	return ret;
  21.684 +}
  21.685 +
  21.686 +/* The PowerPC hypervisor runs in a separate address space from Linux
  21.687 + * kernel/userspace, i.e. real mode. We must therefore translate userspace
  21.688 + * pointers to something the hypervisor can make sense of. */
  21.689 +int privcmd_hypercall(privcmd_hypercall_t *hypercall)
  21.690 +{
  21.691 +	switch (hypercall->op) {
  21.692 +	case __HYPERVISOR_domctl:
  21.693 +		return xenppc_privcmd_domctl(hypercall);
  21.694 +	case __HYPERVISOR_sysctl:
  21.695 +		return xenppc_privcmd_sysctl(hypercall);
  21.696 +	case __HYPERVISOR_platform_op:
  21.697 +		return xenppc_privcmd_platform_op(hypercall);
  21.698 +	case __HYPERVISOR_memory_op:
  21.699 +		return xenppc_privcmd_memory_op(hypercall);
  21.700 +	case __HYPERVISOR_xen_version:
  21.701 +		return xenppc_privcmd_version(hypercall);
  21.702 +	case __HYPERVISOR_event_channel_op:
  21.703 +		return xenppc_privcmd_event_channel_op(hypercall);
  21.704 +	default:
  21.705 +		printk(KERN_ERR "%s: unknown hcall (%ld)\n", __func__, hypercall->op);
  21.706 +		/* fallthru */
  21.707 +		/* below are the hcalls we know will fail and its ok */
  21.708 +	case __HYPERVISOR_acm_op:
  21.709 +		return plpar_hcall_norets(XEN_MARK(hypercall->op),
  21.710 +				hypercall->arg[0],
  21.711 +				hypercall->arg[1],
  21.712 +				hypercall->arg[2],
  21.713 +				hypercall->arg[3],
  21.714 +				hypercall->arg[4]);
  21.715 +	}
  21.716 +}
  21.717 +
  21.718 +int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
  21.719 +{
  21.720 +	int argsize;
  21.721 +	const unsigned long hcall = __HYPERVISOR_vcpu_op;
  21.722 +	void *desc;
  21.723 +	int rc;
  21.724 +
  21.725 +	switch (cmd) {
  21.726 +	case  VCPUOP_initialise:
  21.727 +		argsize = sizeof(vcpu_guest_context_t);
  21.728 +		break;
  21.729 +	case VCPUOP_up:
  21.730 +	case VCPUOP_down:
  21.731 +	case VCPUOP_is_up:
  21.732 +		return plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, 0);
  21.733 +
  21.734 +	case VCPUOP_get_runstate_info:
  21.735 +		argsize = sizeof (vcpu_runstate_info_t);
  21.736 +		break;
  21.737 +	default:
  21.738 +		printk(KERN_ERR "%s: unknown version cmd %d\n", __func__, cmd);
  21.739 +		return -ENOSYS;
  21.740 +	}
  21.741 +
  21.742 +	desc = xencomm_map_no_alloc(extra_args, argsize);
  21.743 +
  21.744 +	if (desc == NULL)
  21.745 +		return -EINVAL;
  21.746 +
  21.747 +	rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, desc);
  21.748 +
  21.749 +	xencomm_free(desc);
  21.750 +
  21.751 +	return rc;
  21.752 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/arch/powerpc/platforms/xen/reboot.c	Tue Jul 10 08:40:03 2007 -0600
    22.3 @@ -0,0 +1,53 @@
    22.4 +/*
    22.5 + * This program is free software; you can redistribute it and/or modify
    22.6 + * it under the terms of the GNU General Public License as published by
    22.7 + * the Free Software Foundation; either version 2 of the License, or
    22.8 + * (at your option) any later version.
    22.9 + *
   22.10 + * This program is distributed in the hope that it will be useful,
   22.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.13 + * GNU General Public License for more details.
   22.14 + *
   22.15 + * You should have received a copy of the GNU General Public License
   22.16 + * along with this program; if not, write to the Free Software
   22.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   22.18 + *
   22.19 + * Copyright (C) IBM Corp. 2006
   22.20 + *
   22.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   22.22 + */
   22.23 +
   22.24 +#include <linux/module.h>
   22.25 +#include <xen/interface/xen.h>
   22.26 +#include <xen/interface/io/console.h>
   22.27 +#include <xen/xencons.h>
   22.28 +#include <asm/hypervisor.h>
   22.29 +#include <asm/machdep.h>
   22.30 +
   22.31 +static void domain_machine_restart(char * __unused)
   22.32 +{
   22.33 +	/* We really want to get pending console data out before we die. */
   22.34 +	xencons_force_flush();
   22.35 +	HYPERVISOR_shutdown(SHUTDOWN_reboot);
   22.36 +}
   22.37 +
   22.38 +static void domain_machine_power_off(void)
   22.39 +{
   22.40 +	/* We really want to get pending console data out before we die. */
   22.41 +	xencons_force_flush();
   22.42 +	HYPERVISOR_shutdown(SHUTDOWN_poweroff);
   22.43 +}
   22.44 +
   22.45 +void xen_reboot_init(struct machdep_calls *md)
   22.46 +{
   22.47 +	if (md != NULL) {
   22.48 +		ppc_md.restart	 = md->restart;
   22.49 +		ppc_md.power_off = md->power_off;
   22.50 +		ppc_md.halt	 = md->halt;
   22.51 +	} else {
   22.52 +		ppc_md.restart	 = domain_machine_restart;
   22.53 +		ppc_md.power_off = domain_machine_power_off;
   22.54 +		ppc_md.halt	 = domain_machine_power_off;
   22.55 +	}
   22.56 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/arch/powerpc/platforms/xen/setup.c	Tue Jul 10 08:40:03 2007 -0600
    23.3 @@ -0,0 +1,324 @@
    23.4 +/*
    23.5 + * This program is free software; you can redistribute it and/or modify
    23.6 + * it under the terms of the GNU General Public License as published by
    23.7 + * the Free Software Foundation; either version 2 of the License, or
    23.8 + * (at your option) any later version.
    23.9 + *
   23.10 + * This program is distributed in the hope that it will be useful,
   23.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.13 + * GNU General Public License for more details.
   23.14 + *
   23.15 + * You should have received a copy of the GNU General Public License
   23.16 + * along with this program; if not, write to the Free Software
   23.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   23.18 + *
   23.19 + * Copyright (C) IBM Corp. 2006
   23.20 + *
   23.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   23.22 + */
   23.23 +
   23.24 +#define DEBUG
   23.25 +#define CONFIG_SHARE_MPIC
   23.26 +
   23.27 +#include <linux/module.h>
   23.28 +#include <linux/rwsem.h>
   23.29 +#include <linux/delay.h>
   23.30 +#include <linux/console.h>
   23.31 +#include <xen/interface/xen.h>
   23.32 +#include <xen/interface/sched.h>
   23.33 +#include <xen/evtchn.h>
   23.34 +#include <xen/features.h>
   23.35 +#include <xen/xencons.h>
   23.36 +#include <asm/udbg.h>
   23.37 +#include <asm/pgtable.h>
   23.38 +#include <asm/prom.h>
   23.39 +#include <asm/iommu.h>
   23.40 +#include <asm/mmu.h>
   23.41 +#include <asm/abs_addr.h>
   23.42 +#include <asm/machdep.h>
   23.43 +#include <asm/hypervisor.h>
   23.44 +#include <asm/time.h>
   23.45 +#include "setup.h"
   23.46 +
   23.47 +#ifdef DEBUG
   23.48 +#define DBG(fmt...) udbg_printf(fmt)
   23.49 +#else
   23.50 +#define DBG(fmt...)
   23.51 +#endif
   23.52 +
   23.53 +/* Apperently on other arches this could be used before its defined,
   23.54 + * this should not be the case in PPC */
   23.55 +shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)NULL;
   23.56 +EXPORT_SYMBOL(HYPERVISOR_shared_info);
   23.57 +
   23.58 +/* Raw start-of-day parameters from the hypervisor. */
   23.59 +static start_info_t xsi;
   23.60 +start_info_t *xen_start_info;
   23.61 +EXPORT_SYMBOL(xen_start_info);
   23.62 +
   23.63 +extern struct machdep_calls mach_maple_md;
   23.64 +extern void maple_pci_init(void);
   23.65 +
   23.66 +static unsigned long foreign_mfn_flag;
   23.67 +
   23.68 +/* Must be called with &vma->vm_mm->mmap_sem locked for write */
   23.69 +int direct_remap_pfn_range(struct vm_area_struct *vma,
   23.70 +		unsigned long address, 
   23.71 +		unsigned long mfn,
   23.72 +		unsigned long size, 
   23.73 +		pgprot_t prot,
   23.74 +		domid_t  domid)
   23.75 +{
   23.76 +	int rc;
   23.77 +
   23.78 +	/* Set the MFN flag to tell Xen that this is not a PFN. */
   23.79 +	printk("%s: mapping mfn 0x%lx (size 0x%lx) -> 0x%lx\n", __func__,
   23.80 +			mfn, size, mfn | foreign_mfn_flag);
   23.81 +	mfn = mfn | foreign_mfn_flag;
   23.82 +
   23.83 +	WARN_ON(!rwsem_is_locked(&vma->vm_mm->mmap_sem));
   23.84 +	rc = remap_pfn_range(vma, address, mfn, size, prot);
   23.85 +
   23.86 +	return rc;
   23.87 +}
   23.88 +
   23.89 +static void __init xen_fw_feature_init(void)
   23.90 +{
   23.91 +	DBG(" -> %s\n", __func__);
   23.92 +
   23.93 +	powerpc_firmware_features = 0;
   23.94 +
   23.95 +	powerpc_firmware_features |= FW_FEATURE_LPAR;
   23.96 +	powerpc_firmware_features |= FW_FEATURE_TCE | FW_FEATURE_DABR;
   23.97 +		
   23.98 +	printk(KERN_INFO "firmware_features = 0x%lx\n", 
   23.99 +			powerpc_firmware_features);
  23.100 +
  23.101 +	DBG(" <- %s\n", __func__);
  23.102 +}
  23.103 +
  23.104 +/* if these were global then I could get them from the pseries/setup.c */
  23.105 +static int pseries_set_dabr(unsigned long dabr)
  23.106 +{
  23.107 +	return plpar_hcall_norets(H_SET_DABR, dabr);
  23.108 +}
  23.109 +
  23.110 +static int pseries_set_xdabr(unsigned long dabr)
  23.111 +{
  23.112 +	/* We want to catch accesses from kernel and userspace */
  23.113 +	return plpar_hcall_norets(H_SET_XDABR, dabr,
  23.114 +			H_DABRX_KERNEL | H_DABRX_USER);
  23.115 +}
  23.116 +
  23.117 +/* 
  23.118 + * Early initialization.
  23.119 + */
  23.120 +static void __init xenppc_init_early(void)
  23.121 +{
  23.122 +	struct device_node *xen;
  23.123 +
  23.124 +	DBG(" -> %s\n", __func__);
  23.125 +
  23.126 +	xen = of_find_node_by_path("/xen");
  23.127 +
  23.128 +	xen_start_info = &xsi;
  23.129 +
  23.130 +	/* fill out start_info_t from devtree */
  23.131 +	if ((char *)get_property(xen, "privileged", NULL))
  23.132 +		xen_start_info->flags |= SIF_PRIVILEGED;
  23.133 +	if ((char *)get_property(xen, "initdomain", NULL))
  23.134 +		xen_start_info->flags |= SIF_INITDOMAIN;
  23.135 +	xen_start_info->shared_info = *((u64 *)get_property(xen, 
  23.136 +	   "shared-info", NULL));
  23.137 +
  23.138 +	/* only look for store and console for guest domains */
  23.139 +	if (xen_start_info->flags == 0) {
  23.140 +		struct device_node *console = of_find_node_by_path("/xen/console");
  23.141 +		struct device_node *store = of_find_node_by_path("/xen/store");
  23.142 +
  23.143 +		xen_start_info->store_mfn = (*((u64 *)get_property(store,
  23.144 +		   "reg", NULL))) >> PAGE_SHIFT;
  23.145 +		xen_start_info->store_evtchn = *((u32 *)get_property(store,
  23.146 +		   "interrupts", NULL));
  23.147 +		xen_start_info->console.domU.mfn = (*((u64 *)get_property(console,
  23.148 +		   "reg", NULL))) >> PAGE_SHIFT;
  23.149 +		xen_start_info->console.domU.evtchn = *((u32 *)get_property(console,
  23.150 +		   "interrupts", NULL));
  23.151 +	}
  23.152 +
  23.153 +	HYPERVISOR_shared_info = __va(xen_start_info->shared_info);
  23.154 +
  23.155 +	udbg_init_xen();
  23.156 +
  23.157 +	DBG("xen_start_info at %p\n", xen_start_info);
  23.158 +	DBG("    magic          %s\n", xen_start_info->magic);
  23.159 +	DBG("    flags          %x\n", xen_start_info->flags);
  23.160 +	DBG("    shared_info    %lx, %p\n",
  23.161 +	    xen_start_info->shared_info, HYPERVISOR_shared_info);
  23.162 +	DBG("    store_mfn      %llx\n", xen_start_info->store_mfn);
  23.163 +	DBG("    store_evtchn   %x\n", xen_start_info->store_evtchn);
  23.164 +	DBG("    console_mfn    %llx\n", xen_start_info->console.domU.mfn);
  23.165 +	DBG("    console_evtchn %x\n", xen_start_info->console.domU.evtchn);
  23.166 +
  23.167 +	xen_setup_time(&mach_maple_md);
  23.168 +
  23.169 +	xencons_early_setup();
  23.170 +	add_preferred_console("xvc", 0, NULL);
  23.171 +
  23.172 +	if (get_property(xen, "power-control", NULL))
  23.173 +		xen_reboot_init(&mach_maple_md);
  23.174 +	else
  23.175 +		xen_reboot_init(NULL);
  23.176 +
  23.177 +	if (is_initial_xendomain()) {
  23.178 +		u64 *mfnflag = (u64 *)get_property(xen, "mfn-flag", NULL);
  23.179 +		if (mfnflag) {
  23.180 +			foreign_mfn_flag = (1UL << mfnflag[0]);
  23.181 +			printk("OF: using 0x%lx as foreign mfn flag\n", foreign_mfn_flag);
  23.182 +		} else
  23.183 +			printk("OF: /xen/mfn-base must be present it build guests\n");
  23.184 +	}
  23.185 +
  23.186 +	/* get the domain features */
  23.187 +	setup_xen_features();
  23.188 +
  23.189 +	DBG("Hello World I'm Maple Xen-LPAR!\n");
  23.190 +
  23.191 +	if (firmware_has_feature(FW_FEATURE_DABR))
  23.192 +		ppc_md.set_dabr = pseries_set_dabr;
  23.193 +	else if (firmware_has_feature(FW_FEATURE_XDABR))
  23.194 +		ppc_md.set_dabr = pseries_set_xdabr;
  23.195 +
  23.196 +	iommu_init_early_pSeries();
  23.197 +
  23.198 +	DBG(" <- %s\n", __func__);
  23.199 +}
  23.200 +
  23.201 +/*
  23.202 + * this interface is limiting
  23.203 + */
  23.204 +static int running_on_xen;
  23.205 +int is_running_on_xen(void)
  23.206 +{
  23.207 +	return running_on_xen;
  23.208 +}
  23.209 +EXPORT_SYMBOL(is_running_on_xen);
  23.210 +
  23.211 +static void xenppc_power_save(void)
  23.212 +{
  23.213 +	/* SCHEDOP_yield could immediately return. Instead, we
  23.214 +	 * want to idle in the Xen idle domain, so use
  23.215 +	 * SCHEDOP_block with a one-shot timer. */
  23.216 +	/* XXX do tickless stuff here. See
  23.217 +	 * linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c */
  23.218 +	u64 now_ns = tb_to_ns(get_tb());
  23.219 +	u64 offset_ns = jiffies_to_ns(1);
  23.220 +	int rc;
  23.221 +
  23.222 +	rc = HYPERVISOR_set_timer_op(now_ns + offset_ns);
  23.223 +	BUG_ON(rc != 0);
  23.224 +
  23.225 +	HYPERVISOR_sched_op(SCHEDOP_block, NULL);
  23.226 +}
  23.227 +
  23.228 +void __init xenppc_setup_arch(void)
  23.229 +{
  23.230 +	/* init to some ~sane value until calibrate_delay() runs */
  23.231 +	loops_per_jiffy = 50000000;
  23.232 +
  23.233 +	/* Lookup PCI hosts */
  23.234 +	if (is_initial_xendomain())
  23.235 +		maple_pci_init();
  23.236 +
  23.237 +#ifdef CONFIG_DUMMY_CONSOLE
  23.238 +	conswitchp = &dummy_con;
  23.239 +#endif
  23.240 +#ifdef CONFIG_SMP
  23.241 +	/* let them fly */
  23.242 +	xen_setup_smp();
  23.243 +#endif
  23.244 +
  23.245 +	printk(KERN_INFO "Using Xen idle loop\n");
  23.246 +}
  23.247 +
  23.248 +static int __init xen_probe_flat_dt(unsigned long node,
  23.249 +				    const char *uname, int depth,
  23.250 +				    void *data)
  23.251 +{
  23.252 +	if (depth != 1)
  23.253 +		return 0;
  23.254 +	if (strcmp(uname, "xen") != 0)
  23.255 + 		return 0;
  23.256 +
  23.257 +	running_on_xen = 1;
  23.258 +
  23.259 +	return 1;
  23.260 +}
  23.261 +
  23.262 +/*
  23.263 + * Called very early, MMU is off, device-tree isn't unflattened
  23.264 + */
  23.265 +/* forward ref */
  23.266 +struct machdep_calls __initdata xen_md;
  23.267 +static int __init xenppc_probe(void)
  23.268 +{
  23.269 +	of_scan_flat_dt(xen_probe_flat_dt, NULL);
  23.270 +
  23.271 +	if (!running_on_xen)
  23.272 +		return 0;
  23.273 +
  23.274 +	xen_fw_feature_init();
  23.275 +
  23.276 +	hpte_init_lpar();
  23.277 +
  23.278 +	return 1;
  23.279 +}
  23.280 +
  23.281 +static void __init xenppc_progress(char *s, unsigned short hex)
  23.282 +{
  23.283 +	printk("*** %04x : %s\n", hex, s ? s : "");
  23.284 +}
  23.285 +
  23.286 +unsigned int xenppc_get_irq(struct pt_regs *regs)
  23.287 +{
  23.288 +	evtchn_do_upcall(regs);
  23.289 +	/* evtchn_do_upcall() handles all pending event channels directly, so there
  23.290 +	 * is nothing for do_IRQ() to do.
  23.291 +	 * XXX This means we aren't using IRQ stacks. */
  23.292 +	return NO_IRQ;
  23.293 +}
  23.294 +
  23.295 +#ifdef CONFIG_KEXEC
  23.296 +void xen_machine_kexec(struct kimage *image)
  23.297 +{
  23.298 +	panic("%s(%p): called\n", __func__, image);
  23.299 +}
  23.300 +
  23.301 +int xen_machine_kexec_prepare(struct kimage *image)
  23.302 +{
  23.303 +	panic("%s(%p): called\n", __func__, image);
  23.304 +}
  23.305 +
  23.306 +void xen_machine_crash_shutdown(struct pt_regs *regs)
  23.307 +{
  23.308 +	panic("%s(%p): called\n", __func__, regs);
  23.309 +}       
  23.310 +#endif
  23.311 +
  23.312 +define_machine(xen) {
  23.313 +	.name			= "Xen-Maple",
  23.314 +	.probe			= xenppc_probe,
  23.315 +	.setup_arch		= xenppc_setup_arch,
  23.316 +	.init_early		= xenppc_init_early,
  23.317 +	.init_IRQ		= xen_init_IRQ,
  23.318 +	.get_irq		= xenppc_get_irq,
  23.319 +	.calibrate_decr		= generic_calibrate_decr,
  23.320 +	.progress		= xenppc_progress,
  23.321 +	.power_save		= xenppc_power_save,
  23.322 +#ifdef CONFIG_KEXEC
  23.323 +	.machine_kexec		= xen_machine_kexec,
  23.324 +	.machine_kexec_prepare	= xen_machine_kexec_prepare,
  23.325 +	.machine_crash_shutdown	= xen_machine_crash_shutdown,
  23.326 +#endif
  23.327 +};
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/arch/powerpc/platforms/xen/setup.h	Tue Jul 10 08:40:03 2007 -0600
    24.3 @@ -0,0 +1,49 @@
    24.4 +/*
    24.5 + * This program is free software; you can redistribute it and/or modify
    24.6 + * it under the terms of the GNU General Public License as published by
    24.7 + * the Free Software Foundation; either version 2 of the License, or
    24.8 + * (at your option) any later version.
    24.9 + *
   24.10 + * This program is distributed in the hope that it will be useful,
   24.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.13 + * GNU General Public License for more details.
   24.14 + *
   24.15 + * You should have received a copy of the GNU General Public License
   24.16 + * along with this program; if not, write to the Free Software
   24.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   24.18 + *
   24.19 + * Copyright (C) IBM Corp. 2006
   24.20 + *
   24.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   24.22 + */
   24.23 +
   24.24 +#include <asm/machdep.h>
   24.25 +#include <asm/time.h>
   24.26 +
   24.27 +extern void evtchn_init_IRQ(void);
   24.28 +extern void xen_init_IRQ(void);
   24.29 +extern void xen_reboot_init(struct machdep_calls *);
   24.30 +extern void xen_maple_init_IRQ(void);
   24.31 +extern unsigned int xen_get_irq(struct pt_regs *regs);
   24.32 +
   24.33 +static inline u64 tb_to_ns(u64 tb)
   24.34 +{
   24.35 +	if (likely(tb_ticks_per_sec)) {
   24.36 +		return tb * (1000000000UL / tb_ticks_per_sec);
   24.37 +	}
   24.38 +	return 0;
   24.39 +}
   24.40 +
   24.41 +static inline u64 jiffies_to_ns(unsigned long j) 
   24.42 +{
   24.43 +	return j * (1000000000UL / HZ);
   24.44 +}
   24.45 +
   24.46 +#define xen_guest_handle(hnd)  ((hnd).p)
   24.47 +
   24.48 +extern struct page *alloc_foreign_page(void);
   24.49 +extern void free_foreign_page(struct page *page);
   24.50 +
   24.51 +extern void __init xen_setup_time(struct machdep_calls *host_md);
   24.52 +extern void xen_setup_smp(void);
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/arch/powerpc/platforms/xen/smp.c	Tue Jul 10 08:40:03 2007 -0600
    25.3 @@ -0,0 +1,444 @@
    25.4 +/*
    25.5 + * This program is free software; you can redistribute it and/or modify
    25.6 + * it under the terms of the GNU General Public License as published by
    25.7 + * the Free Software Foundation; either version 2 of the License, or
    25.8 + * (at your option) any later version.
    25.9 + *
   25.10 + * This program is distributed in the hope that it will be useful,
   25.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   25.13 + * GNU General Public License for more details.
   25.14 + *
   25.15 + * You should have received a copy of the GNU General Public License
   25.16 + * along with this program; if not, write to the Free Software
   25.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   25.18 + *
   25.19 + * Copyright (C) IBM Corp. 2006
   25.20 + *
   25.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   25.22 + */
   25.23 +
   25.24 +#include <linux/kernel.h>
   25.25 +#include <linux/config.h>
   25.26 +#include <linux/bootmem.h>
   25.27 +#include <linux/irq.h>
   25.28 +#include <linux/smp.h>
   25.29 +#include <xen/interface/xen.h>
   25.30 +#include <xen/interface/vcpu.h>
   25.31 +#include <xen/evtchn.h>
   25.32 +#include <asm/prom.h>
   25.33 +#include <asm/udbg.h>
   25.34 +#include <asm/hypervisor.h>
   25.35 +#include "setup.h"
   25.36 +
   25.37 +#undef DEBUG
   25.38 +
   25.39 +#ifdef DEBUG
   25.40 +#define DBG(fmt...) printk(KERN_EMERG fmt)
   25.41 +#else
   25.42 +#define DBG(fmt...)
   25.43 +#endif
   25.44 +
   25.45 +static inline void *xen_of_alloc(ulong size)
   25.46 +{
   25.47 +	if (mem_init_done)
   25.48 +		return kmalloc(size, GFP_KERNEL);
   25.49 +	return alloc_bootmem(size);
   25.50 +}
   25.51 +static inline void xen_of_free(void *ptr)
   25.52 +{
   25.53 +	/* if this happens with the boot allocator then we are screwed */
   25.54 +	BUG_ON(!mem_init_done);
   25.55 +	kfree(ptr);
   25.56 +}
   25.57 +
   25.58 +static struct property *dup_prop(struct property *op)
   25.59 +{
   25.60 +	struct property *np;
   25.61 +	void *p;
   25.62 +	ulong sz;
   25.63 +
   25.64 +
   25.65 +	/* allocate everything in one go in case it fails */
   25.66 +	sz = sizeof (*np); /* prop node */
   25.67 +	sz += strlen(op->name) + 1; /* prop name */
   25.68 +	sz += op->length; /* prop value */
   25.69 +		
   25.70 +	p = xen_of_alloc(sz);
   25.71 +	if (!p)
   25.72 +		return NULL;
   25.73 +	memset(p, 0, sz);
   25.74 +
   25.75 +	/* prop node first */
   25.76 +	np = p;
   25.77 +	p += sizeof (*np);
   25.78 +
   25.79 +	/* value next becuase we want it aligned */
   25.80 +	np->value = p;
   25.81 +	p += op->length;
   25.82 +
   25.83 +	/* name */
   25.84 +	np->name = p;
   25.85 +
   25.86 +	/* copy it all */
   25.87 +	strcpy(np->name, op->name);
   25.88 +	np->length = op->length;
   25.89 +	memcpy(np->value, op->value, np->length);
   25.90 +
   25.91 +	return np;
   25.92 +}
   25.93 +
   25.94 +static int dup_properties(struct device_node *dst, struct device_node *src)
   25.95 +{
   25.96 +	struct property *op;
   25.97 +	struct property *np;
   25.98 +	struct property *lp;
   25.99 +	int rc = 0;
  25.100 +
  25.101 +	DBG("%s: duping to new cpu node: %s\n", __func__, dst->full_name);
  25.102 +
  25.103 +	np = lp = NULL;
  25.104 +	for (op = src->properties; op != 0; op = op->next) {
  25.105 +		lp = np;
  25.106 +		np = dup_prop(op);
  25.107 +		if (!np)
  25.108 +			break;
  25.109 +
  25.110 +		prom_add_property(dst, np);
  25.111 +	}
  25.112 +
  25.113 +	if (!np) {
  25.114 +		DBG("%s: FAILED duping: %s\n", __func__, dst->full_name);
  25.115 +		/* we could not allocate enuff so free what we have
  25.116 +		 * allocated */
  25.117 +		rc = -ENOMEM;
  25.118 +		for (op = dst->properties; lp && op != lp; op = op->next)
  25.119 +			xen_of_free(op);
  25.120 +	}
  25.121 +
  25.122 +	return rc;
  25.123 +}
  25.124 +
  25.125 +/* returns added device node so it can be added to procfs in the case
  25.126 + * of hotpluging */
  25.127 +static struct device_node *xen_add_vcpu_node(struct device_node *boot_cpu,
  25.128 +					     uint cpu)
  25.129 +{
  25.130 +	struct device_node *new_cpu;
  25.131 +	struct property *pp;
  25.132 +	void *p;
  25.133 +	int sz;
  25.134 +	int type_sz;
  25.135 +	int name_sz;
  25.136 +
  25.137 +	DBG("%s: boot cpu: %s\n", __func__, boot_cpu->full_name);
  25.138 +
  25.139 +	/* allocate in one shot in case we fail */
  25.140 +	name_sz = strlen(boot_cpu->name) + 1;
  25.141 +	type_sz = strlen(boot_cpu->type) + 1;
  25.142 +
  25.143 +	sz = sizeof (*new_cpu);	/* the node */
  25.144 +	sz += strlen(boot_cpu->full_name) + 3; /* full_name */
  25.145 +	sz += name_sz; /* name */
  25.146 +	sz += type_sz; /* type */
  25.147 +
  25.148 +	p = xen_of_alloc(sz);
  25.149 +	if (!p)
  25.150 +		return NULL;
  25.151 +	memset(p, 0, sz);
  25.152 +
  25.153 +	/* the node */
  25.154 +	new_cpu = p;
  25.155 +	p += sizeof (*new_cpu);
  25.156 +	
  25.157 +	/* name */
  25.158 +	new_cpu->name = p;
  25.159 +	strcpy(new_cpu->name, boot_cpu->name);
  25.160 +	p += name_sz;
  25.161 +	
  25.162 +	/* type */
  25.163 +	new_cpu->type = p;
  25.164 +	strcpy(new_cpu->type, boot_cpu->type);
  25.165 +	p += type_sz;
  25.166 +
  25.167 +	/* full_name */
  25.168 +	new_cpu->full_name = p;
  25.169 +
  25.170 +	/* assemble new full_name */
  25.171 +	pp = of_find_property(boot_cpu, "name", NULL);
  25.172 +	if (!pp)
  25.173 +		panic("%s: no name prop\n", __func__);
  25.174 +
  25.175 +	DBG("%s: name is: %s = %s\n", __func__, pp->name, pp->value);
  25.176 +	sprintf(new_cpu->full_name, "/cpus/%s@%u", pp->value, cpu);
  25.177 +
  25.178 +	if (dup_properties(new_cpu, boot_cpu)) {
  25.179 +		xen_of_free(new_cpu);
  25.180 +		return NULL;
  25.181 +	}
  25.182 +
  25.183 +	/* fixup reg property */
  25.184 +	DBG("%s: updating reg: %d\n", __func__, cpu);
  25.185 +	pp = of_find_property(new_cpu, "reg", NULL);
  25.186 +	if (!pp)
  25.187 +		panic("%s: no reg prop\n", __func__);
  25.188 +	*(int *)pp->value = cpu;
  25.189 +
  25.190 +	if (mem_init_done)
  25.191 +		OF_MARK_DYNAMIC(new_cpu);
  25.192 +
  25.193 +	kref_init(&new_cpu->kref);
  25.194 +
  25.195 +	/* insert the node */
  25.196 +	new_cpu->parent = of_get_parent(boot_cpu);
  25.197 +	of_attach_node(new_cpu);
  25.198 +	of_node_put(new_cpu->parent);
  25.199 +
  25.200 +	return new_cpu;
  25.201 +}
  25.202 +
  25.203 +static void cpu_initialize_context(unsigned int vcpu, ulong entry)
  25.204 +{
  25.205 +	vcpu_guest_context_t ctxt;
  25.206 +
  25.207 +	memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
  25.208 +
  25.209 +	ctxt.user_regs.pc = entry;
  25.210 +	ctxt.user_regs.msr = 0;
  25.211 +	ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
  25.212 +	ctxt.user_regs.gprs[3] = vcpu;
  25.213 +
  25.214 +	/* XXX verify this *** */
  25.215 +	/* There is a buggy kernel that does not zero the "local_paca", so
  25.216 +	 * we must make sure this register is 0 */
  25.217 +	ctxt.user_regs.gprs[13] = 0;
  25.218 +
  25.219 +	DBG("%s: initializing vcpu: %d\n", __func__, vcpu);
  25.220 +
  25.221 +	if (HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt))
  25.222 +		panic("%s: VCPUOP_initialise failed, vcpu: %d\n",
  25.223 +		       __func__, vcpu);
  25.224 +
  25.225 +}
  25.226 +
  25.227 +static int xen_start_vcpu(uint vcpu, ulong entry)
  25.228 +{
  25.229 +	DBG("%s: starting vcpu: %d\n", __func__, vcpu);
  25.230 +
  25.231 +	cpu_initialize_context(vcpu, entry);
  25.232 +
  25.233 +	DBG("%s: Spinning up vcpu: %d\n", __func__, vcpu);
  25.234 +	return HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
  25.235 +}
  25.236 +
  25.237 +extern void __secondary_hold(void);
  25.238 +extern unsigned long __secondary_hold_spinloop;
  25.239 +extern unsigned long __secondary_hold_acknowledge;
  25.240 +
  25.241 +static void xen_boot_secondary_vcpus(void)
  25.242 +{
  25.243 +	int vcpu;
  25.244 +	int rc;
  25.245 +	const unsigned long mark = (unsigned long)-1;
  25.246 +	unsigned long *spinloop = &__secondary_hold_spinloop;
  25.247 +	unsigned long *acknowledge = &__secondary_hold_acknowledge;
  25.248 +#ifdef CONFIG_PPC64
  25.249 +	/* __secondary_hold is actually a descriptor, not the text address */
  25.250 +	unsigned long secondary_hold = __pa(*(unsigned long *)__secondary_hold);
  25.251 +#else
  25.252 +	unsigned long secondary_hold = __pa(__secondary_hold);
  25.253 +#endif
  25.254 +	struct device_node *boot_cpu;
  25.255 +
  25.256 +	DBG("%s: finding CPU node\n", __func__);
  25.257 +	boot_cpu = of_find_node_by_type(NULL, "cpu");
  25.258 +	if (!boot_cpu)
  25.259 +		panic("%s: Cannot find Booting CPU node\n", __func__);
  25.260 +
  25.261 +	/* Set the common spinloop variable, so all of the secondary cpus
  25.262 +	 * will block when they are awakened from their OF spinloop.
  25.263 +	 * This must occur for both SMP and non SMP kernels, since OF will
  25.264 +	 * be trashed when we move the kernel.
  25.265 +	 */
  25.266 +	*spinloop = 0;
  25.267 +
  25.268 +	DBG("%s: Searching for all vcpu numbers > 0\n", __func__);
  25.269 +	/* try and start as many as we can */
  25.270 +	for (vcpu = 1; vcpu < NR_CPUS; vcpu++) {
  25.271 +		int i;
  25.272 +
  25.273 +		rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, vcpu, NULL);
  25.274 +		if (rc < 0)
  25.275 +			continue;
  25.276 +
  25.277 +		DBG("%s: Found vcpu: %d\n", __func__, vcpu);
  25.278 +		/* Init the acknowledge var which will be reset by
  25.279 +		 * the secondary cpu when it awakens from its OF
  25.280 +		 * spinloop.
  25.281 +		 */
  25.282 +		*acknowledge = mark;
  25.283 +
  25.284 +		DBG("%s: Starting vcpu: %d at pc: 0x%lx\n", __func__,
  25.285 +		    vcpu, secondary_hold);
  25.286 +		rc = xen_start_vcpu(vcpu, secondary_hold);
  25.287 +		if (rc)
  25.288 +			panic("%s: xen_start_vpcu() failed\n", __func__);
  25.289 +
  25.290 +
  25.291 +		DBG("%s: Waiting for ACK on vcpu: %d\n", __func__, vcpu);
  25.292 +		for (i = 0; (i < 100000000) && (*acknowledge == mark); i++)
  25.293 +			mb();
  25.294 +
  25.295 +		if (*acknowledge == vcpu)
  25.296 +			DBG("%s: Recieved for ACK on vcpu: %d\n",
  25.297 +			    __func__, vcpu);
  25.298 +
  25.299 +		xen_add_vcpu_node(boot_cpu, vcpu);
  25.300 +
  25.301 +		cpu_set(vcpu, cpu_present_map);
  25.302 +		set_hard_smp_processor_id(vcpu, vcpu);
  25.303 +	}
  25.304 +	of_node_put(boot_cpu);
  25.305 +	DBG("%s: end...\n", __func__);
  25.306 +}
  25.307 +
  25.308 +static int __init smp_xen_probe(void)
  25.309 +{
  25.310 +	return cpus_weight(cpu_present_map);
  25.311 +}
  25.312 +
  25.313 +static irqreturn_t xen_ppc_msg_reschedule(int irq, void *dev_id,
  25.314 +					  struct pt_regs *regs)
  25.315 +{
  25.316 +	smp_message_recv(PPC_MSG_RESCHEDULE, regs);
  25.317 +	return IRQ_HANDLED;
  25.318 +}
  25.319 +
  25.320 +static irqreturn_t xen_ppc_msg_call_function(int irq, void *dev_id,
  25.321 +					     struct pt_regs *regs)
  25.322 +{
  25.323 +	smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
  25.324 +	return IRQ_HANDLED;
  25.325 +}
  25.326 +
  25.327 +static irqreturn_t xen_ppc_msg_debugger_break(int irq, void *dev_id,
  25.328 +					  struct pt_regs *regs)
  25.329 +{
  25.330 +	smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
  25.331 +	return IRQ_HANDLED;
  25.332 +}
  25.333 +
  25.334 +struct message {
  25.335 +	irqreturn_t (*f)(int, void *, struct pt_regs *);
  25.336 +	int num;
  25.337 +	char *name;
  25.338 +};
  25.339 +static struct message ipi_msgs[] = {
  25.340 +	{
  25.341 +		.num = PPC_MSG_RESCHEDULE,
  25.342 +		.f = xen_ppc_msg_reschedule,
  25.343 +		.name = "IPI-resched"
  25.344 +	},
  25.345 +	{
  25.346 +		.num = PPC_MSG_CALL_FUNCTION,
  25.347 +		.f = xen_ppc_msg_call_function,
  25.348 +		.name = "IPI-function"
  25.349 +		},
  25.350 +	{
  25.351 +		.num = PPC_MSG_DEBUGGER_BREAK,
  25.352 +		.f = xen_ppc_msg_debugger_break,
  25.353 +		.name = "IPI-debug"
  25.354 +	}
  25.355 +};
  25.356 +
  25.357 +DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
  25.358 +
  25.359 +static void __devinit smp_xen_setup_cpu(int cpu)
  25.360 +{
  25.361 +	int irq;
  25.362 +	int i;
  25.363 +	const int nr_ipis = ARRAY_SIZE(__get_cpu_var(ipi_to_irq));
  25.364 +
  25.365 +	/* big scary include web could mess with our values, so we
  25.366 +	 * make sure they are sane */
  25.367 +	BUG_ON(ARRAY_SIZE(ipi_msgs) > nr_ipis);
  25.368 +
  25.369 +	for (i = 0; i < ARRAY_SIZE(ipi_msgs); i++) {
  25.370 +		BUG_ON(ipi_msgs[i].num >= nr_ipis);
  25.371 +
  25.372 +		irq = bind_ipi_to_irqhandler(ipi_msgs[i].num,
  25.373 +					     cpu,
  25.374 +					     ipi_msgs[i].f,
  25.375 +					     SA_INTERRUPT,
  25.376 +					     ipi_msgs[i].name,
  25.377 +					     NULL);
  25.378 +		BUG_ON(irq < 0);
  25.379 +		per_cpu(ipi_to_irq, cpu)[ipi_msgs[i].num] = irq;
  25.380 +		DBG("%s: cpu: %d vector :%d irq: %d\n",
  25.381 +		       __func__, cpu, ipi_msgs[i].num, irq);
  25.382 +	}
  25.383 +}
  25.384 +
  25.385 +static inline void send_IPI_one(unsigned int cpu, int vector)
  25.386 +{
  25.387 +	int irq;
  25.388 +
  25.389 +	irq = per_cpu(ipi_to_irq, cpu)[vector];
  25.390 +	BUG_ON(irq < 0);
  25.391 +
  25.392 +	DBG("%s: cpu: %d vector :%d irq: %d!\n",
  25.393 +	       __func__, cpu, vector, irq);
  25.394 +	DBG("%s: per_cpu[%p]: %d %d %d %d\n",
  25.395 +	       __func__, per_cpu(ipi_to_irq, cpu),
  25.396 +	       per_cpu(ipi_to_irq, cpu)[0],
  25.397 +	       per_cpu(ipi_to_irq, cpu)[1],
  25.398 +	       per_cpu(ipi_to_irq, cpu)[2],
  25.399 +	       per_cpu(ipi_to_irq, cpu)[3]);
  25.400 +
  25.401 +	notify_remote_via_irq(irq);
  25.402 +}
  25.403 +
  25.404 +static void smp_xen_message_pass(int target, int msg)
  25.405 +{
  25.406 +	int cpu;
  25.407 +
  25.408 +	switch (msg) {
  25.409 +	case PPC_MSG_RESCHEDULE:
  25.410 +	case PPC_MSG_CALL_FUNCTION:
  25.411 +	case PPC_MSG_DEBUGGER_BREAK:
  25.412 +		break;
  25.413 +	default:
  25.414 +		panic("SMP %d: smp_message_pass: unknown msg %d\n",
  25.415 +		       smp_processor_id(), msg);
  25.416 +		return;
  25.417 +	}
  25.418 +	switch (target) {
  25.419 +	case MSG_ALL:
  25.420 +	case MSG_ALL_BUT_SELF:
  25.421 +		for_each_online_cpu(cpu) {
  25.422 +			if (target == MSG_ALL_BUT_SELF &&
  25.423 +			    cpu == smp_processor_id())
  25.424 +				continue;
  25.425 +			send_IPI_one(cpu, msg);
  25.426 +		}
  25.427 +		break;
  25.428 +	default:
  25.429 +		send_IPI_one(target, msg);
  25.430 +		break;
  25.431 +	}
  25.432 +}
  25.433 +
  25.434 +static struct smp_ops_t xen_smp_ops = {
  25.435 +	.probe		= smp_xen_probe,
  25.436 +	.message_pass	= smp_xen_message_pass,
  25.437 +	.kick_cpu	= smp_generic_kick_cpu,
  25.438 +	.setup_cpu	= smp_xen_setup_cpu,
  25.439 +};
  25.440 +
  25.441 +void xen_setup_smp(void)
  25.442 +{
  25.443 +	smp_ops = &xen_smp_ops;
  25.444 +
  25.445 +	xen_boot_secondary_vcpus();
  25.446 +	smp_release_cpus();
  25.447 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/arch/powerpc/platforms/xen/time.c	Tue Jul 10 08:40:03 2007 -0600
    26.3 @@ -0,0 +1,114 @@
    26.4 +/*
    26.5 + * This program is free software; you can redistribute it and/or modify
    26.6 + * it under the terms of the GNU General Public License as published by
    26.7 + * the Free Software Foundation; either version 2 of the License, or
    26.8 + * (at your option) any later version.
    26.9 + *
   26.10 + * This program is distributed in the hope that it will be useful,
   26.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.13 + * GNU General Public License for more details.
   26.14 + *
   26.15 + * You should have received a copy of the GNU General Public License
   26.16 + * along with this program; if not, write to the Free Software
   26.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   26.18 + *
   26.19 + * Copyright (C) IBM Corp. 2006
   26.20 + *
   26.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   26.22 + */
   26.23 +
   26.24 +#include <linux/module.h>
   26.25 +#include <linux/time.h>
   26.26 +#include <linux/rtc.h>
   26.27 +#include <asm/hypervisor.h>
   26.28 +#include <asm/machdep.h>
   26.29 +#include <asm/time.h>
   26.30 +#include <asm/udbg.h>
   26.31 +
   26.32 +#ifdef DEBUG
   26.33 +#define DBG(fmt...) printk(fmt)
   26.34 +#else
   26.35 +#define DBG(fmt...)
   26.36 +#endif
   26.37 +
   26.38 +void time_resume(void)
   26.39 +{
   26.40 +	snapshot_timebase();
   26.41 +}
   26.42 +
   26.43 +static inline ulong time_from_shared(void)
   26.44 +{
   26.45 +	ulong t;
   26.46 +
   26.47 +	DBG("tb_freq: %ld\n", ppc_tb_freq);
   26.48 +
   26.49 +	t = mftb() - HYPERVISOR_shared_info->arch.boot_timebase;
   26.50 +	t /= ppc_tb_freq;
   26.51 +	t += HYPERVISOR_shared_info->wc_sec;
   26.52 +
   26.53 +	return t;
   26.54 +}
   26.55 +
   26.56 +static void (*host_md_get_rtc_time)(struct rtc_time *tm);
   26.57 +static void xen_get_rtc_time(struct rtc_time *tm)
   26.58 +{
   26.59 +	if (is_initial_xendomain()) {
   26.60 +		host_md_get_rtc_time(tm);
   26.61 +		return;
   26.62 +	} else {
   26.63 +		ulong t;
   26.64 +
   26.65 +		t = time_from_shared();
   26.66 +		to_tm(t, tm);
   26.67 +	}
   26.68 +}
   26.69 +
   26.70 +static int (*host_md_set_rtc_time)(struct rtc_time *tm);
   26.71 +static int xen_set_rtc_time(struct rtc_time *tm)
   26.72 +{
   26.73 +	ulong sec;
   26.74 +
   26.75 +	if (is_initial_xendomain()) {
   26.76 +		host_md_set_rtc_time(tm);
   26.77 +		return 0;
   26.78 +	}
   26.79 +
   26.80 +	sec = mktime(tm->tm_year, tm->tm_mon, tm->tm_mday,
   26.81 +		     tm->tm_hour, tm->tm_min, tm->tm_sec);
   26.82 +
   26.83 +	HYPERVISOR_shared_info->wc_sec = sec;
   26.84 +	HYPERVISOR_shared_info->arch.boot_timebase = mftb();
   26.85 +
   26.86 +	return 0;
   26.87 +}
   26.88 +
   26.89 +static unsigned long (*host_md_get_boot_time)(void);
   26.90 +static unsigned long __init xen_get_boot_time(void)
   26.91 +{
   26.92 +	ulong t;
   26.93 +
   26.94 +	if (is_initial_xendomain()) {
   26.95 +		t = host_md_get_boot_time();
   26.96 +
   26.97 +		HYPERVISOR_shared_info->wc_sec = t;
   26.98 +		HYPERVISOR_shared_info->arch.boot_timebase = mftb();
   26.99 +		DBG("%s: time: %ld\n", __func__, t);
  26.100 +	} else {
  26.101 +		t = time_from_shared();
  26.102 +		DBG("%s: %ld\n", __func__, t);
  26.103 +	}
  26.104 +	return t;
  26.105 +}
  26.106 +
  26.107 +void __init xen_setup_time(struct machdep_calls *host_md)
  26.108 +{
  26.109 +	ppc_md.get_boot_time = xen_get_boot_time;
  26.110 +	host_md_get_boot_time = host_md->get_boot_time;
  26.111 +
  26.112 +	ppc_md.set_rtc_time = xen_set_rtc_time;
  26.113 +	host_md_set_rtc_time = host_md->set_rtc_time;
  26.114 +
  26.115 +	ppc_md.get_rtc_time = xen_get_rtc_time;
  26.116 +	host_md_get_rtc_time = host_md->get_rtc_time;
  26.117 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/arch/powerpc/platforms/xen/udbg_xen.c	Tue Jul 10 08:40:03 2007 -0600
    27.3 @@ -0,0 +1,164 @@
    27.4 +/*
    27.5 + * This program is free software; you can redistribute it and/or modify
    27.6 + * it under the terms of the GNU General Public License as published by
    27.7 + * the Free Software Foundation; either version 2 of the License, or
    27.8 + * (at your option) any later version.
    27.9 + *
   27.10 + * This program is distributed in the hope that it will be useful,
   27.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   27.13 + * GNU General Public License for more details.
   27.14 + *
   27.15 + * You should have received a copy of the GNU General Public License
   27.16 + * along with this program; if not, write to the Free Software
   27.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   27.18 + *
   27.19 + * Copyright (C) IBM Corp. 2006
   27.20 + *
   27.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   27.22 + */
   27.23 +
   27.24 +#include <linux/module.h>
   27.25 +#include <xen/interface/xen.h>
   27.26 +#include <xen/interface/io/console.h>
   27.27 +#include <xen/evtchn.h>
   27.28 +#include <asm/udbg.h>
   27.29 +#include <asm/hypervisor.h>
   27.30 +#include "setup.h"
   27.31 +
   27.32 +static void udbg_xen_wait(void)
   27.33 +{
   27.34 +	evtchn_port_t port = 0;
   27.35 +
   27.36 +	if (xen_start_info) {
   27.37 +		port = xen_start_info->console.domU.evtchn;
   27.38 +		clear_evtchn(port);
   27.39 +	}
   27.40 +	HYPERVISOR_poll(&port, 1, 10);
   27.41 +}
   27.42 +
   27.43 +static int udbg_getc_xen(void)
   27.44 +{
   27.45 +	int ch;
   27.46 +	for (;;) {
   27.47 +		ch = udbg_getc_poll();
   27.48 +		if (ch == -1) {
   27.49 +			udbg_xen_wait();
   27.50 +		} else {
   27.51 +			return ch;
   27.52 +		}
   27.53 +	}
   27.54 +}
   27.55 +
   27.56 +static void udbg_putc_dom0_xen(char c)
   27.57 +{
   27.58 +	unsigned long rc;
   27.59 +
   27.60 +	if (c == '\n')
   27.61 +		udbg_putc_dom0_xen('\r');
   27.62 +
   27.63 +	do {
   27.64 +		rc = HYPERVISOR_console_io(CONSOLEIO_write, 1, &c);
   27.65 +	} while (rc < 0);
   27.66 +}
   27.67 +
   27.68 +/* Buffered chars getc */
   27.69 +static long inbuflen;
   27.70 +static char inbuf[128];	/* Xen serial ring buffer */
   27.71 +
   27.72 +static int udbg_getc_poll_dom0_xen(void)
   27.73 +{
   27.74 +	/* The interface is tricky because it may return many chars.
   27.75 +	 * We save them statically for future calls to udbg_getc().
   27.76 +	 */
   27.77 +	char ch, *buf = (char *)inbuf;
   27.78 +	int i;
   27.79 +
   27.80 +	if (inbuflen == 0) {
   27.81 +		/* get some more chars. */
   27.82 +		inbuflen = HYPERVISOR_console_io(CONSOLEIO_read,
   27.83 +						 sizeof(inbuf), buf);
   27.84 +	}
   27.85 +
   27.86 +	if (inbuflen == 0)
   27.87 +		return -1;
   27.88 +
   27.89 +	ch = buf[0];
   27.90 +	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
   27.91 +		buf[i-1] = buf[i];
   27.92 +	inbuflen--;
   27.93 +
   27.94 +	return ch;
   27.95 +}
   27.96 +
   27.97 +static struct xencons_interface *intf;
   27.98 +
   27.99 +static void udbg_putc_domu_xen(char c)
  27.100 +{
  27.101 +	XENCONS_RING_IDX cons, prod;
  27.102 +
  27.103 +	if (c == '\n')
  27.104 +		udbg_putc_domu_xen('\r');
  27.105 +
  27.106 +	cons = intf->out_cons;
  27.107 +	prod = intf->out_prod;
  27.108 +	mb();
  27.109 +
  27.110 +	if ((prod - cons) < sizeof(intf->out))
  27.111 +		intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = c;
  27.112 +
  27.113 +	wmb();
  27.114 +	intf->out_prod = prod;
  27.115 +
  27.116 +	if (xen_start_info)
  27.117 +		notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
  27.118 +}
  27.119 +
  27.120 +static int udbg_getc_poll_domu_xen(void)
  27.121 +{
  27.122 +	XENCONS_RING_IDX cons, prod;
  27.123 +	int c;
  27.124 +
  27.125 +	mb();
  27.126 +	cons = intf->in_cons;
  27.127 +	prod = intf->in_prod;
  27.128 +	BUG_ON((prod - cons) > sizeof(intf->in));
  27.129 +
  27.130 +	if (cons == prod)
  27.131 +		return -1;
  27.132 +
  27.133 +	c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
  27.134 +	wmb();
  27.135 +	intf->in_cons = cons;
  27.136 +
  27.137 +	if (xen_start_info)
  27.138 +		notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
  27.139 +
  27.140 +	return c;
  27.141 +}
  27.142 +
  27.143 +void udbg_init_xen(void)
  27.144 +{
  27.145 +	ulong __console_mfn = 0;
  27.146 +
  27.147 +	if (xen_start_info) {
  27.148 +		/* we can find out where everything is */
  27.149 +		if (!(xen_start_info->flags & SIF_INITDOMAIN))
  27.150 +			__console_mfn = xen_start_info->console.domU.mfn;
  27.151 +	} else {
  27.152 +		/* VERY early printf */
  27.153 +#ifdef CONFIG_PPC_EARLY_DEBUG_XEN_DOMU
  27.154 +		__console_mfn = 0x3ffdUL;
  27.155 +#endif
  27.156 +	}
  27.157 +
  27.158 +	udbg_getc = udbg_getc_xen;
  27.159 +	if (__console_mfn == 0) {
  27.160 +		udbg_putc = udbg_putc_dom0_xen;
  27.161 +		udbg_getc_poll = udbg_getc_poll_dom0_xen;
  27.162 +	} else {
  27.163 +		udbg_putc = udbg_putc_domu_xen;
  27.164 +		udbg_getc_poll = udbg_getc_poll_domu_xen;
  27.165 +		intf = (struct xencons_interface *)mfn_to_virt(__console_mfn);
  27.166 +	}
  27.167 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/arch/powerpc/platforms/xen/util.c	Tue Jul 10 08:40:03 2007 -0600
    28.3 @@ -0,0 +1,70 @@
    28.4 +/*
    28.5 + * This program is free software; you can redistribute it and/or modify
    28.6 + * it under the terms of the GNU General Public License as published by
    28.7 + * the Free Software Foundation; either version 2 of the License, or
    28.8 + * (at your option) any later version.
    28.9 + *
   28.10 + * This program is distributed in the hope that it will be useful,
   28.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.13 + * GNU General Public License for more details.
   28.14 + *
   28.15 + * You should have received a copy of the GNU General Public License
   28.16 + * along with this program; if not, write to the Free Software
   28.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   28.18 + *
   28.19 + * Copyright (C) IBM Corp. 2006
   28.20 + *
   28.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   28.22 + */
   28.23 +
   28.24 +#include <linux/config.h>
   28.25 +#include <linux/mm.h>
   28.26 +#include <linux/module.h>
   28.27 +#include <linux/slab.h>
   28.28 +#include <linux/vmalloc.h>
   28.29 +#include <asm/uaccess.h>
   28.30 +#include <xen/driver_util.h>
   28.31 +#include "setup.h"
   28.32 +
   28.33 +struct vm_struct *alloc_vm_area(unsigned long size)
   28.34 +{
   28.35 +	struct vm_struct *area;
   28.36 +	struct page *page;
   28.37 +
   28.38 +	page = alloc_foreign_page();
   28.39 +	if (page == NULL) {
   28.40 +		BUG();
   28.41 +		return NULL;
   28.42 +	}
   28.43 +
   28.44 +	area = kmalloc(sizeof(*area), GFP_KERNEL);
   28.45 +	if (area != NULL) {
   28.46 +		area->flags = VM_MAP;//XXX
   28.47 +		area->addr = pfn_to_kaddr(page_to_pfn(page));
   28.48 +		area->size = size;
   28.49 +		area->pages = NULL; //XXX
   28.50 +		area->nr_pages = size >> PAGE_SHIFT;
   28.51 +		area->phys_addr = 0;
   28.52 +	}
   28.53 +	return area;
   28.54 +}
   28.55 +EXPORT_SYMBOL_GPL(alloc_vm_area);
   28.56 +
   28.57 +void free_vm_area(struct vm_struct *area)
   28.58 +{
   28.59 +	free_foreign_page(virt_to_page(area->addr));
   28.60 +	kfree(area);
   28.61 +}
   28.62 +EXPORT_SYMBOL_GPL(free_vm_area);
   28.63 +
   28.64 +void lock_vm_area(struct vm_struct *area)
   28.65 +{
   28.66 +	preempt_disable();
   28.67 +}
   28.68 +
   28.69 +void unlock_vm_area(struct vm_struct *area)
   28.70 +{
   28.71 +	preempt_enable();
   28.72 +}
   28.73 +EXPORT_SYMBOL_GPL(unlock_vm_area);
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/arch/powerpc/platforms/xen/xen_guest.S	Tue Jul 10 08:40:03 2007 -0600
    29.3 @@ -0,0 +1,27 @@
    29.4 +/*
    29.5 + * This program is free software; you can redistribute it and/or modify
    29.6 + * it under the terms of the GNU General Public License as published by
    29.7 + * the Free Software Foundation; either version 2 of the License, or
    29.8 + * (at your option) any later version.
    29.9 + *
   29.10 + * This program is distributed in the hope that it will be useful,
   29.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.13 + * GNU General Public License for more details.
   29.14 + *
   29.15 + * You should have received a copy of the GNU General Public License
   29.16 + * along with this program; if not, write to the Free Software
   29.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   29.18 + *
   29.19 + * Copyright (C) IBM Corp. 2006
   29.20 + *
   29.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   29.22 + */
   29.23 +
   29.24 +	.section __xen_guest
   29.25 +	.ascii	"GUEST_OS=linux"
   29.26 +	.ascii  ",GUEST_VER=xen-3.0"
   29.27 +	.ascii	",XEN_VER=xen-3.0"
   29.28 +	.ascii	",VIRT_BASE=0xC000000000000000"
   29.29 +	.ascii	",LOADER=generic"
   29.30 +	.byte	0
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/arch/powerpc/platforms/xen/xencomm.c	Tue Jul 10 08:40:03 2007 -0600
    30.3 @@ -0,0 +1,54 @@
    30.4 +/*
    30.5 + * This program is free software; you can redistribute it and/or modify
    30.6 + * it under the terms of the GNU General Public License as published by
    30.7 + * the Free Software Foundation; either version 2 of the License, or
    30.8 + * (at your option) any later version.
    30.9 + * 
   30.10 + * This program is distributed in the hope that it will be useful,
   30.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.13 + * GNU General Public License for more details.
   30.14 + * 
   30.15 + * You should have received a copy of the GNU General Public License
   30.16 + * along with this program; if not, write to the Free Software
   30.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   30.18 + *
   30.19 + * Copyright (C) IBM Corp. 2006
   30.20 + *
   30.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   30.22 + */
   30.23 +
   30.24 +#include <linux/types.h>
   30.25 +#include <linux/sched.h>
   30.26 +#include <linux/mm.h>
   30.27 +#include <asm/page.h>
   30.28 +#include <asm/current.h>
   30.29 +#include <xen/interface/arch-powerpc.h>
   30.30 +#include <xen/xencomm.h>
   30.31 +
   30.32 +/* translate virtual address to physical address */
   30.33 +unsigned long xencomm_vtop(unsigned long vaddr)
   30.34 +{
   30.35 +	struct page *page;
   30.36 +	struct vm_area_struct *vma;
   30.37 +
   30.38 +	/* NULL is NULL */
   30.39 +	if (vaddr == 0)
   30.40 +		return 0;
   30.41 +
   30.42 +	if (is_kernel_addr(vaddr))
   30.43 +		return __pa(vaddr);
   30.44 +
   30.45 +	/* XXX double-check (lack of) locking */
   30.46 +	vma = find_extend_vma(current->mm, vaddr);
   30.47 +	BUG_ON(!vma);
   30.48 +	if (!vma)
   30.49 +		return ~0UL;
   30.50 +
   30.51 +	page = follow_page(vma, vaddr, 0);
   30.52 +	BUG_ON(!page);
   30.53 +	if (!page)
   30.54 +		return ~0UL;
   30.55 +
   30.56 +	return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
   30.57 +}
    31.1 --- a/arch/powerpc/sysdev/mpic.c	Mon Jul 09 09:24:03 2007 -0600
    31.2 +++ b/arch/powerpc/sysdev/mpic.c	Tue Jul 10 08:40:03 2007 -0600
    31.3 @@ -765,6 +765,9 @@ static int mpic_host_map(struct irq_host
    31.4  	else if (hw >= MPIC_VEC_IPI_0) {
    31.5  		WARN_ON(!(mpic->flags & MPIC_PRIMARY));
    31.6  
    31.7 +		if (mpic->flags & MPIC_SKIP_IPI_INIT)
    31.8 +			return 0;
    31.9 +
   31.10  		DBG("mpic: mapping as IPI\n");
   31.11  		set_irq_chip_data(virq, mpic);
   31.12  		set_irq_chip_and_handler(virq, &mpic->hc_ipi,
   31.13 @@ -1019,6 +1022,9 @@ void __init mpic_init(struct mpic *mpic)
   31.14  			   (MPIC_VEC_TIMER_0 + i));
   31.15  	}
   31.16  
   31.17 +	if (mpic->flags & MPIC_SKIP_IPI_INIT)
   31.18 +		goto ipi_bailout;
   31.19 +
   31.20  	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
   31.21  	mpic_test_broken_ipi(mpic);
   31.22  	for (i = 0; i < 4; i++) {
   31.23 @@ -1028,6 +1034,7 @@ void __init mpic_init(struct mpic *mpic)
   31.24  			       (MPIC_VEC_IPI_0 + i));
   31.25  	}
   31.26  
   31.27 +ipi_bailout:
   31.28  	/* Initialize interrupt sources */
   31.29  	if (mpic->irq_count == 0)
   31.30  		mpic->irq_count = mpic->num_sources;
    32.1 --- a/arch/powerpc/xmon/xmon.c	Mon Jul 09 09:24:03 2007 -0600
    32.2 +++ b/arch/powerpc/xmon/xmon.c	Tue Jul 10 08:40:03 2007 -0600
    32.3 @@ -752,6 +752,9 @@ cmds(struct pt_regs *excp)
    32.4  			cmd = inchar();
    32.5  		}
    32.6  		switch (cmd) {
    32.7 +		case 'A':
    32.8 +			asm volatile(".long 0x200;nop");
    32.9 +			break;
   32.10  		case 'm':
   32.11  			cmd = inchar();
   32.12  			switch (cmd) {
    33.1 --- a/drivers/xen/Kconfig	Mon Jul 09 09:24:03 2007 -0600
    33.2 +++ b/drivers/xen/Kconfig	Tue Jul 10 08:40:03 2007 -0600
    33.3 @@ -272,6 +272,18 @@ config NO_IDLE_HZ
    33.4  config XEN_SMPBOOT
    33.5  	bool
    33.6  	default y
    33.7 -	depends on SMP
    33.8 +	depends on SMP && !PPC_XEN
    33.9 +
   33.10 +config XEN_BALLOON
   33.11 +	bool
   33.12 +	default y
   33.13 +	depends on !PPC_XEN
   33.14 +
   33.15 +config XEN_XENCOMM
   33.16 +	bool
   33.17 +
   33.18 +config XEN_DEVMEM
   33.19 +	bool
   33.20 +	default y
   33.21  
   33.22  endif
    34.1 --- a/drivers/xen/Makefile	Mon Jul 09 09:24:03 2007 -0600
    34.2 +++ b/drivers/xen/Makefile	Tue Jul 10 08:40:03 2007 -0600
    34.3 @@ -1,13 +1,12 @@
    34.4  obj-y	+= core/
    34.5  obj-y	+= console/
    34.6  obj-y	+= evtchn/
    34.7 -obj-y	+= privcmd/
    34.8  obj-y	+= xenbus/
    34.9  obj-y	+= gntdev/
   34.10 -obj-y	+= balloon/
   34.11  obj-y	+= char/
   34.12  
   34.13  obj-y	+= util.o
   34.14 +obj-$(CONFIG_XEN_BALLOON)		+= balloon/
   34.15  obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
   34.16  obj-$(CONFIG_XEN_BLKDEV_TAP)		+= blktap/
   34.17  obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
   34.18 @@ -18,3 +17,4 @@ obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pcib
   34.19  obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
   34.20  obj-$(CONFIG_XEN_FRAMEBUFFER)		+= fbfront/
   34.21  obj-$(CONFIG_XEN_KEYBOARD)		+= fbfront/
   34.22 +obj-$(CONFIG_XEN_PRIVCMD)	+= privcmd/
    35.1 --- a/drivers/xen/blkback/xenbus.c	Mon Jul 09 09:24:03 2007 -0600
    35.2 +++ b/drivers/xen/blkback/xenbus.c	Tue Jul 10 08:40:03 2007 -0600
    35.3 @@ -173,6 +173,9 @@ static int blkback_remove(struct xenbus_
    35.4  
    35.5  	DPRINTK("");
    35.6  
    35.7 +	if (be->major || be->minor)
    35.8 +		xenvbd_sysfs_delif(dev);
    35.9 +
   35.10  	if (be->backend_watch.node) {
   35.11  		unregister_xenbus_watch(&be->backend_watch);
   35.12  		kfree(be->backend_watch.node);
   35.13 @@ -186,9 +189,6 @@ static int blkback_remove(struct xenbus_
   35.14  		be->blkif = NULL;
   35.15  	}
   35.16  
   35.17 -	if (be->major || be->minor)
   35.18 -		xenvbd_sysfs_delif(dev);
   35.19 -
   35.20  	kfree(be);
   35.21  	dev->dev.driver_data = NULL;
   35.22  	return 0;
    36.1 --- a/drivers/xen/blkfront/blkfront.c	Mon Jul 09 09:24:03 2007 -0600
    36.2 +++ b/drivers/xen/blkfront/blkfront.c	Tue Jul 10 08:40:03 2007 -0600
    36.3 @@ -354,6 +354,8 @@ static void connect(struct blkfront_info
    36.4  	spin_unlock_irq(&blkif_io_lock);
    36.5  
    36.6  	add_disk(info->gd);
    36.7 +
    36.8 +	info->is_ready = 1;
    36.9  }
   36.10  
   36.11  /**
   36.12 @@ -862,6 +864,13 @@ static void blkif_recover(struct blkfron
   36.13  	spin_unlock_irq(&blkif_io_lock);
   36.14  }
   36.15  
   36.16 +int blkfront_is_ready(struct xenbus_device *dev)
   36.17 +{
   36.18 +	struct blkfront_info *info = dev->dev.driver_data;
   36.19 +
   36.20 +	return info->is_ready;
   36.21 +}
   36.22 +
   36.23  
   36.24  /* ** Driver Registration ** */
   36.25  
   36.26 @@ -880,6 +889,7 @@ static struct xenbus_driver blkfront = {
   36.27  	.remove = blkfront_remove,
   36.28  	.resume = blkfront_resume,
   36.29  	.otherend_changed = backend_changed,
   36.30 +	.is_ready = blkfront_is_ready,
   36.31  };
   36.32  
   36.33  
    37.1 --- a/drivers/xen/blkfront/block.h	Mon Jul 09 09:24:03 2007 -0600
    37.2 +++ b/drivers/xen/blkfront/block.h	Tue Jul 10 08:40:03 2007 -0600
    37.3 @@ -111,6 +111,7 @@ struct blkfront_info
    37.4  	struct blk_shadow shadow[BLK_RING_SIZE];
    37.5  	unsigned long shadow_free;
    37.6  	int feature_barrier;
    37.7 +	int is_ready;
    37.8  
    37.9  	/**
   37.10  	 * The number of people holding this device open.  We won't allow a
    38.1 --- a/drivers/xen/blktap/xenbus.c	Mon Jul 09 09:24:03 2007 -0600
    38.2 +++ b/drivers/xen/blktap/xenbus.c	Tue Jul 10 08:40:03 2007 -0600
    38.3 @@ -170,6 +170,8 @@ static int blktap_remove(struct xenbus_d
    38.4  {
    38.5  	struct backend_info *be = dev->dev.driver_data;
    38.6  
    38.7 +	if (be->group_added)
    38.8 +		xentap_sysfs_delif(be->dev);
    38.9  	if (be->backend_watch.node) {
   38.10  		unregister_xenbus_watch(&be->backend_watch);
   38.11  		kfree(be->backend_watch.node);
   38.12 @@ -182,8 +184,6 @@ static int blktap_remove(struct xenbus_d
   38.13  		tap_blkif_free(be->blkif);
   38.14  		be->blkif = NULL;
   38.15  	}
   38.16 -	if (be->group_added)
   38.17 -		xentap_sysfs_delif(be->dev);
   38.18  	kfree(be);
   38.19  	dev->dev.driver_data = NULL;
   38.20  	return 0;
    39.1 --- a/drivers/xen/char/Makefile	Mon Jul 09 09:24:03 2007 -0600
    39.2 +++ b/drivers/xen/char/Makefile	Tue Jul 10 08:40:03 2007 -0600
    39.3 @@ -1,2 +1,1 @@
    39.4 -
    39.5 -obj-y	:= mem.o
    39.6 +obj-$(CONFIG_XEN_DEVMEM)	:= mem.o
    40.1 --- a/drivers/xen/char/mem.c	Mon Jul 09 09:24:03 2007 -0600
    40.2 +++ b/drivers/xen/char/mem.c	Tue Jul 10 08:40:03 2007 -0600
    40.3 @@ -58,7 +58,7 @@ static ssize_t read_mem(struct file * fi
    40.4  
    40.5  		sz = min_t(unsigned long, sz, count);
    40.6  
    40.7 -		v = xlate_dev_mem_ptr(p, sz);
    40.8 +		v = xen_xlate_dev_mem_ptr(p, sz);
    40.9  		if (IS_ERR(v) || v == NULL) {
   40.10  			/*
   40.11  			 * Some programs (e.g., dmidecode) groove off into
   40.12 @@ -75,7 +75,7 @@ static ssize_t read_mem(struct file * fi
   40.13  		}
   40.14  
   40.15  		ignored = copy_to_user(buf, v, sz);
   40.16 -		xlate_dev_mem_ptr_unmap(v);
   40.17 +		xen_xlate_dev_mem_ptr_unmap(v);
   40.18  		if (ignored)
   40.19  			return -EFAULT;
   40.20  		buf += sz;
   40.21 @@ -109,7 +109,7 @@ static ssize_t write_mem(struct file * f
   40.22  
   40.23  		sz = min_t(unsigned long, sz, count);
   40.24  
   40.25 -		v = xlate_dev_mem_ptr(p, sz);
   40.26 +		v = xen_xlate_dev_mem_ptr(p, sz);
   40.27  		if (v == NULL)
   40.28  			break;
   40.29  		if (IS_ERR(v)) {
   40.30 @@ -119,7 +119,7 @@ static ssize_t write_mem(struct file * f
   40.31  		}
   40.32  
   40.33  		ignored = copy_from_user(v, buf, sz);
   40.34 -		xlate_dev_mem_ptr_unmap(v);
   40.35 +		xen_xlate_dev_mem_ptr_unmap(v);
   40.36  		if (ignored) {
   40.37  			written += sz - ignored;
   40.38  			if (written)
    41.1 --- a/drivers/xen/core/Makefile	Mon Jul 09 09:24:03 2007 -0600
    41.2 +++ b/drivers/xen/core/Makefile	Tue Jul 10 08:40:03 2007 -0600
    41.3 @@ -10,3 +10,4 @@ obj-$(CONFIG_HOTPLUG_CPU)	+= cpu_hotplug
    41.4  obj-$(CONFIG_XEN_SYSFS)		+= xen_sysfs.o
    41.5  obj-$(CONFIG_XEN_SMPBOOT)	+= smpboot.o
    41.6  obj-$(CONFIG_KEXEC)		+= machine_kexec.o
    41.7 +obj-$(CONFIG_XEN_XENCOMM)	+= xencomm.o
    42.1 --- a/drivers/xen/core/evtchn.c	Mon Jul 09 09:24:03 2007 -0600
    42.2 +++ b/drivers/xen/core/evtchn.c	Tue Jul 10 08:40:03 2007 -0600
    42.3 @@ -197,6 +197,9 @@ static inline void exit_idle(void) {}
    42.4  	(regs)->IRQ_REG = ~(irq);	\
    42.5  	do_IRQ((regs));			\
    42.6  } while (0)
    42.7 +#elif defined (__powerpc__)
    42.8 +#define do_IRQ(irq, regs)	__do_IRQ(irq, regs)
    42.9 +static inline void exit_idle(void) {}
   42.10  #endif
   42.11  
   42.12  /* Xen will never allocate port zero for any purpose. */
    43.1 --- a/drivers/xen/core/gnttab.c	Mon Jul 09 09:24:03 2007 -0600
    43.2 +++ b/drivers/xen/core/gnttab.c	Tue Jul 10 08:40:03 2007 -0600
    43.3 @@ -430,7 +430,7 @@ static inline unsigned int max_nr_grant_
    43.4  
    43.5  #ifdef CONFIG_XEN
    43.6  
    43.7 -#ifndef __ia64__
    43.8 +#ifdef CONFIG_X86
    43.9  static int map_pte_fn(pte_t *pte, struct page *pmd_page,
   43.10  		      unsigned long addr, void *data)
   43.11  {
   43.12 @@ -448,7 +448,15 @@ static int unmap_pte_fn(pte_t *pte, stru
   43.13  	set_pte_at(&init_mm, addr, pte, __pte(0));
   43.14  	return 0;
   43.15  }
   43.16 -#endif
   43.17 +
   43.18 +void *arch_gnttab_alloc_shared(unsigned long *frames)
   43.19 +{
   43.20 +	struct vm_struct *area;
   43.21 +	area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
   43.22 +	BUG_ON(area == NULL);
   43.23 +	return area->addr;
   43.24 +}
   43.25 +#endif /* CONFIG_X86 */
   43.26  
   43.27  static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
   43.28  {
   43.29 @@ -473,21 +481,16 @@ static int gnttab_map(unsigned int start
   43.30  
   43.31  	BUG_ON(rc || setup.status);
   43.32  
   43.33 -#ifndef __ia64__
   43.34 -	if (shared == NULL) {
   43.35 -		struct vm_struct *area;
   43.36 -		area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
   43.37 -		BUG_ON(area == NULL);
   43.38 -		shared = area->addr;
   43.39 -	}
   43.40 +	if (shared == NULL)
   43.41 +		shared = arch_gnttab_alloc_shared(frames);
   43.42 +
   43.43 +#ifdef CONFIG_X86
   43.44  	rc = apply_to_page_range(&init_mm, (unsigned long)shared,
   43.45  				 PAGE_SIZE * nr_gframes,
   43.46  				 map_pte_fn, &frames);
   43.47  	BUG_ON(rc);
   43.48 -        frames -= nr_gframes; /* adjust after map_pte_fn() */
   43.49 -#else
   43.50 -	shared = __va(frames[0] << PAGE_SHIFT);
   43.51 -#endif
   43.52 +	frames -= nr_gframes; /* adjust after map_pte_fn() */
   43.53 +#endif /* CONFIG_X86 */
   43.54  
   43.55  	kfree(frames);
   43.56  
   43.57 @@ -623,7 +626,7 @@ int gnttab_resume(void)
   43.58  
   43.59  int gnttab_suspend(void)
   43.60  {
   43.61 -#ifndef __ia64__
   43.62 +#ifdef CONFIG_X86
   43.63  	apply_to_page_range(&init_mm, (unsigned long)shared,
   43.64  			    PAGE_SIZE * nr_grant_frames,
   43.65  			    unmap_pte_fn, NULL);
    44.1 --- a/drivers/xen/core/hypervisor_sysfs.c	Mon Jul 09 09:24:03 2007 -0600
    44.2 +++ b/drivers/xen/core/hypervisor_sysfs.c	Tue Jul 10 08:40:03 2007 -0600
    44.3 @@ -11,6 +11,7 @@
    44.4  #include <linux/module.h>
    44.5  #include <linux/kobject.h>
    44.6  #include <xen/hypervisor_sysfs.h>
    44.7 +#include <asm/hypervisor.h>
    44.8  
    44.9  static ssize_t hyp_sysfs_show(struct kobject *kobj,
   44.10  			      struct attribute *attr,
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/drivers/xen/core/xencomm.c	Tue Jul 10 08:40:03 2007 -0600
    45.3 @@ -0,0 +1,192 @@
    45.4 +/*
    45.5 + * This program is free software; you can redistribute it and/or modify
    45.6 + * it under the terms of the GNU General Public License as published by
    45.7 + * the Free Software Foundation; either version 2 of the License, or
    45.8 + * (at your option) any later version.
    45.9 + * 
   45.10 + * This program is distributed in the hope that it will be useful,
   45.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   45.13 + * GNU General Public License for more details.
   45.14 + * 
   45.15 + * You should have received a copy of the GNU General Public License
   45.16 + * along with this program; if not, write to the Free Software
   45.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   45.18 + *
   45.19 + * Copyright (C) IBM Corp. 2006
   45.20 + *
   45.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   45.22 + */
   45.23 +
   45.24 +#include <linux/gfp.h>
   45.25 +#include <linux/mm.h>
   45.26 +#include <asm/page.h>
   45.27 +#include <xen/xencomm.h>
   45.28 +#include <xen/interface/xen.h>
   45.29 +
   45.30 +static int xencomm_init(struct xencomm_desc *desc,
   45.31 +			void *buffer, unsigned long bytes)
   45.32 +{
   45.33 +	unsigned long recorded = 0;
   45.34 +	int i = 0;
   45.35 +
   45.36 +	while ((recorded < bytes) && (i < desc->nr_addrs)) {
   45.37 +		unsigned long vaddr = (unsigned long)buffer + recorded;
   45.38 +		unsigned long paddr;
   45.39 +		int offset;
   45.40 +		int chunksz;
   45.41 +
   45.42 +		offset = vaddr % PAGE_SIZE; /* handle partial pages */
   45.43 +		chunksz = min(PAGE_SIZE - offset, bytes - recorded);
   45.44 +
   45.45 +		paddr = xencomm_vtop(vaddr);
   45.46 +		if (paddr == ~0UL) {
   45.47 +			printk("%s: couldn't translate vaddr %lx\n",
   45.48 +			       __func__, vaddr);
   45.49 +			return -EINVAL;
   45.50 +		}
   45.51 +
   45.52 +		desc->address[i++] = paddr;
   45.53 +		recorded += chunksz;
   45.54 +	}
   45.55 +
   45.56 +	if (recorded < bytes) {
   45.57 +		printk("%s: could only translate %ld of %ld bytes\n",
   45.58 +		       __func__, recorded, bytes);
   45.59 +		return -ENOSPC;
   45.60 +	}
   45.61 +
   45.62 +	/* mark remaining addresses invalid (just for safety) */
   45.63 +	while (i < desc->nr_addrs)
   45.64 +		desc->address[i++] = XENCOMM_INVALID;
   45.65 +
   45.66 +	desc->magic = XENCOMM_MAGIC;
   45.67 +
   45.68 +	return 0;
   45.69 +}
   45.70 +
   45.71 +/* XXX use slab allocator */
   45.72 +static struct xencomm_desc *xencomm_alloc(gfp_t gfp_mask)
   45.73 +{
   45.74 +	struct xencomm_desc *desc;
   45.75 +
   45.76 +	desc = (struct xencomm_desc *)__get_free_page(gfp_mask);
   45.77 +	if (desc == NULL)
   45.78 +		return NULL;
   45.79 +
   45.80 +	desc->nr_addrs = (PAGE_SIZE - sizeof(struct xencomm_desc)) /
   45.81 +			sizeof(*desc->address);
   45.82 +
   45.83 +	return desc;
   45.84 +}
   45.85 +
   45.86 +void xencomm_free(void *desc)
   45.87 +{
   45.88 +	if (desc && !((ulong)desc & XENCOMM_INLINE_FLAG))
   45.89 +		free_page((unsigned long)__va(desc));
   45.90 +}
   45.91 +
   45.92 +static int xencomm_create(void *buffer, unsigned long bytes, struct xencomm_desc **ret, gfp_t gfp_mask)
   45.93 +{
   45.94 +	struct xencomm_desc *desc;
   45.95 +	int rc;
   45.96 +
   45.97 +	pr_debug("%s: %p[%ld]\n", __func__, buffer, bytes);
   45.98 +
   45.99 +	if (bytes == 0) {
  45.100 +		/* don't create a descriptor; Xen recognizes NULL. */
  45.101 +		BUG_ON(buffer != NULL);
  45.102 +		*ret = NULL;
  45.103 +		return 0;
  45.104 +	}
  45.105 +
  45.106 +	BUG_ON(buffer == NULL); /* 'bytes' is non-zero */
  45.107 +
  45.108 +	desc = xencomm_alloc(gfp_mask);
  45.109 +	if (!desc) {
  45.110 +		printk("%s failure\n", "xencomm_alloc");
  45.111 +		return -ENOMEM;
  45.112 +	}
  45.113 +
  45.114 +	rc = xencomm_init(desc, buffer, bytes);
  45.115 +	if (rc) {
  45.116 +		printk("%s failure: %d\n", "xencomm_init", rc);
  45.117 +		xencomm_free(desc);
  45.118 +		return rc;
  45.119 +	}
  45.120 +
  45.121 +	*ret = desc;
  45.122 +	return 0;
  45.123 +}
  45.124 +
  45.125 +/* check if memory address is within VMALLOC region  */
  45.126 +static int is_phys_contiguous(unsigned long addr)
  45.127 +{
  45.128 +	if (!is_kernel_addr(addr))
  45.129 +		return 0;
  45.130 +
  45.131 +	return (addr < VMALLOC_START) || (addr >= VMALLOC_END);
  45.132 +}
  45.133 +
  45.134 +static void *xencomm_create_inline(void *ptr)
  45.135 +{
  45.136 +	unsigned long paddr;
  45.137 +
  45.138 +	BUG_ON(!is_phys_contiguous((unsigned long)ptr));
  45.139 +
  45.140 +	paddr = (unsigned long)xencomm_pa(ptr);
  45.141 +	BUG_ON(paddr & XENCOMM_INLINE_FLAG);
  45.142 +	return (void *)(paddr | XENCOMM_INLINE_FLAG);
  45.143 +}
  45.144 +
  45.145 +/* "mini" routine, for stack-based communications: */
  45.146 +static int xencomm_create_mini(void *buffer,
  45.147 +	unsigned long bytes, struct xencomm_mini *xc_desc,
  45.148 +	struct xencomm_desc **ret)
  45.149 +{
  45.150 +	int rc = 0;
  45.151 +	struct xencomm_desc *desc;
  45.152 +
  45.153 +	desc = (void *)xc_desc; 
  45.154 +
  45.155 +	desc->nr_addrs = XENCOMM_MINI_ADDRS;
  45.156 +
  45.157 +	if (!(rc = xencomm_init(desc, buffer, bytes)))
  45.158 +		*ret = desc;
  45.159 +
  45.160 +	return rc;
  45.161 +}
  45.162 +
  45.163 +void *xencomm_map(void *ptr, unsigned long bytes)
  45.164 +{
  45.165 +	int rc;
  45.166 +	struct xencomm_desc *desc;
  45.167 +
  45.168 +	if (is_phys_contiguous((unsigned long)ptr))
  45.169 +		return xencomm_create_inline(ptr);
  45.170 +
  45.171 +	rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL);
  45.172 +
  45.173 +	if (rc || desc == NULL)
  45.174 +		return NULL;
  45.175 +
  45.176 +	return (void *)__pa(desc);
  45.177 +}
  45.178 +
  45.179 +void *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, 
  45.180 +			struct xencomm_mini *xc_desc)
  45.181 +{
  45.182 +	int rc;
  45.183 +	struct xencomm_desc *desc = NULL;
  45.184 +
  45.185 +	if (is_phys_contiguous((unsigned long)ptr))
  45.186 +		return xencomm_create_inline(ptr);
  45.187 +
  45.188 +	rc = xencomm_create_mini(ptr, bytes, xc_desc,
  45.189 +				&desc);
  45.190 +
  45.191 +	if (rc)
  45.192 +		return NULL;
  45.193 + 
  45.194 +	return (void *)__pa(desc);
  45.195 +}
    46.1 --- a/drivers/xen/netback/Makefile	Mon Jul 09 09:24:03 2007 -0600
    46.2 +++ b/drivers/xen/netback/Makefile	Tue Jul 10 08:40:03 2007 -0600
    46.3 @@ -1,5 +1,5 @@
    46.4  obj-$(CONFIG_XEN_NETDEV_BACKEND) := netbk.o
    46.5  obj-$(CONFIG_XEN_NETDEV_LOOPBACK) += netloop.o
    46.6  
    46.7 -netbk-y   := netback.o xenbus.o interface.o
    46.8 +netbk-y   := netback.o xenbus.o interface.o accel.o
    46.9  netloop-y := loopback.o
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/drivers/xen/netback/accel.c	Tue Jul 10 08:40:03 2007 -0600
    47.3 @@ -0,0 +1,207 @@
    47.4 +/******************************************************************************
    47.5 + * drivers/xen/netback/accel.c
    47.6 + *
    47.7 + * Interface between backend virtual network device and accelerated plugin. 
    47.8 + * 
    47.9 + * Copyright (C) 2007 Solarflare Communications, Inc
   47.10 + * 
   47.11 + * This program is free software; you can redistribute it and/or
   47.12 + * modify it under the terms of the GNU General Public License version 2
   47.13 + * as published by the Free Software Foundation; or, when distributed
   47.14 + * separately from the Linux kernel or incorporated into other
   47.15 + * software packages, subject to the following license:
   47.16 + * 
   47.17 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   47.18 + * of this source file (the "Software"), to deal in the Software without
   47.19 + * restriction, including without limitation the rights to use, copy, modify,
   47.20 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   47.21 + * and to permit persons to whom the Software is furnished to do so, subject to
   47.22 + * the following conditions:
   47.23 + * 
   47.24 + * The above copyright notice and this permission notice shall be included in
   47.25 + * all copies or substantial portions of the Software.
   47.26 + * 
   47.27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   47.28 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   47.29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   47.30 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   47.31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   47.32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   47.33 + * IN THE SOFTWARE.
   47.34 + */
   47.35 +
   47.36 +#include <linux/list.h>
   47.37 +#include <asm/atomic.h>
   47.38 +#include <xen/xenbus.h>
   47.39 +
   47.40 +#include "common.h"
   47.41 +
   47.42 +#if 0
   47.43 +#undef DPRINTK
   47.44 +#define DPRINTK(fmt, args...)						\
   47.45 +	printk("netback/accel (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   47.46 +#endif
   47.47 +
   47.48 +/* 
   47.49 + * A list of available netback accelerator plugin modules (each list
   47.50 + * entry is of type struct netback_accelerator) 
   47.51 + */ 
   47.52 +static struct list_head accelerators_list;
   47.53 +/* Lock used to protect access to accelerators_list */
   47.54 +static spinlock_t accelerators_lock;
   47.55 +
   47.56 +/* 
   47.57 + * Compare a backend to an accelerator, and decide if they are
   47.58 + * compatible (i.e. if the accelerator should be used by the
   47.59 + * backend) 
   47.60 + */
   47.61 +static int match_accelerator(struct backend_info *be, 
   47.62 +			     struct netback_accelerator *accelerator)
   47.63 +{
   47.64 +	/*
   47.65 +	 * This could do with being more sophisticated.  For example,
   47.66 +	 * determine which hardware is being used by each backend from
   47.67 +	 * the bridge and network topology of the domain
   47.68 +	 */
   47.69 +	return be->accelerator == NULL;
   47.70 +}
   47.71 +
   47.72 +/*
   47.73 + * Notify all suitable backends that a new accelerator is available
   47.74 + * and connected.  This will also notify the accelerator plugin module
   47.75 + * that it is being used for a device through the probe hook.
   47.76 + */
   47.77 +static int netback_accelerator_tell_backend(struct device *dev, void *arg)
   47.78 +{
   47.79 +	struct netback_accelerator *accelerator = 
   47.80 +		(struct netback_accelerator *)arg;
   47.81 +	struct xenbus_device *xendev = to_xenbus_device(dev);
   47.82 +
   47.83 +	if (!strcmp("vif", xendev->devicetype)) {
   47.84 +		struct backend_info *be = xendev->dev.driver_data;
   47.85 +
   47.86 +		if (match_accelerator(be, accelerator)) {
   47.87 +			be->accelerator = accelerator;
   47.88 +			atomic_inc(&be->accelerator->use_count);
   47.89 +			be->accelerator->hooks->probe(xendev);
   47.90 +		}
   47.91 +	}
   47.92 +	return 0;
   47.93 +}
   47.94 +
   47.95 +
   47.96 +/*
   47.97 + * Entry point for an netback accelerator plugin module.  Called to
   47.98 + * advertise its presence, and connect to any suitable backends.
   47.99 + */
  47.100 +void netback_connect_accelerator(int id, const char *frontend, 
  47.101 +				 struct netback_accel_hooks *hooks)
  47.102 +{
  47.103 +	struct netback_accelerator *new_accelerator = 
  47.104 +		kmalloc(sizeof(struct netback_accelerator), GFP_KERNEL);
  47.105 +	unsigned frontend_len, flags;
  47.106 +
  47.107 +	if (!new_accelerator) {
  47.108 +		DPRINTK("%s: failed to allocate memory for accelerator\n",
  47.109 +			__FUNCTION__);
  47.110 +		return;
  47.111 +	}
  47.112 +
  47.113 +	new_accelerator->id = id;
  47.114 +	
  47.115 +	frontend_len = strlen(frontend)+1;
  47.116 +	new_accelerator->frontend = kmalloc(frontend_len, GFP_KERNEL);
  47.117 +	if (!new_accelerator->frontend) {
  47.118 +		DPRINTK("%s: failed to allocate memory for frontend string\n",
  47.119 +			__FUNCTION__);
  47.120 +		kfree(new_accelerator);
  47.121 +		return;
  47.122 +	}
  47.123 +	strlcpy(new_accelerator->frontend, frontend, frontend_len);
  47.124 +	
  47.125 +	new_accelerator->hooks = hooks;
  47.126 +
  47.127 +	atomic_set(&new_accelerator->use_count, 0);
  47.128 +	
  47.129 +	spin_lock_irqsave(&accelerators_lock, flags);
  47.130 +	list_add(&new_accelerator->link, &accelerators_list);
  47.131 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  47.132 +	
  47.133 +	/* tell existing backends about new plugin */
  47.134 +	xenbus_for_each_backend(new_accelerator, 
  47.135 +				netback_accelerator_tell_backend);
  47.136 +
  47.137 +}
  47.138 +EXPORT_SYMBOL_GPL(netback_connect_accelerator);
  47.139 +
  47.140 +
  47.141 +/* 
  47.142 + * Disconnect an accerator plugin module that has previously been
  47.143 + * connected.
  47.144 + *
  47.145 + * This should only be allowed when there are no remaining users -
  47.146 + * i.e. it is not necessary to go through and clear all the hooks, as
  47.147 + * they should have already been removed.  This is enforced through a
  47.148 + * usage count and BUG_ON(use!=0), but should be made more user-friendly
  47.149 + */
  47.150 +void netback_disconnect_accelerator(int id, const char *frontend)
  47.151 +{
  47.152 +	struct netback_accelerator *accelerator, *next;
  47.153 +	unsigned flags;
  47.154 +
  47.155 +	spin_lock_irqsave(&accelerators_lock, flags);
  47.156 +	list_for_each_entry_safe(accelerator, next, &accelerators_list, link) {
  47.157 +		if (strcmp(frontend, accelerator->frontend)) {
  47.158 +			BUG_ON(atomic_read(&accelerator->use_count) != 0);
  47.159 +			list_del(&accelerator->link);
  47.160 +			spin_unlock_irqrestore(&accelerators_lock, flags);
  47.161 +			kfree(accelerator->frontend);
  47.162 +			kfree(accelerator);
  47.163 +			return;
  47.164 +		}
  47.165 +	}
  47.166 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  47.167 +}
  47.168 +EXPORT_SYMBOL_GPL(netback_disconnect_accelerator);
  47.169 +
  47.170 +
  47.171 +void netback_probe_accelerators(struct backend_info *be,
  47.172 +				struct xenbus_device *dev)
  47.173 +{
  47.174 +	struct netback_accelerator *accelerator;
  47.175 +	unsigned flags;
  47.176 +
  47.177 +	/* 
  47.178 +	 * Check list of accelerators to see if any is suitable, and
  47.179 +	 * use it if it is.
  47.180 +	 */
  47.181 +	spin_lock_irqsave(&accelerators_lock, flags);
  47.182 +	list_for_each_entry(accelerator, &accelerators_list, link) { 
  47.183 +		if (match_accelerator(be, accelerator)) {
  47.184 +			be->accelerator = accelerator;
  47.185 +			atomic_inc(&be->accelerator->use_count);
  47.186 +			be->accelerator->hooks->probe(dev);
  47.187 +			break;
  47.188 +		}
  47.189 +	}
  47.190 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  47.191 +}
  47.192 +
  47.193 +
  47.194 +void netback_remove_accelerators(struct backend_info *be,
  47.195 +				 struct xenbus_device *dev)
  47.196 +{
  47.197 +	/* Notify the accelerator (if any) of this device's removal */
  47.198 +	if ( be->accelerator ) {
  47.199 +		be->accelerator->hooks->remove(dev);
  47.200 +		atomic_dec(&be->accelerator->use_count);
  47.201 +	}
  47.202 +	be->accelerator = NULL;
  47.203 +}
  47.204 +
  47.205 +
  47.206 +void netif_accel_init(void)
  47.207 +{
  47.208 +	INIT_LIST_HEAD(&accelerators_list);
  47.209 +	spin_lock_init(&accelerators_lock);
  47.210 +}
    48.1 --- a/drivers/xen/netback/common.h	Mon Jul 09 09:24:03 2007 -0600
    48.2 +++ b/drivers/xen/netback/common.h	Tue Jul 10 08:40:03 2007 -0600
    48.3 @@ -45,6 +45,7 @@
    48.4  #include <xen/interface/grant_table.h>
    48.5  #include <xen/gnttab.h>
    48.6  #include <xen/driver_util.h>
    48.7 +#include <xen/xenbus.h>
    48.8  
    48.9  #define DPRINTK(_f, _a...)			\
   48.10  	pr_debug("(file=%s, line=%d) " _f,	\
   48.11 @@ -122,6 +123,49 @@ enum {
   48.12  
   48.13  extern int netbk_copy_skb_mode;
   48.14  
   48.15 +/* Function pointers into netback accelerator plugin modules */
   48.16 +struct netback_accel_hooks {
   48.17 +	int  (*probe)(struct xenbus_device *dev);
   48.18 +	int (*remove)(struct xenbus_device *dev);
   48.19 +};
   48.20 +
   48.21 +/* Structure to track the state of a netback accelerator plugin */
   48.22 +struct netback_accelerator {
   48.23 +	struct list_head link;
   48.24 +	int id;
   48.25 +	char *frontend;
   48.26 +	atomic_t use_count;
   48.27 +	struct netback_accel_hooks *hooks;
   48.28 +};
   48.29 +
   48.30 +struct backend_info {
   48.31 +	struct xenbus_device *dev;
   48.32 +	netif_t *netif;
   48.33 +	enum xenbus_state frontend_state;
   48.34 +
   48.35 +	/* State relating to the netback accelerator */
   48.36 +	void *netback_accel_priv;
   48.37 +	/* The accelerator that this backend is currently using */
   48.38 +	struct netback_accelerator *accelerator;
   48.39 +};
   48.40 +
   48.41 +/* Connect an accelerator plugin module to netback */
   48.42 +extern void netback_connect_accelerator(int id, const char *frontend, 
   48.43 +					struct netback_accel_hooks *hooks);
   48.44 +/* Disconnect a previously connected accelerator pluging module */
   48.45 +extern void netback_disconnect_accelerator(int id, const char *frontend);
   48.46 +
   48.47 +
   48.48 +extern
   48.49 +void netback_probe_accelerators(struct backend_info *be,
   48.50 +				struct xenbus_device *dev);
   48.51 +extern
   48.52 +void netback_remove_accelerators(struct backend_info *be,
   48.53 +				 struct xenbus_device *dev);
   48.54 +extern
   48.55 +void netif_accel_init(void);
   48.56 +
   48.57 +
   48.58  #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
   48.59  #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
   48.60  
    49.1 --- a/drivers/xen/netback/netback.c	Mon Jul 09 09:24:03 2007 -0600
    49.2 +++ b/drivers/xen/netback/netback.c	Tue Jul 10 08:40:03 2007 -0600
    49.3 @@ -1587,6 +1587,8 @@ static int __init netback_init(void)
    49.4  			netbk_copy_skb_mode = NETBK_DELAYED_COPY_SKB;
    49.5  	}
    49.6  
    49.7 +	netif_accel_init();
    49.8 +
    49.9  	netif_xenbus_init();
   49.10  
   49.11  #ifdef NETBE_DEBUG_INTERRUPT
    50.1 --- a/drivers/xen/netback/xenbus.c	Mon Jul 09 09:24:03 2007 -0600
    50.2 +++ b/drivers/xen/netback/xenbus.c	Tue Jul 10 08:40:03 2007 -0600
    50.3 @@ -28,11 +28,6 @@
    50.4      printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
    50.5  #endif
    50.6  
    50.7 -struct backend_info {
    50.8 -	struct xenbus_device *dev;
    50.9 -	netif_t *netif;
   50.10 -	enum xenbus_state frontend_state;
   50.11 -};
   50.12  
   50.13  static int connect_rings(struct backend_info *);
   50.14  static void connect(struct backend_info *);
   50.15 @@ -42,6 +37,8 @@ static int netback_remove(struct xenbus_
   50.16  {
   50.17  	struct backend_info *be = dev->dev.driver_data;
   50.18  
   50.19 +	netback_remove_accelerators(be, dev);
   50.20 +
   50.21  	if (be->netif) {
   50.22  		netif_disconnect(be->netif);
   50.23  		be->netif = NULL;
   50.24 @@ -125,6 +122,8 @@ static int netback_probe(struct xenbus_d
   50.25  		goto fail;
   50.26  	}
   50.27  
   50.28 +	netback_probe_accelerators(be, dev);
   50.29 +
   50.30  	err = xenbus_switch_state(dev, XenbusStateInitWait);
   50.31  	if (err)
   50.32  		goto fail;
    51.1 --- a/drivers/xen/netfront/Makefile	Mon Jul 09 09:24:03 2007 -0600
    51.2 +++ b/drivers/xen/netfront/Makefile	Tue Jul 10 08:40:03 2007 -0600
    51.3 @@ -1,4 +1,4 @@
    51.4  
    51.5  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	:= xennet.o
    51.6  
    51.7 -xennet-objs := netfront.o
    51.8 +xennet-objs := netfront.o accel.o
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/drivers/xen/netfront/accel.c	Tue Jul 10 08:40:03 2007 -0600
    52.3 @@ -0,0 +1,866 @@
    52.4 +/******************************************************************************
    52.5 + * Virtual network driver for conversing with remote driver backends.
    52.6 + *
    52.7 + * Copyright (C) 2007 Solarflare Communications, Inc.
    52.8 + *
    52.9 + * This program is free software; you can redistribute it and/or
   52.10 + * modify it under the terms of the GNU General Public License version 2
   52.11 + * as published by the Free Software Foundation; or, when distributed
   52.12 + * separately from the Linux kernel or incorporated into other
   52.13 + * software packages, subject to the following license:
   52.14 + *
   52.15 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   52.16 + * of this source file (the "Software"), to deal in the Software without
   52.17 + * restriction, including without limitation the rights to use, copy, modify,
   52.18 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   52.19 + * and to permit persons to whom the Software is furnished to do so, subject to
   52.20 + * the following conditions:
   52.21 + *
   52.22 + * The above copyright notice and this permission notice shall be included in
   52.23 + * all copies or substantial portions of the Software.
   52.24 + *
   52.25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   52.26 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   52.27 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   52.28 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   52.29 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   52.30 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   52.31 + * IN THE SOFTWARE.
   52.32 + */
   52.33 +
   52.34 +#include <linux/netdevice.h>
   52.35 +#include <linux/skbuff.h>
   52.36 +#include <linux/list.h>
   52.37 +#include <linux/kref.h>
   52.38 +
   52.39 +#include <xen/xenbus.h>
   52.40 +
   52.41 +#include "netfront.h"
   52.42 +
   52.43 +#define DPRINTK(fmt, args...)				\
   52.44 +	pr_debug("netfront/accel (%s:%d) " fmt,		\
   52.45 +	       __FUNCTION__, __LINE__, ##args)
   52.46 +#define IPRINTK(fmt, args...)				\
   52.47 +	printk(KERN_INFO "netfront/accel: " fmt, ##args)
   52.48 +#define WPRINTK(fmt, args...)				\
   52.49 +	printk(KERN_WARNING "netfront/accel: " fmt, ##args)
   52.50 +
   52.51 +/*
   52.52 + * List of all netfront accelerator plugin modules available.  Each
   52.53 + * list entry is of type struct netfront_accelerator.
   52.54 + */ 
   52.55 +static struct list_head accelerators_list;
   52.56 +
   52.57 +/*
   52.58 + * Lock to protect access to accelerators_list
   52.59 + */
   52.60 +static spinlock_t accelerators_lock;
   52.61 +
   52.62 +/* Forward declaration of kref cleanup functions */
   52.63 +static void accel_kref_release(struct kref *ref);
   52.64 +static void vif_kref_release(struct kref *ref);
   52.65 +
   52.66 +
   52.67 +void netif_init_accel(void)
   52.68 +{
   52.69 +	INIT_LIST_HEAD(&accelerators_list);
   52.70 +	spin_lock_init(&accelerators_lock);
   52.71 +}
   52.72 +
   52.73 +
   52.74 +/* 
   52.75 + * Initialise the accel_vif_state field in the netfront state
   52.76 + */ 
   52.77 +void init_accelerator_vif(struct netfront_info *np,
   52.78 +			  struct xenbus_device *dev)
   52.79 +{
   52.80 +	np->accelerator = NULL;
   52.81 +
   52.82 +	/* It's assumed that these things don't change */
   52.83 +	np->accel_vif_state.np = np;
   52.84 +	np->accel_vif_state.dev = dev;
   52.85 +
   52.86 +	np->accel_vif_state.ready_for_probe = 1;
   52.87 +	np->accel_vif_state.need_probe = NULL;
   52.88 +}
   52.89 +
   52.90 +
   52.91 +/*
   52.92 + * Compare a frontend description string against an accelerator to see
   52.93 + * if they match.  Would ultimately be nice to replace the string with
   52.94 + * a unique numeric identifier for each accelerator.
   52.95 + */
   52.96 +static int match_accelerator(const char *frontend, 
   52.97 +			     struct netfront_accelerator *accelerator)
   52.98 +{
   52.99 +	return strcmp(frontend, accelerator->frontend) == 0;
  52.100 +}
  52.101 +
  52.102 +
  52.103 +/* 
  52.104 + * Add a frontend vif to the list of vifs that is using a netfront
  52.105 + * accelerator plugin module.
  52.106 + */
  52.107 +static void add_accelerator_vif(struct netfront_accelerator *accelerator,
  52.108 +				struct netfront_info *np)
  52.109 +{
  52.110 +	if (np->accelerator == NULL) {
  52.111 +		np->accelerator = accelerator;
  52.112 +		
  52.113 +		list_add(&np->accel_vif_state.link, &accelerator->vif_states);
  52.114 +	} else {
  52.115 +		/* 
  52.116 +		 * May get here legitimately if reconnecting to the
  52.117 +		 * same accelerator, eg. after resume, so check that
  52.118 +		 * is the case
  52.119 +		 */
  52.120 +		BUG_ON(np->accelerator != accelerator);
  52.121 +	}
  52.122 +}
  52.123 +
  52.124 +
  52.125 +/*
  52.126 + * Initialise the state to track an accelerator plugin module.
  52.127 + */ 
  52.128 +static int init_accelerator(const char *frontend, 
  52.129 +			    struct netfront_accelerator **result)
  52.130 +{
  52.131 +	struct netfront_accelerator *accelerator = 
  52.132 +		kmalloc(sizeof(struct netfront_accelerator), GFP_KERNEL);
  52.133 +	int frontend_len;
  52.134 +
  52.135 +	if (!accelerator) {
  52.136 +		DPRINTK("no memory for accelerator\n");
  52.137 +		return -ENOMEM;
  52.138 +	}
  52.139 +
  52.140 +	frontend_len = strlen(frontend) + 1;
  52.141 +	accelerator->frontend = kmalloc(frontend_len, GFP_KERNEL);
  52.142 +	if (!accelerator->frontend) {
  52.143 +		DPRINTK("no memory for accelerator\n");
  52.144 +		kfree(accelerator);
  52.145 +		return -ENOMEM;
  52.146 +	}
  52.147 +	strlcpy(accelerator->frontend, frontend, frontend_len);
  52.148 +	
  52.149 +	INIT_LIST_HEAD(&accelerator->vif_states);
  52.150 +	spin_lock_init(&accelerator->vif_states_lock);
  52.151 +
  52.152 +	accelerator->hooks = NULL;
  52.153 +
  52.154 +	accelerator->ready_for_probe = 1;
  52.155 +	accelerator->need_probe = NULL;
  52.156 +
  52.157 +	list_add(&accelerator->link, &accelerators_list);
  52.158 +
  52.159 +	*result = accelerator;
  52.160 +
  52.161 +	return 0;
  52.162 +}					
  52.163 +
  52.164 +
  52.165 +/* 
  52.166 + * Modify the hooks stored in the per-vif state to match that in the
  52.167 + * netfront accelerator's state.
  52.168 + */
  52.169 +static void 
  52.170 +accelerator_set_vif_state_hooks(struct netfront_accel_vif_state *vif_state)
  52.171 +{
  52.172 +	/* This function must be called with the vif_state_lock held */
  52.173 +
  52.174 +	DPRINTK("%p\n",vif_state);
  52.175 +
  52.176 +	/*
  52.177 +	 * Take references to stop hooks disappearing.
  52.178 +	 * This persists until vif_kref gets to zero.
  52.179 +	 */
  52.180 +	kref_get(&vif_state->np->accelerator->accel_kref);
  52.181 +	/* This persists until vif_state->hooks are cleared */
  52.182 +	kref_init(&vif_state->vif_kref);
  52.183 +
  52.184 +	/* Make sure there are no data path operations going on */
  52.185 +	netif_poll_disable(vif_state->np->netdev);
  52.186 +	netif_tx_lock_bh(vif_state->np->netdev);
  52.187 +
  52.188 +	vif_state->hooks = vif_state->np->accelerator->hooks;
  52.189 +
  52.190 +	netif_tx_unlock_bh(vif_state->np->netdev);
  52.191 +	netif_poll_enable(vif_state->np->netdev);
  52.192 +}
  52.193 +
  52.194 +
  52.195 +static void accelerator_probe_new_vif(struct netfront_info *np,
  52.196 +				      struct xenbus_device *dev, 
  52.197 +				      struct netfront_accelerator *accelerator)
  52.198 +{
  52.199 +	struct netfront_accel_hooks *hooks;
  52.200 +	unsigned flags;
  52.201 +	
  52.202 +	DPRINTK("\n");
  52.203 +
  52.204 +	spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.205 +	
  52.206 +	/*
  52.207 +	 * Include this frontend device on the accelerator's list
  52.208 +	 */
  52.209 +	add_accelerator_vif(accelerator, np);
  52.210 +	
  52.211 +	hooks = accelerator->hooks;
  52.212 +	
  52.213 +	if (hooks) {
  52.214 +		if (np->accel_vif_state.ready_for_probe) {
  52.215 +			np->accel_vif_state.ready_for_probe = 0;
  52.216 +			
  52.217 +			kref_get(&accelerator->accel_kref);
  52.218 +			
  52.219 +			spin_unlock_irqrestore(&accelerator->vif_states_lock,
  52.220 +					       flags);
  52.221 +			
  52.222 +			hooks->new_device(np->netdev, dev);
  52.223 +			
  52.224 +			kref_put(&accelerator->accel_kref,
  52.225 +				 accel_kref_release);
  52.226 +			/* 
  52.227 +			 * Hooks will get linked into vif_state by a
  52.228 +			 * future call by the accelerator to
  52.229 +			 * netfront_accelerator_ready()
  52.230 +			 */
  52.231 +			return;
  52.232 +		} else {
  52.233 +			if (np->accel_vif_state.need_probe != NULL)
  52.234 +				DPRINTK("Probe request on vif awaiting probe\n");
  52.235 +			np->accel_vif_state.need_probe = hooks;
  52.236 +		}
  52.237 +	}
  52.238 +		
  52.239 +	spin_unlock_irqrestore(&accelerator->vif_states_lock,
  52.240 +			       flags);
  52.241 +	return;
  52.242 +}
  52.243 +
  52.244 +/*  
  52.245 + * Request that a particular netfront accelerator plugin is loaded.
  52.246 + * Usually called as a result of the vif configuration specifying
  52.247 + * which one to use.
  52.248 + */
  52.249 +int netfront_load_accelerator(struct netfront_info *np, 
  52.250 +			      struct xenbus_device *dev, 
  52.251 +			      const char *frontend)
  52.252 +{
  52.253 +	struct netfront_accelerator *accelerator;
  52.254 +	int rc;
  52.255 +	unsigned flags;
  52.256 +
  52.257 +	DPRINTK(" %s\n", frontend);
  52.258 +
  52.259 +	spin_lock_irqsave(&accelerators_lock, flags);
  52.260 +
  52.261 +	/* 
  52.262 +	 * Look at list of loaded accelerators to see if the requested
  52.263 +	 * one is already there 
  52.264 +	 */
  52.265 +	list_for_each_entry(accelerator, &accelerators_list, link) {
  52.266 +		if (match_accelerator(frontend, accelerator)) {
  52.267 +			spin_unlock_irqrestore(&accelerators_lock, flags);
  52.268 +
  52.269 +			accelerator_probe_new_vif(np, dev, accelerator);
  52.270 +
  52.271 +			return 0;
  52.272 +		}
  52.273 +	}
  52.274 +
  52.275 +	/* Couldn't find it, so create a new one and load the module */
  52.276 +	if ((rc = init_accelerator(frontend, &accelerator)) < 0) {
  52.277 +		spin_unlock_irqrestore(&accelerators_lock, flags);
  52.278 +		return rc;
  52.279 +	}
  52.280 +
  52.281 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  52.282 +
  52.283 +	/* Include this frontend device on the accelerator's list */
  52.284 +	spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.285 +	add_accelerator_vif(accelerator, np);
  52.286 +	spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
  52.287 +
  52.288 +	DPRINTK("requesting module %s\n", frontend);
  52.289 +
  52.290 +	/* load module */
  52.291 +	request_module("%s", frontend);
  52.292 +
  52.293 +	/*
  52.294 +	 * Module should now call netfront_accelerator_loaded() once
  52.295 +	 * it's up and running, and we can continue from there 
  52.296 +	 */
  52.297 +
  52.298 +	return 0;
  52.299 +}
  52.300 +
  52.301 +
  52.302 +/*
  52.303 + * Go through all the netfront vifs and see if they have requested
  52.304 + * this accelerator.  Notify the accelerator plugin of the relevant
  52.305 + * device if so.  Called when an accelerator plugin module is first
  52.306 + * loaded and connects to netfront.
  52.307 + */
  52.308 +static void 
  52.309 +accelerator_probe_vifs(struct netfront_accelerator *accelerator,
  52.310 +		       struct netfront_accel_hooks *hooks,
  52.311 +		       unsigned lock_flags)
  52.312 +{
  52.313 +	struct netfront_accel_vif_state *vif_state, *tmp;
  52.314 +
  52.315 +	/* Calling function must have taken the vif_states_lock */
  52.316 +
  52.317 +	DPRINTK("%p\n", accelerator);
  52.318 +
  52.319 +	/* 
  52.320 +	 * kref_init() takes a single reference to the hooks that will
  52.321 +	 * persist until the accelerator hooks are removed (e.g. by
  52.322 +	 * accelerator module unload)
  52.323 +	 */
  52.324 +	kref_init(&accelerator->accel_kref);
  52.325 +
  52.326 +	/* 
  52.327 +	 * Store the hooks for future calls to probe a new device, and
  52.328 +	 * to wire into the vif_state once the accelerator plugin is
  52.329 +	 * ready to accelerate each vif
  52.330 +	 */
  52.331 +	BUG_ON(hooks == NULL);
  52.332 +	accelerator->hooks = hooks;
  52.333 +	
  52.334 +	list_for_each_entry_safe(vif_state, tmp, &accelerator->vif_states,
  52.335 +				 link) {
  52.336 +		struct netfront_info *np = vif_state->np;
  52.337 +
  52.338 +		if (vif_state->ready_for_probe) {
  52.339 +			vif_state->ready_for_probe = 0;
  52.340 +			kref_get(&accelerator->accel_kref);
  52.341 +
  52.342 +			/* 
  52.343 +			 * drop lock before calling hook.  hooks are
  52.344 +			 * protected by the kref
  52.345 +			 */
  52.346 +			spin_unlock_irqrestore(&accelerator->vif_states_lock,
  52.347 +					       lock_flags);
  52.348 +			
  52.349 +			hooks->new_device(np->netdev, vif_state->dev);
  52.350 +			
  52.351 +			kref_put(&accelerator->accel_kref, accel_kref_release);
  52.352 +
  52.353 +			/* Retake lock for next go round the loop */
  52.354 +			spin_lock_irqsave(&accelerator->vif_states_lock, lock_flags);
  52.355 +			
  52.356 +			/*
  52.357 +			 * Hooks will get linked into vif_state by a call to
  52.358 +			 * netfront_accelerator_ready() once accelerator
  52.359 +			 * plugin is ready for action
  52.360 +			 */
  52.361 +		} else {
  52.362 +			if (vif_state->need_probe != NULL)
  52.363 +				DPRINTK("Probe request on vif awaiting probe\n");
  52.364 +			vif_state->need_probe = hooks;
  52.365 +		}
  52.366 +	}
  52.367 +	
  52.368 +	/* Return with vif_states_lock held, as on entry */
  52.369 +}
  52.370 +
  52.371 +
  52.372 +/* 
  52.373 + * Wrapper for accelerator_probe_vifs that checks now is a good time
  52.374 + * to do the probe, and postpones till previous state cleared up if
  52.375 + * necessary
  52.376 + */
  52.377 +static void 
  52.378 +accelerator_probe_vifs_on_load(struct netfront_accelerator *accelerator,
  52.379 +			       struct netfront_accel_hooks *hooks)
  52.380 +{
  52.381 +	unsigned flags;
  52.382 +
  52.383 +	DPRINTK("\n");
  52.384 +
  52.385 +	spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.386 +	
  52.387 +	if (accelerator->ready_for_probe) {
  52.388 +		accelerator->ready_for_probe = 0;
  52.389 +		accelerator_probe_vifs(accelerator, hooks, flags);
  52.390 +	} else {
  52.391 +		if (accelerator->need_probe)
  52.392 +			DPRINTK("Probe request on accelerator awaiting probe\n");
  52.393 +		accelerator->need_probe = hooks;
  52.394 +	}
  52.395 +
  52.396 +	spin_unlock_irqrestore(&accelerator->vif_states_lock,
  52.397 +			       flags);
  52.398 +}
  52.399 +
  52.400 +
  52.401 +/* 
  52.402 + * Called by the netfront accelerator plugin module when it has loaded 
  52.403 + */
  52.404 +int netfront_accelerator_loaded(const char *frontend, 
  52.405 +				struct netfront_accel_hooks *hooks)
  52.406 +{
  52.407 +	struct netfront_accelerator *accelerator;
  52.408 +	unsigned flags;
  52.409 +
  52.410 +	spin_lock_irqsave(&accelerators_lock, flags);
  52.411 +
  52.412 +	/* 
  52.413 +	 * Look through list of accelerators to see if it has already
  52.414 +	 * been requested
  52.415 +	 */
  52.416 +	list_for_each_entry(accelerator, &accelerators_list, link) {
  52.417 +		if (match_accelerator(frontend, accelerator)) {
  52.418 +			spin_unlock_irqrestore(&accelerators_lock, flags);
  52.419 +
  52.420 +			accelerator_probe_vifs_on_load(accelerator, hooks);
  52.421 +
  52.422 +			return 0;
  52.423 +		}
  52.424 +	}
  52.425 +
  52.426 +	/*
  52.427 +	 * If it wasn't in the list, add it now so that when it is
  52.428 +	 * requested the caller will find it
  52.429 +	 */
  52.430 +	DPRINTK("Couldn't find matching accelerator (%s)\n",
  52.431 +		frontend);
  52.432 +
  52.433 +	init_accelerator(frontend, &accelerator);
  52.434 +
  52.435 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  52.436 +
  52.437 +	return 0;
  52.438 +}
  52.439 +EXPORT_SYMBOL_GPL(netfront_accelerator_loaded);
  52.440 +
  52.441 +
  52.442 +/* 
  52.443 + * Called by the accelerator module after it has been probed with a
  52.444 + * network device to say that it is ready to start accelerating
  52.445 + * traffic on that device
  52.446 + */
  52.447 +void netfront_accelerator_ready(const char *frontend,
  52.448 +				struct xenbus_device *dev)
  52.449 +{
  52.450 +	struct netfront_accelerator *accelerator;
  52.451 +	struct netfront_accel_vif_state *accel_vif_state;
  52.452 +	unsigned flags, flags1;
  52.453 +
  52.454 +	DPRINTK("%s %p\n", frontend, dev);
  52.455 +
  52.456 +	spin_lock_irqsave(&accelerators_lock, flags);
  52.457 +
  52.458 +	list_for_each_entry(accelerator, &accelerators_list, link) {
  52.459 +		if (match_accelerator(frontend, accelerator)) {
  52.460 +			spin_lock_irqsave
  52.461 +				(&accelerator->vif_states_lock, flags1);
  52.462 +
  52.463 +			list_for_each_entry(accel_vif_state,
  52.464 +					    &accelerator->vif_states, link) {
  52.465 +				if (accel_vif_state->dev == dev)
  52.466 +					accelerator_set_vif_state_hooks
  52.467 +						(accel_vif_state);
  52.468 +			}
  52.469 +
  52.470 +			spin_unlock_irqrestore
  52.471 +				(&accelerator->vif_states_lock, flags1);
  52.472 +			goto done;
  52.473 +		}
  52.474 +	}
  52.475 +
  52.476 + done:
  52.477 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  52.478 +}
  52.479 +EXPORT_SYMBOL_GPL(netfront_accelerator_ready);
  52.480 +
  52.481 +
  52.482 +/* 
  52.483 + * Safely remove the accelerator function hooks from a netfront state.
  52.484 + */
  52.485 +static void accelerator_remove_hooks(struct netfront_accelerator *accelerator,
  52.486 +				     int remove_master)
  52.487 +{
  52.488 +	struct netfront_accel_vif_state *vif_state, *tmp;
  52.489 +	unsigned flags;
  52.490 +
  52.491 +	spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.492 +
  52.493 +	list_for_each_entry_safe(vif_state, tmp,
  52.494 +				 &accelerator->vif_states,
  52.495 +				 link) {
  52.496 +		/* Make sure there are no data path operations going on */
  52.497 +		netif_poll_disable(vif_state->np->netdev);
  52.498 +		netif_tx_lock_bh(vif_state->np->netdev);
  52.499 +
  52.500 +		/* 
  52.501 +		 * Remove the hooks, but leave the vif_state on the
  52.502 +		 * accelerator's list as that signifies this vif is
  52.503 +		 * interested in using that accelerator if it becomes
  52.504 +		 * available again
  52.505 +		 */
  52.506 +		vif_state->hooks = NULL;
  52.507 +		
  52.508 +		netif_tx_unlock_bh(vif_state->np->netdev);
  52.509 +		netif_poll_enable(vif_state->np->netdev);
  52.510 +
  52.511 +		/* 
  52.512 +		 * Remove the reference taken when the vif_state hooks
  52.513 +		 * were set, must be called without lock held
  52.514 +		 */
  52.515 +		spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
  52.516 +		kref_put(&vif_state->vif_kref, vif_kref_release);
  52.517 +		spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.518 +	}
  52.519 +	
  52.520 +	if(remove_master)
  52.521 +		accelerator->hooks = NULL;
  52.522 +
  52.523 +	spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
  52.524 +
  52.525 +	if(remove_master)
  52.526 +		/* Remove the reference taken when module loaded */ 
  52.527 +		kref_put(&accelerator->accel_kref, accel_kref_release);
  52.528 +}
  52.529 +
  52.530 +
  52.531 +/* 
  52.532 + * Called by a netfront accelerator when it is unloaded.  This safely
  52.533 + * removes the hooks into the plugin and blocks until all devices have
  52.534 + * finished using it, so on return it is safe to unload.
  52.535 + */
  52.536 +void netfront_accelerator_stop(const char *frontend, int unloading)
  52.537 +{
  52.538 +	struct netfront_accelerator *accelerator;
  52.539 +	unsigned flags;
  52.540 +
  52.541 +	spin_lock_irqsave(&accelerators_lock, flags);
  52.542 +
  52.543 +	list_for_each_entry(accelerator, &accelerators_list, link) {
  52.544 +		if (match_accelerator(frontend, accelerator)) {
  52.545 +			spin_unlock_irqrestore(&accelerators_lock, flags);
  52.546 +
  52.547 +			/* 
  52.548 +			 * Use semaphore to ensure we know when all
  52.549 +			 * uses of hooks are complete
  52.550 +			 */
  52.551 +			sema_init(&accelerator->exit_semaphore, 0);
  52.552 +
  52.553 +			accelerator_remove_hooks(accelerator, unloading);
  52.554 +
  52.555 +			if (unloading)
  52.556 +				/* Wait for hooks to be unused, then return */
  52.557 +				down(&accelerator->exit_semaphore);
  52.558 +			
  52.559 +			return;
  52.560 +		}
  52.561 +	}
  52.562 +	spin_unlock_irqrestore(&accelerators_lock, flags);
  52.563 +}
  52.564 +EXPORT_SYMBOL_GPL(netfront_accelerator_stop);
  52.565 +
  52.566 +
  52.567 +
  52.568 +int netfront_check_accelerator_queue_busy(struct net_device *dev,
  52.569 +					  struct netfront_info *np)
  52.570 +{
  52.571 +	struct netfront_accel_hooks *hooks;
  52.572 +	int rc = 1;
  52.573 +	unsigned flags;
  52.574 +
  52.575 +	/*
  52.576 +	 * Call the check busy accelerator hook. The use count for the
  52.577 +	 * accelerator's hooks is incremented for the duration of the
  52.578 +	 * call to prevent the accelerator being able to modify the
  52.579 +	 * hooks in the middle (by, for example, unloading)
  52.580 +	 */ 
  52.581 +	if (np->accel_vif_state.hooks) {
  52.582 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.583 +		hooks = np->accel_vif_state.hooks;
  52.584 +		if (hooks) {
  52.585 +			kref_get(&np->accel_vif_state.vif_kref);
  52.586 +			spin_unlock_irqrestore
  52.587 +				(&np->accelerator->vif_states_lock, flags);
  52.588 +
  52.589 +			rc = np->accel_vif_state.hooks->check_busy(dev);
  52.590 +			
  52.591 +			kref_put(&np->accel_vif_state.vif_kref,
  52.592 +				 vif_kref_release);
  52.593 +		} else {
  52.594 +			spin_unlock_irqrestore
  52.595 +				(&np->accelerator->vif_states_lock, flags);
  52.596 +		}
  52.597 +	}
  52.598 +
  52.599 +	return rc;
  52.600 +}
  52.601 +
  52.602 +
  52.603 +int netfront_accelerator_call_remove(struct netfront_info *np,
  52.604 +				     struct xenbus_device *dev)
  52.605 +{
  52.606 +	struct netfront_accel_hooks *hooks;
  52.607 +	unsigned flags;
  52.608 +	int rc = 0;
  52.609 +
  52.610 +	/* 
  52.611 +	 * Call the remove accelerator hook. The use count for the
  52.612 +	 * accelerator's hooks is incremented for the duration of the
  52.613 +	 * call to prevent the accelerator being able to modify the
  52.614 +	 * hooks in the middle (by, for example, unloading)
  52.615 +	 */ 
  52.616 +	if (np->accel_vif_state.hooks) {
  52.617 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.618 +		hooks = np->accel_vif_state.hooks;
  52.619 +		if (hooks) {
  52.620 +			kref_get(&np->accel_vif_state.vif_kref);
  52.621 +			spin_unlock_irqrestore
  52.622 +				(&np->accelerator->vif_states_lock, flags);
  52.623 +
  52.624 +			rc = np->accel_vif_state.hooks->remove(dev);
  52.625 +
  52.626 +			kref_put(&np->accel_vif_state.vif_kref,
  52.627 +				 vif_kref_release);
  52.628 +		} else {
  52.629 +			spin_unlock_irqrestore
  52.630 +				(&np->accelerator->vif_states_lock, flags);
  52.631 +		}
  52.632 +	}
  52.633 +	return rc;
  52.634 +}
  52.635 +
  52.636 +
  52.637 +int netfront_accelerator_call_suspend(struct netfront_info *np,
  52.638 +				      struct xenbus_device *dev)
  52.639 +{
  52.640 +	struct netfront_accel_hooks *hooks;
  52.641 +	unsigned flags;
  52.642 +	int rc = 0;
  52.643 +
  52.644 +	IPRINTK("netfront_accelerator_call_suspend\n");
  52.645 +
  52.646 +	/* 
  52.647 +	 *  Call the suspend accelerator hook.  The use count for the
  52.648 +	 *  accelerator's hooks is incremented for the duration of
  52.649 +	 *  the call to prevent the accelerator being able to modify
  52.650 +	 *  the hooks in the middle (by, for example, unloading)
  52.651 +	 */
  52.652 +	if (np->accel_vif_state.hooks) {
  52.653 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.654 +		hooks = np->accel_vif_state.hooks;
  52.655 +		if (hooks) {
  52.656 +			kref_get(&np->accel_vif_state.vif_kref);
  52.657 +			spin_unlock_irqrestore
  52.658 +				(&np->accelerator->vif_states_lock, flags);
  52.659 +
  52.660 +			rc = np->accel_vif_state.hooks->suspend(dev);
  52.661 +
  52.662 +			kref_put(&np->accel_vif_state.vif_kref,
  52.663 +				 vif_kref_release);
  52.664 +		} else {
  52.665 +			spin_unlock_irqrestore
  52.666 +				(&np->accelerator->vif_states_lock, flags);
  52.667 +		}
  52.668 +	}
  52.669 +	return rc;
  52.670 +}
  52.671 +
  52.672 +
  52.673 +int netfront_accelerator_call_suspend_cancel(struct netfront_info *np,
  52.674 +					     struct xenbus_device *dev)
  52.675 +{
  52.676 +	struct netfront_accel_hooks *hooks;
  52.677 +	unsigned flags;
  52.678 +	int rc = 0;
  52.679 +
  52.680 +	IPRINTK(" netfront_accelerator_call_suspend_cancel\n");
  52.681 +
  52.682 +	/* 
  52.683 +	 *  Call the suspend_cancel accelerator hook.  The use count
  52.684 +	 *  for the accelerator's hooks is incremented for the
  52.685 +	 *  duration of the call to prevent the accelerator being able
  52.686 +	 *  to modify the hooks in the middle (by, for example,
  52.687 +	 *  unloading)
  52.688 +	 */
  52.689 +	if (np->accel_vif_state.hooks) {
  52.690 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.691 +		hooks = np->accel_vif_state.hooks;
  52.692 +		if (hooks) {
  52.693 +			kref_get(&np->accel_vif_state.vif_kref);
  52.694 +			spin_unlock_irqrestore
  52.695 +				(&np->accelerator->vif_states_lock, flags);
  52.696 +
  52.697 +			rc = np->accel_vif_state.hooks->suspend_cancel(dev);
  52.698 +
  52.699 +			kref_put(&np->accel_vif_state.vif_kref,
  52.700 +				 vif_kref_release);
  52.701 +		} else {
  52.702 +			spin_unlock_irqrestore
  52.703 +				(&np->accelerator->vif_states_lock, flags);
  52.704 +		}
  52.705 +	}
  52.706 +	return rc;
  52.707 +}
  52.708 +
  52.709 +
  52.710 +int netfront_accelerator_call_resume(struct netfront_info *np,
  52.711 +				     struct xenbus_device *dev)
  52.712 +{
  52.713 +	struct netfront_accel_hooks *hooks;
  52.714 +	unsigned flags;
  52.715 +	int rc = 0;
  52.716 +
  52.717 +	/* 
  52.718 +	 *  Call the resume accelerator hook.  The use count for the
  52.719 +	 *  accelerator's hooks is incremented for the duration of
  52.720 +	 *  the call to prevent the accelerator being able to modify
  52.721 +	 *  the hooks in the middle (by, for example, unloading)
  52.722 +	 */
  52.723 +	if (np->accel_vif_state.hooks) {
  52.724 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.725 +		hooks = np->accel_vif_state.hooks;
  52.726 +		if (hooks) {
  52.727 +			kref_get(&np->accel_vif_state.vif_kref);
  52.728 +			spin_unlock_irqrestore
  52.729 +				(&np->accelerator->vif_states_lock, flags);
  52.730 +
  52.731 +			rc = np->accel_vif_state.hooks->resume(dev);
  52.732 +
  52.733 +			kref_put(&np->accel_vif_state.vif_kref,
  52.734 +				 vif_kref_release);
  52.735 +		} else {
  52.736 +			spin_unlock_irqrestore
  52.737 +				(&np->accelerator->vif_states_lock, flags);
  52.738 +		}
  52.739 +	}
  52.740 +	return rc;
  52.741 +}
  52.742 +
  52.743 +
  52.744 +void netfront_accelerator_call_backend_changed(struct netfront_info *np,
  52.745 +					       struct xenbus_device *dev,
  52.746 +					       enum xenbus_state backend_state)
  52.747 +{
  52.748 +	struct netfront_accel_hooks *hooks;
  52.749 +	unsigned flags;
  52.750 +
  52.751 +	/* 
  52.752 +	 * Call the backend_changed accelerator hook. The use count
  52.753 +	 * for the accelerator's hooks is incremented for the duration
  52.754 +	 * of the call to prevent the accelerator being able to modify
  52.755 +	 * the hooks in the middle (by, for example, unloading)
  52.756 +	 */
  52.757 +	if (np->accel_vif_state.hooks) {
  52.758 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.759 +		hooks = np->accel_vif_state.hooks;
  52.760 +		if (hooks) {
  52.761 +			kref_get(&np->accel_vif_state.vif_kref);
  52.762 +			spin_unlock_irqrestore
  52.763 +				(&np->accelerator->vif_states_lock, flags);
  52.764 +
  52.765 + 			np->accel_vif_state.hooks->backend_changed
  52.766 + 				(dev, backend_state);
  52.767 +
  52.768 +			kref_put(&np->accel_vif_state.vif_kref,
  52.769 +				 vif_kref_release);
  52.770 +		} else {
  52.771 +			spin_unlock_irqrestore
  52.772 +				(&np->accelerator->vif_states_lock, flags);
  52.773 +		}
  52.774 +	}
  52.775 +}
  52.776 +
  52.777 +
  52.778 +void netfront_accelerator_call_stop_napi_irq(struct netfront_info *np,
  52.779 +					     struct net_device *dev)
  52.780 +{
  52.781 +	struct netfront_accel_hooks *hooks;
  52.782 +	unsigned flags;
  52.783 +
  52.784 +	/* 
  52.785 +	 * Call the stop_napi_interrupts accelerator hook.  The use
  52.786 +	 * count for the accelerator's hooks is incremented for the
  52.787 +	 * duration of the call to prevent the accelerator being able
  52.788 +	 * to modify the hooks in the middle (by, for example,
  52.789 +	 * unloading)
  52.790 +	 */
  52.791 +
  52.792 +	if (np->accel_vif_state.hooks) {
  52.793 +		spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
  52.794 +		hooks = np->accel_vif_state.hooks;
  52.795 +		if (hooks) {
  52.796 +			kref_get(&np->accel_vif_state.vif_kref);
  52.797 +			spin_unlock_irqrestore
  52.798 +				(&np->accelerator->vif_states_lock, flags);
  52.799 +
  52.800 + 			np->accel_vif_state.hooks->stop_napi_irq(dev);
  52.801 +		
  52.802 +			kref_put(&np->accel_vif_state.vif_kref,
  52.803 +				 vif_kref_release);
  52.804 +		} else {
  52.805 +			spin_unlock_irqrestore
  52.806 +				(&np->accelerator->vif_states_lock, flags);
  52.807 +		}
  52.808 +	}
  52.809 +}
  52.810 +
  52.811 +
  52.812 +/* 
  52.813 + * Once all users of hooks have kref_put()'d we can signal that it's
  52.814 + * safe to unload
  52.815 + */ 
  52.816 +static void accel_kref_release(struct kref *ref)
  52.817 +{
  52.818 +	struct netfront_accelerator *accelerator =
  52.819 +		container_of(ref, struct netfront_accelerator, accel_kref);
  52.820 +	struct netfront_accel_hooks *hooks;
  52.821 +	unsigned flags;
  52.822 +
  52.823 +	DPRINTK("%p\n", accelerator);
  52.824 +
  52.825 +	/* Signal that all users of hooks are done */
  52.826 +	up(&accelerator->exit_semaphore);
  52.827 +
  52.828 +	spin_lock_irqsave(&accelerator->vif_states_lock, flags);
  52.829 +	if (accelerator->need_probe) {
  52.830 +		hooks = accelerator->need_probe;
  52.831 +		accelerator->need_probe = NULL;
  52.832 +		accelerator_probe_vifs(accelerator, hooks, flags);
  52.833 +	} 
  52.834 +	else
  52.835 +		accelerator->ready_for_probe = 1;
  52.836 +
  52.837 +	spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
  52.838 +}
  52.839 +
  52.840 +
  52.841 +static void vif_kref_release(struct kref *ref)
  52.842 +{
  52.843 +	struct netfront_accel_vif_state *vif_state = 
  52.844 +		container_of(ref, struct netfront_accel_vif_state, vif_kref);
  52.845 +	struct netfront_accel_hooks *hooks;
  52.846 +	unsigned flags;
  52.847 +
  52.848 +	DPRINTK("%p\n", vif_state);
  52.849 +
  52.850 +	/* 
  52.851 +	 * Now that this vif has finished using the hooks, it can
  52.852 +	 * decrement the accelerator's global copy ref count 
  52.853 +	 */
  52.854 +	kref_put(&vif_state->np->accelerator->accel_kref, accel_kref_release);
  52.855 +
  52.856 +	spin_lock_irqsave(&vif_state->np->accelerator->vif_states_lock, flags);
  52.857 +	if (vif_state->need_probe) {
  52.858 +		hooks = vif_state->need_probe;
  52.859 +		vif_state->need_probe = NULL;
  52.860 +		spin_unlock_irqrestore
  52.861 +			(&vif_state->np->accelerator->vif_states_lock, flags);
  52.862 +		hooks->new_device(vif_state->np->netdev, vif_state->dev);
  52.863 +	} else {
  52.864 +		vif_state->ready_for_probe = 1;
  52.865 +		spin_unlock_irqrestore
  52.866 +			(&vif_state->np->accelerator->vif_states_lock, flags);
  52.867 +	}
  52.868 +}
  52.869 +
    53.1 --- a/drivers/xen/netfront/netfront.c	Mon Jul 09 09:24:03 2007 -0600
    53.2 +++ b/drivers/xen/netfront/netfront.c	Tue Jul 10 08:40:03 2007 -0600
    53.3 @@ -3,6 +3,7 @@
    53.4   *
    53.5   * Copyright (c) 2002-2005, K A Fraser
    53.6   * Copyright (c) 2005, XenSource Ltd
    53.7 + * Copyright (C) 2007 Solarflare Communications, Inc.
    53.8   *
    53.9   * This program is free software; you can redistribute it and/or
   53.10   * modify it under the terms of the GNU General Public License version 2
   53.11 @@ -62,6 +63,7 @@
   53.12  #include <asm/uaccess.h>
   53.13  #include <xen/interface/grant_table.h>
   53.14  #include <xen/gnttab.h>
   53.15 +#include <xen/hypercall.h>
   53.16  
   53.17  #ifdef HAVE_XEN_PLATFORM_COMPAT_H
   53.18  #include <xen/platform-compat.h>
   53.19 @@ -74,6 +76,8 @@ struct netfront_cb {
   53.20  
   53.21  #define NETFRONT_SKB_CB(skb)	((struct netfront_cb *)((skb)->cb))
   53.22  
   53.23 +#include "netfront.h"
   53.24 +
   53.25  /*
   53.26   * Mutually-exclusive module options to select receive data path:
   53.27   *  rx_copy : Packets are copied by network backend into local memory
   53.28 @@ -144,57 +148,6 @@ static inline int netif_needs_gso(struct
   53.29  
   53.30  #define GRANT_INVALID_REF	0
   53.31  
   53.32 -#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
   53.33 -#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
   53.34 -
   53.35 -struct netfront_info {
   53.36 -	struct list_head list;
   53.37 -	struct net_device *netdev;
   53.38 -
   53.39 -	struct net_device_stats stats;
   53.40 -
   53.41 -	struct netif_tx_front_ring tx;
   53.42 -	struct netif_rx_front_ring rx;
   53.43 -
   53.44 -	spinlock_t   tx_lock;
   53.45 -	spinlock_t   rx_lock;
   53.46 -
   53.47 -	unsigned int irq;
   53.48 -	unsigned int copying_receiver;
   53.49 -	unsigned int carrier;
   53.50 -
   53.51 -	/* Receive-ring batched refills. */
   53.52 -#define RX_MIN_TARGET 8
   53.53 -#define RX_DFL_MIN_TARGET 64
   53.54 -#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
   53.55 -	unsigned rx_min_target, rx_max_target, rx_target;
   53.56 -	struct sk_buff_head rx_batch;
   53.57 -
   53.58 -	struct timer_list rx_refill_timer;
   53.59 -
   53.60 -	/*
   53.61 -	 * {tx,rx}_skbs store outstanding skbuffs. The first entry in tx_skbs
   53.62 -	 * is an index into a chain of free entries.
   53.63 -	 */
   53.64 -	struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1];
   53.65 -	struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
   53.66 -
   53.67 -#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
   53.68 -	grant_ref_t gref_tx_head;
   53.69 -	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
   53.70 -	grant_ref_t gref_rx_head;
   53.71 -	grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
   53.72 -
   53.73 -	struct xenbus_device *xbdev;
   53.74 -	int tx_ring_ref;
   53.75 -	int rx_ring_ref;
   53.76 -	u8 mac[ETH_ALEN];
   53.77 -
   53.78 -	unsigned long rx_pfn_array[NET_RX_RING_SIZE];
   53.79 -	struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
   53.80 -	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
   53.81 -};
   53.82 -
   53.83  struct netfront_rx_info {
   53.84  	struct netif_rx_response rx;
   53.85  	struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
   53.86 @@ -334,6 +287,8 @@ static int __devexit netfront_remove(str
   53.87  
   53.88  	DPRINTK("%s\n", dev->nodename);
   53.89  
   53.90 +	netfront_accelerator_call_remove(info, dev);
   53.91 +
   53.92  	netif_disconnect_backend(info);
   53.93  
   53.94  	del_timer_sync(&info->rx_refill_timer);
   53.95 @@ -347,6 +302,21 @@ static int __devexit netfront_remove(str
   53.96  	return 0;
   53.97  }
   53.98  
   53.99 +
  53.100 +static int netfront_suspend(struct xenbus_device *dev)
  53.101 +{
  53.102 +	struct netfront_info *info = dev->dev.driver_data;
  53.103 +	return netfront_accelerator_call_suspend(info, dev);
  53.104 +}
  53.105 +
  53.106 +
  53.107 +static int netfront_suspend_cancel(struct xenbus_device *dev)
  53.108 +{
  53.109 +	struct netfront_info *info = dev->dev.driver_data;
  53.110 +	return netfront_accelerator_call_suspend_cancel(info, dev);
  53.111 +}
  53.112 +
  53.113 +
  53.114  /**
  53.115   * We are reconnecting to the backend, due to a suspend/resume, or a backend
  53.116   * driver restart.  We tear down our netif structure and recreate it, but
  53.117 @@ -359,6 +329,8 @@ static int netfront_resume(struct xenbus
  53.118  
  53.119  	DPRINTK("%s\n", dev->nodename);
  53.120  
  53.121 +	netfront_accelerator_call_resume(info, dev);
  53.122 +
  53.123  	netif_disconnect_backend(info);
  53.124  	return 0;
  53.125  }
  53.126 @@ -577,6 +549,8 @@ static void backend_changed(struct xenbu
  53.127  		xenbus_frontend_closed(dev);
  53.128  		break;
  53.129  	}
  53.130 +
  53.131 +	netfront_accelerator_call_backend_changed(np, dev, backend_state);
  53.132  }
  53.133  
  53.134  /** Send a packet on a net device to encourage switches to learn the
  53.135 @@ -613,16 +587,30 @@ static inline int netfront_tx_slot_avail
  53.136  		(TX_MAX_TARGET - MAX_SKB_FRAGS - 2));
  53.137  }
  53.138  
  53.139 +
  53.140  static inline void network_maybe_wake_tx(struct net_device *dev)
  53.141  {
  53.142  	struct netfront_info *np = netdev_priv(dev);
  53.143  
  53.144  	if (unlikely(netif_queue_stopped(dev)) &&
  53.145  	    netfront_tx_slot_available(np) &&
  53.146 -	    likely(netif_running(dev)))
  53.147 +	    likely(netif_running(dev)) &&
  53.148 +	    netfront_check_accelerator_queue_busy(dev, np))
  53.149  		netif_wake_queue(dev);
  53.150  }
  53.151  
  53.152 +
  53.153 +int netfront_check_queue_busy(struct net_device *dev)
  53.154 +{
  53.155 +	struct netfront_info *np = netdev_priv(dev);
  53.156 +
  53.157 +	return unlikely(netif_queue_stopped(dev)) &&
  53.158 +		netfront_tx_slot_available(np) &&
  53.159 +		likely(netif_running(dev));
  53.160 +}
  53.161 +EXPORT_SYMBOL(netfront_check_queue_busy);
  53.162 +
  53.163 +
  53.164  static int network_open(struct net_device *dev)
  53.165  {
  53.166  	struct netfront_info *np = netdev_priv(dev);
  53.167 @@ -633,8 +621,11 @@ static int network_open(struct net_devic
  53.168  	if (netfront_carrier_ok(np)) {
  53.169  		network_alloc_rx_buffers(dev);
  53.170  		np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
  53.171 -		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
  53.172 +		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)){
  53.173 +			netfront_accelerator_call_stop_napi_irq(np, dev);
  53.174 +
  53.175  			netif_rx_schedule(dev);
  53.176 +		}
  53.177  	}
  53.178  	spin_unlock_bh(&np->rx_lock);
  53.179  
  53.180 @@ -702,6 +693,10 @@ static void network_tx_buf_gc(struct net
  53.181  static void rx_refill_timeout(unsigned long data)
  53.182  {
  53.183  	struct net_device *dev = (struct net_device *)data;
  53.184 +	struct netfront_info *np = netdev_priv(dev);
  53.185 +
  53.186 +	netfront_accelerator_call_stop_napi_irq(np, dev);
  53.187 +
  53.188  	netif_rx_schedule(dev);
  53.189  }
  53.190  
  53.191 @@ -941,6 +936,13 @@ static int network_start_xmit(struct sk_
  53.192  	unsigned int offset = offset_in_page(data);
  53.193  	unsigned int len = skb_headlen(skb);
  53.194  
  53.195 +	/* Check the fast path, if hooks are available */
  53.196 + 	if (np->accel_vif_state.hooks && 
  53.197 + 	    np->accel_vif_state.hooks->start_xmit(skb, dev)) { 
  53.198 + 		/* Fast path has sent this packet */ 
  53.199 + 		return 0; 
  53.200 + 	} 
  53.201 +
  53.202  	frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
  53.203  	if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
  53.204  		printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
  53.205 @@ -1044,8 +1046,11 @@ static irqreturn_t netif_int(int irq, vo
  53.206  	if (likely(netfront_carrier_ok(np))) {
  53.207  		network_tx_buf_gc(dev);
  53.208  		/* Under tx_lock: protects access to rx shared-ring indexes. */
  53.209 -		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
  53.210 +		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) {
  53.211 +			netfront_accelerator_call_stop_napi_irq(np, dev);
  53.212 +
  53.213  			netif_rx_schedule(dev);
  53.214 +		}
  53.215  	}
  53.216  
  53.217  	spin_unlock_irqrestore(&np->tx_lock, flags);
  53.218 @@ -1305,7 +1310,7 @@ static int netif_poll(struct net_device 
  53.219  	struct netif_extra_info *extras = rinfo.extras;
  53.220  	RING_IDX i, rp;
  53.221  	struct multicall_entry *mcl;
  53.222 -	int work_done, budget, more_to_do = 1;
  53.223 +	int work_done, budget, more_to_do = 1, accel_more_to_do = 1;
  53.224  	struct sk_buff_head rxq;
  53.225  	struct sk_buff_head errq;
  53.226  	struct sk_buff_head tmpq;
  53.227 @@ -1472,6 +1477,20 @@ err:
  53.228  
  53.229  	network_alloc_rx_buffers(dev);
  53.230  
  53.231 +	if (work_done < budget) {
  53.232 +		/* there's some spare capacity, try the accelerated path */
  53.233 +		int accel_budget = budget - work_done;
  53.234 +		int accel_budget_start = accel_budget;
  53.235 +
  53.236 + 		if (np->accel_vif_state.hooks) { 
  53.237 + 			accel_more_to_do =  
  53.238 + 				np->accel_vif_state.hooks->netdev_poll 
  53.239 + 				(dev, &accel_budget); 
  53.240 + 			work_done += (accel_budget_start - accel_budget); 
  53.241 + 		} else
  53.242 +			accel_more_to_do = 0;
  53.243 +	}
  53.244 +
  53.245  	*pbudget   -= work_done;
  53.246  	dev->quota -= work_done;
  53.247  
  53.248 @@ -1479,15 +1498,26 @@ err:
  53.249  		local_irq_save(flags);
  53.250  
  53.251  		RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
  53.252 -		if (!more_to_do)
  53.253 +
  53.254 +		if (!more_to_do && !accel_more_to_do && 
  53.255 +		    np->accel_vif_state.hooks) {
  53.256 +			/* 
  53.257 +			 *  Slow path has nothing more to do, see if
  53.258 +			 *  fast path is likewise
  53.259 +			 */
  53.260 +			accel_more_to_do = 
  53.261 + 				np->accel_vif_state.hooks->start_napi_irq(dev);
  53.262 +		}
  53.263 +
  53.264 +		if (!more_to_do && !accel_more_to_do)
  53.265  			__netif_rx_complete(dev);
  53.266  
  53.267  		local_irq_restore(flags);
  53.268  	}
  53.269  
  53.270  	spin_unlock(&np->rx_lock);
  53.271 -
  53.272 -	return more_to_do;
  53.273 +	
  53.274 +	return more_to_do | accel_more_to_do;
  53.275  }
  53.276  
  53.277  static void netif_release_tx_bufs(struct netfront_info *np)
  53.278 @@ -1687,7 +1717,9 @@ static int network_connect(struct net_de
  53.279  	struct sk_buff *skb;
  53.280  	grant_ref_t ref;
  53.281  	netif_rx_request_t *req;
  53.282 -	unsigned int feature_rx_copy, feature_rx_flip;
  53.283 +	unsigned int feature_rx_copy, feature_rx_flip, feature_accel;
  53.284 +	char *accel_frontend;
  53.285 +	int accel_len;
  53.286  
  53.287  	err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
  53.288  			   "feature-rx-copy", "%u", &feature_rx_copy);
  53.289 @@ -1698,6 +1730,12 @@ static int network_connect(struct net_de
  53.290  	if (err != 1)
  53.291  		feature_rx_flip = 1;
  53.292  
  53.293 +	feature_accel = 1;
  53.294 +	accel_frontend = xenbus_read(XBT_NIL, np->xbdev->otherend, 
  53.295 +				     "accel", &accel_len);
  53.296 +	if (IS_ERR(accel_frontend)) 
  53.297 +		feature_accel = 0;
  53.298 +
  53.299  	/*
  53.300  	 * Copy packets on receive path if:
  53.301  	 *  (a) This was requested by user, and the backend supports it; or
  53.302 @@ -1710,9 +1748,14 @@ static int network_connect(struct net_de
  53.303  	if (err)
  53.304  		return err;
  53.305  
  53.306 +	if (feature_accel) {
  53.307 +		netfront_load_accelerator(np, np->xbdev, accel_frontend);
  53.308 +		kfree(accel_frontend);
  53.309 +	}
  53.310 +
  53.311  	xennet_set_features(dev);
  53.312  
  53.313 -	IPRINTK("device %s has %sing receive path.\n",
  53.314 +	DPRINTK("device %s has %sing receive path.\n",
  53.315  		dev->name, np->copying_receiver ? "copy" : "flipp");
  53.316  
  53.317  	spin_lock_bh(&np->rx_lock);
  53.318 @@ -1956,6 +1999,8 @@ static struct net_device * __devinit cre
  53.319  	spin_lock_init(&np->tx_lock);
  53.320  	spin_lock_init(&np->rx_lock);
  53.321  
  53.322 +	init_accelerator_vif(np, dev);
  53.323 +
  53.324  	skb_queue_head_init(&np->rx_batch);
  53.325  	np->rx_target     = RX_DFL_MIN_TARGET;
  53.326  	np->rx_min_target = RX_DFL_MIN_TARGET;
  53.327 @@ -2081,6 +2126,8 @@ static struct xenbus_driver netfront = {
  53.328  	.ids = netfront_ids,
  53.329  	.probe = netfront_probe,
  53.330  	.remove = __devexit_p(netfront_remove),
  53.331 +	.suspend = netfront_suspend,
  53.332 +	.suspend_cancel = netfront_suspend_cancel,
  53.333  	.resume = netfront_resume,
  53.334  	.otherend_changed = backend_changed,
  53.335  };
  53.336 @@ -2110,6 +2157,8 @@ static int __init netif_init(void)
  53.337  	if (is_initial_xendomain())
  53.338  		return 0;
  53.339  
  53.340 +	netif_init_accel();
  53.341 +
  53.342  	IPRINTK("Initialising virtual ethernet driver.\n");
  53.343  
  53.344  	(void)register_inetaddr_notifier(&notifier_inetdev);
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/drivers/xen/netfront/netfront.h	Tue Jul 10 08:40:03 2007 -0600
    54.3 @@ -0,0 +1,297 @@
    54.4 +/******************************************************************************
    54.5 + * Virtual network driver for conversing with remote driver backends.
    54.6 + *
    54.7 + * Copyright (c) 2002-2005, K A Fraser
    54.8 + * Copyright (c) 2005, XenSource Ltd
    54.9 + * Copyright (C) 2007 Solarflare Communications, Inc.
   54.10 + *
   54.11 + * This program is free software; you can redistribute it and/or
   54.12 + * modify it under the terms of the GNU General Public License version 2
   54.13 + * as published by the Free Software Foundation; or, when distributed
   54.14 + * separately from the Linux kernel or incorporated into other
   54.15 + * software packages, subject to the following license:
   54.16 + *
   54.17 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   54.18 + * of this source file (the "Software"), to deal in the Software without
   54.19 + * restriction, including without limitation the rights to use, copy, modify,
   54.20 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   54.21 + * and to permit persons to whom the Software is furnished to do so, subject to
   54.22 + * the following conditions:
   54.23 + *
   54.24 + * The above copyright notice and this permission notice shall be included in
   54.25 + * all copies or substantial portions of the Software.
   54.26 + *
   54.27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   54.28 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   54.29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   54.30 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   54.31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   54.32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   54.33 + * IN THE SOFTWARE.
   54.34 + */
   54.35 +
   54.36 +#ifndef NETFRONT_H
   54.37 +#define NETFRONT_H
   54.38 +
   54.39 +#include <xen/interface/io/netif.h>
   54.40 +#include <linux/netdevice.h>
   54.41 +#include <linux/skbuff.h>
   54.42 +#include <linux/list.h>
   54.43 +#include <linux/kref.h>
   54.44 +
   54.45 +#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
   54.46 +#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
   54.47 +
   54.48 +#include <xen/xenbus.h>
   54.49 +
   54.50 +/* 
   54.51 + * Function pointer table for hooks into a network acceleration
   54.52 + * plugin.  These are called at appropriate points from the netfront
   54.53 + * driver 
   54.54 + */
   54.55 +struct netfront_accel_hooks {
   54.56 +	/* 
   54.57 +	 * new_device: Accelerator hook to ask the plugin to support a
   54.58 +	 * new network interface
   54.59 +	 */
   54.60 +	int (*new_device)(struct net_device *net_dev, struct xenbus_device *dev);
   54.61 +	/*
   54.62 +	 * suspend, suspend_cancel, resume, remove: Equivalent to the
   54.63 +	 * normal xenbus_* callbacks
   54.64 +	 */
   54.65 +	int (*suspend)(struct xenbus_device *dev);
   54.66 +	int (*suspend_cancel)(struct xenbus_device *dev);
   54.67 +	int (*resume)(struct xenbus_device *dev);
   54.68 +	int (*remove)(struct xenbus_device *dev);
   54.69 +	/* 
   54.70 +	 * backend_changed: Callback from watch based on backend's
   54.71 +	 * xenbus state changing
   54.72 +	 */
   54.73 +	void (*backend_changed)(struct xenbus_device *dev,
   54.74 +				enum xenbus_state backend_state);
   54.75 +	/*
   54.76 +	 * The net_device is being polled, check the accelerated
   54.77 +	 * hardware for any pending packets
   54.78 +	 */
   54.79 +	int (*netdev_poll)(struct net_device *dev, int *pbudget);
   54.80 +	/*
   54.81 +	 * start_xmit: Used to give the accelerated plugin the option
   54.82 +	 * of sending a packet.  Returns non-zero if has done so, or
   54.83 +	 * zero to decline and force the packet onto normal send
   54.84 +	 * path
   54.85 +	 */
   54.86 +	int (*start_xmit)(struct sk_buff *skb, struct net_device *dev);
   54.87 +	/* 
   54.88 +	 * start/stop_napi_interrupts Used by netfront to indicate
   54.89 +	 * when napi interrupts should be enabled or disabled 
   54.90 +	 */
   54.91 +	int (*start_napi_irq)(struct net_device *dev);
   54.92 +	void (*stop_napi_irq)(struct net_device *dev);
   54.93 +	/* 
   54.94 +	 * Called before re-enabling the TX queue to check the fast
   54.95 +	 * path has slots too
   54.96 +	 */
   54.97 +	int (*check_busy)(struct net_device *dev);
   54.98 +};
   54.99 +
  54.100 +/* 
  54.101 + * Per-netfront device state for the accelerator.  This is used to
  54.102 + * allow efficient per-netfront device access to the accelerator
  54.103 + * hooks 
  54.104 + */
  54.105 +struct netfront_accel_vif_state {
  54.106 +	struct list_head link;
  54.107 +
  54.108 +	struct xenbus_device *dev;
  54.109 +	struct netfront_info *np;
  54.110 +	struct netfront_accel_hooks *hooks;
  54.111 +
  54.112 +	/* 
  54.113 +	 * Protect against removal of hooks while in use.  
  54.114 +	 */
  54.115 +	struct kref vif_kref;
  54.116 +
  54.117 +	unsigned ready_for_probe;
  54.118 +	struct netfront_accel_hooks *need_probe;
  54.119 +}; 
  54.120 +
  54.121 +/* 
  54.122 + * Per-accelerator state stored in netfront.  These form a list that
  54.123 + * is used to track which devices are accelerated by which plugins,
  54.124 + * and what plugins are available/have been requested 
  54.125 + */
  54.126 +struct netfront_accelerator {
  54.127 +	/* Used to make a list */
  54.128 +	struct list_head link;
  54.129 +	/* ID of the accelerator */
  54.130 +	int id;
  54.131 +	/*
  54.132 +	 * String describing the accelerator.  Currently this is the
  54.133 +	 * name of the accelerator module.  This is provided by the
  54.134 +	 * backend accelerator through xenstore 
  54.135 +	 */
  54.136 +	char *frontend;
  54.137 +	/* The hooks into the accelerator plugin module */
  54.138 +	struct netfront_accel_hooks *hooks;
  54.139 +	/* 
  54.140 +	 * Protect against removal of hooks while in use.  
  54.141 +	 */
  54.142 +	struct kref accel_kref;
  54.143 +	/* 
  54.144 +	 * List of per-netfront device state (struct
  54.145 +	 * netfront_accel_vif_state) for each netfront device that is
  54.146 +	 * using this accelerator
  54.147 +	 */
  54.148 +	struct list_head vif_states;
  54.149 +	spinlock_t vif_states_lock;
  54.150 +	/* 
  54.151 +	 * Semaphore to signal that all users of this accelerator have
  54.152 +	 * finished using it before module is unloaded
  54.153 +	 */
  54.154 +	struct semaphore exit_semaphore; 
  54.155 +
  54.156 +	unsigned ready_for_probe;
  54.157 +	struct netfront_accel_hooks *need_probe;
  54.158 +};
  54.159 +
  54.160 +struct netfront_info {
  54.161 +	struct list_head list;
  54.162 +	struct net_device *netdev;
  54.163 +
  54.164 +	struct net_device_stats stats;
  54.165 +
  54.166 +	struct netif_tx_front_ring tx;
  54.167 +	struct netif_rx_front_ring rx;
  54.168 +
  54.169 +	spinlock_t   tx_lock;
  54.170 +	spinlock_t   rx_lock;
  54.171 +
  54.172 +	unsigned int irq;
  54.173 +	unsigned int copying_receiver;
  54.174 +	unsigned int carrier;
  54.175 +
  54.176 +	/* Receive-ring batched refills. */
  54.177 +#define RX_MIN_TARGET 8
  54.178 +#define RX_DFL_MIN_TARGET 64
  54.179 +#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
  54.180 +	unsigned rx_min_target, rx_max_target, rx_target;
  54.181 +	struct sk_buff_head rx_batch;
  54.182 +
  54.183 +	struct timer_list rx_refill_timer;
  54.184 +
  54.185 +	/*
  54.186 +	 * {tx,rx}_skbs store outstanding skbuffs. The first entry in tx_skbs
  54.187 +	 * is an index into a chain of free entries.
  54.188 +	 */
  54.189 +	struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1];
  54.190 +	struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
  54.191 +
  54.192 +#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
  54.193 +	grant_ref_t gref_tx_head;
  54.194 +	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
  54.195 +	grant_ref_t gref_rx_head;
  54.196 +	grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
  54.197 +
  54.198 +	struct xenbus_device *xbdev;
  54.199 +	int tx_ring_ref;
  54.200 +	int rx_ring_ref;
  54.201 +	u8 mac[ETH_ALEN];
  54.202 +
  54.203 +	unsigned long rx_pfn_array[NET_RX_RING_SIZE];
  54.204 +	struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
  54.205 +	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
  54.206 +
  54.207 +	/* Private pointer to state internal to accelerator module */
  54.208 +	void *accel_priv;
  54.209 +	/* The accelerator used by this netfront device */
  54.210 +	struct netfront_accelerator *accelerator;
  54.211 +	/* The accelerator state for this netfront device */
  54.212 +	struct netfront_accel_vif_state accel_vif_state;
  54.213 +};
  54.214 +
  54.215 +
  54.216 +/* Exported Functions */
  54.217 +
  54.218 +/*
  54.219 + * Called by an accelerator plugin module when it has loaded.
  54.220 + *
  54.221 + * frontend: the string describing the accelerator, currently the module name 
  54.222 + * hooks: the hooks for netfront to use to call into the accelerator
  54.223 + */
  54.224 +extern int netfront_accelerator_loaded(const char *frontend, 
  54.225 +				       struct netfront_accel_hooks *hooks);
  54.226 +
  54.227 +/* 
  54.228 + * Called when an accelerator plugin is ready to accelerate a device *
  54.229 + * that has been passed to it from netfront using the "new_device"
  54.230 + * hook.
  54.231 + *
  54.232 + * frontend: the string describing the accelerator. Must match the
  54.233 + * one passed to netfront_accelerator_loaded()
  54.234 + * dev: the xenbus device the plugin was asked to accelerate
  54.235 + */
  54.236 +extern void netfront_accelerator_ready(const char *frontend,
  54.237 +				       struct xenbus_device *dev);
  54.238 +
  54.239 +/* 
  54.240 + * Called by an accelerator plugin module when it is about to unload.
  54.241 + *
  54.242 + * frontend: the string describing the accelerator.  Must match the
  54.243 + * one passed to netfront_accelerator_loaded()
  54.244 + *
  54.245 + * wait: 1 => wait for all users of module to complete before
  54.246 + * returning, thus making it safe to unload on return
  54.247 + */ 
  54.248 +extern void netfront_accelerator_stop(const char *frontend, int wait);
  54.249 +
  54.250 +/* 
  54.251 + * Called by an accelerator before waking the net device's TX queue to
  54.252 + * ensure the slow path has available slots.  Returns true if OK to
  54.253 + * wake, false if still busy 
  54.254 + */
  54.255 +extern int netfront_check_queue_busy(struct net_device *net_dev);
  54.256 +
  54.257 +
  54.258 +
  54.259 +/* Internal-to-netfront Functions */
  54.260 +
  54.261 +/* 
  54.262 + * Call into accelerator and check to see if it has tx space before we
  54.263 + * wake the net device's TX queue.  Returns true if OK to wake, false
  54.264 + * if still busy
  54.265 + */ 
  54.266 +extern 
  54.267 +int netfront_check_accelerator_queue_busy(struct net_device *dev,
  54.268 +					  struct netfront_info *np);
  54.269 +extern
  54.270 +int netfront_accelerator_call_remove(struct netfront_info *np,
  54.271 +				     struct xenbus_device *dev);
  54.272 +extern
  54.273 +int netfront_accelerator_call_suspend(struct netfront_info *np,
  54.274 +				      struct xenbus_device *dev);
  54.275 +extern
  54.276 +int netfront_accelerator_call_suspend_cancel(struct netfront_info *np,
  54.277 +					     struct xenbus_device *dev);
  54.278 +extern
  54.279 +int netfront_accelerator_call_resume(struct netfront_info *np,
  54.280 +				     struct xenbus_device *dev);
  54.281 +extern
  54.282 +void netfront_accelerator_call_backend_changed(struct netfront_info *np,
  54.283 +					       struct xenbus_device *dev,
  54.284 +					       enum xenbus_state backend_state);
  54.285 +extern
  54.286 +void netfront_accelerator_call_stop_napi_irq(struct netfront_info *np,
  54.287 +					     struct net_device *dev);
  54.288 +
  54.289 +extern
  54.290 +int netfront_load_accelerator(struct netfront_info *np, 
  54.291 +			      struct xenbus_device *dev, 
  54.292 +			      const char *frontend);
  54.293 +
  54.294 +extern
  54.295 +void netif_init_accel(void);
  54.296 +
  54.297 +extern
  54.298 +void init_accelerator_vif(struct netfront_info *np,
  54.299 +			  struct xenbus_device *dev);
  54.300 +#endif /* NETFRONT_H */
    55.1 --- a/drivers/xen/privcmd/Makefile	Mon Jul 09 09:24:03 2007 -0600
    55.2 +++ b/drivers/xen/privcmd/Makefile	Tue Jul 10 08:40:03 2007 -0600
    55.3 @@ -1,2 +1,3 @@
    55.4  
    55.5 -obj-$(CONFIG_XEN_PRIVCMD)	:= privcmd.o
    55.6 +obj-y	+= privcmd.o
    55.7 +obj-$(CONFIG_COMPAT)	+= compat_privcmd.o
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/drivers/xen/privcmd/compat_privcmd.c	Tue Jul 10 08:40:03 2007 -0600
    56.3 @@ -0,0 +1,73 @@
    56.4 +/*
    56.5 + * This program is free software; you can redistribute it and/or modify
    56.6 + * it under the terms of the GNU General Public License as published by
    56.7 + * the Free Software Foundation; either version 2 of the License, or
    56.8 + * (at your option) any later version.
    56.9 + *
   56.10 + * This program is distributed in the hope that it will be useful,
   56.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   56.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   56.13 + * GNU General Public License for more details.
   56.14 + *
   56.15 + * You should have received a copy of the GNU General Public License
   56.16 + * along with this program; if not, write to the Free Software
   56.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   56.18 + *
   56.19 + * Copyright (C) IBM Corp. 2006
   56.20 + *
   56.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   56.22 + */
   56.23 +
   56.24 +#include <linux/config.h>
   56.25 +#include <linux/compat.h>
   56.26 +#include <linux/ioctl.h>
   56.27 +#include <linux/syscalls.h>
   56.28 +#include <asm/hypervisor.h>
   56.29 +#include <asm/uaccess.h>
   56.30 +#include <xen/public/privcmd.h>
   56.31 +#include <xen/compat_ioctl.h>
   56.32 +
   56.33 +int privcmd_ioctl_32(int fd, unsigned int cmd, unsigned long arg)
   56.34 +{
   56.35 +	int ret;
   56.36 +
   56.37 +	switch (cmd) {
   56.38 +	case IOCTL_PRIVCMD_MMAP_32: {
   56.39 +		struct privcmd_mmap *p;
   56.40 +		struct privcmd_mmap_32 *p32;
   56.41 +		struct privcmd_mmap_32 n32;
   56.42 +
   56.43 +		p32 = compat_ptr(arg);
   56.44 +		p = compat_alloc_user_space(sizeof(*p));
   56.45 +		if (copy_from_user(&n32, p32, sizeof(n32)) ||
   56.46 +		    put_user(n32.num, &p->num) ||
   56.47 +		    put_user(n32.dom, &p->dom) ||
   56.48 +		    put_user(compat_ptr(n32.entry), &p->entry))
   56.49 +			return -EFAULT;
   56.50 +		
   56.51 +		ret = sys_ioctl(fd, IOCTL_PRIVCMD_MMAP, (unsigned long)p);
   56.52 +	}
   56.53 +		break;
   56.54 +	case IOCTL_PRIVCMD_MMAPBATCH_32: {
   56.55 +		struct privcmd_mmapbatch *p;
   56.56 +		struct privcmd_mmapbatch_32 *p32;
   56.57 +		struct privcmd_mmapbatch_32 n32;
   56.58 +
   56.59 +		p32 = compat_ptr(arg);
   56.60 +		p = compat_alloc_user_space(sizeof(*p));
   56.61 +		if (copy_from_user(&n32, p32, sizeof(n32)) ||
   56.62 +		    put_user(n32.num, &p->num) ||
   56.63 +		    put_user(n32.dom, &p->dom) ||
   56.64 +		    put_user(n32.addr, &p->addr) ||
   56.65 +		    put_user(compat_ptr(n32.arr), &p->arr))
   56.66 +			return -EFAULT;
   56.67 +		
   56.68 +		ret = sys_ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, (unsigned long)p);
   56.69 +	}
   56.70 +		break;
   56.71 +	default:
   56.72 +		ret = -EINVAL;
   56.73 +		break;
   56.74 +	}
   56.75 +	return ret;
   56.76 +}
    57.1 --- a/drivers/xen/privcmd/privcmd.c	Mon Jul 09 09:24:03 2007 -0600
    57.2 +++ b/drivers/xen/privcmd/privcmd.c	Tue Jul 10 08:40:03 2007 -0600
    57.3 @@ -29,6 +29,7 @@
    57.4  #include <xen/public/privcmd.h>
    57.5  #include <xen/interface/xen.h>
    57.6  #include <xen/xen_proc.h>
    57.7 +#include <xen/features.h>
    57.8  
    57.9  static struct proc_dir_entry *privcmd_intf;
   57.10  static struct proc_dir_entry *capabilities_intf;
   57.11 @@ -86,7 +87,7 @@ static int privcmd_ioctl(struct inode *i
   57.12  				"g" (hypercall.arg[4])
   57.13  				: "r8", "r10", "memory" );
   57.14  		}
   57.15 -#elif defined (__ia64__)
   57.16 +#else
   57.17  		ret = privcmd_hypercall(&hypercall);
   57.18  #endif
   57.19  	}
   57.20 @@ -111,7 +112,7 @@ static int privcmd_ioctl(struct inode *i
   57.21  		if (copy_from_user(&msg, p, sizeof(msg)))
   57.22  			return -EFAULT;
   57.23  
   57.24 -		down_read(&mm->mmap_sem);
   57.25 +		down_write(&mm->mmap_sem);
   57.26  
   57.27  		vma = find_vma(mm, msg.va);
   57.28  		rc = -EINVAL;
   57.29 @@ -153,7 +154,7 @@ static int privcmd_ioctl(struct inode *i
   57.30  		rc = 0;
   57.31  
   57.32  	mmap_out:
   57.33 -		up_read(&mm->mmap_sem);
   57.34 +		up_write(&mm->mmap_sem);
   57.35  		ret = rc;
   57.36  	}
   57.37  	break;
   57.38 @@ -176,14 +177,14 @@ static int privcmd_ioctl(struct inode *i
   57.39  		if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
   57.40  			return -EINVAL;
   57.41  
   57.42 -		down_read(&mm->mmap_sem);
   57.43 +		down_write(&mm->mmap_sem);
   57.44  
   57.45  		vma = find_vma(mm, m.addr);
   57.46  		if (!vma ||
   57.47  		    (m.addr != vma->vm_start) ||
   57.48  		    ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
   57.49  		    !privcmd_enforce_singleshot_mapping(vma)) {
   57.50 -			up_read(&mm->mmap_sem);
   57.51 +			up_write(&mm->mmap_sem);
   57.52  			return -EINVAL;
   57.53  		}
   57.54  
   57.55 @@ -191,7 +192,7 @@ static int privcmd_ioctl(struct inode *i
   57.56  		addr = m.addr;
   57.57  		for (i = 0; i < nr_pages; i++, addr += PAGE_SIZE, p++) {
   57.58  			if (get_user(mfn, p)) {
   57.59 -				up_read(&mm->mmap_sem);
   57.60 +				up_write(&mm->mmap_sem);
   57.61  				return -EFAULT;
   57.62  			}
   57.63  
   57.64 @@ -202,7 +203,7 @@ static int privcmd_ioctl(struct inode *i
   57.65  				put_user(0xF0000000 | mfn, p);
   57.66  		}
   57.67  
   57.68 -		up_read(&mm->mmap_sem);
   57.69 +		up_write(&mm->mmap_sem);
   57.70  		ret = 0;
   57.71  	}
   57.72  	break;
    58.1 --- a/drivers/xen/util.c	Mon Jul 09 09:24:03 2007 -0600
    58.2 +++ b/drivers/xen/util.c	Tue Jul 10 08:40:03 2007 -0600
    58.3 @@ -22,9 +22,7 @@ struct class *get_xen_class(void)
    58.4  }
    58.5  EXPORT_SYMBOL_GPL(get_xen_class);
    58.6  
    58.7 -/* Todo: merge ia64 ('auto-translate physmap') versions of these functions. */
    58.8 -#ifndef __ia64__
    58.9 -
   58.10 +#ifdef CONFIG_X86
   58.11  static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
   58.12  {
   58.13  	/* apply_to_page_range() does all the hard work. */
   58.14 @@ -50,9 +48,7 @@ struct vm_struct *alloc_vm_area(unsigned
   58.15  	}
   58.16  
   58.17  	/* Map page directories into every address space. */
   58.18 -#ifdef CONFIG_X86
   58.19  	vmalloc_sync_all();
   58.20 -#endif
   58.21  
   58.22  	return area;
   58.23  }
   58.24 @@ -66,5 +62,4 @@ void free_vm_area(struct vm_struct *area
   58.25  	kfree(area);
   58.26  }
   58.27  EXPORT_SYMBOL_GPL(free_vm_area);
   58.28 -
   58.29 -#endif /* !__ia64__ */
   58.30 +#endif /* CONFIG_X86 */
    59.1 --- a/drivers/xen/xenbus/xenbus_probe.c	Mon Jul 09 09:24:03 2007 -0600
    59.2 +++ b/drivers/xen/xenbus/xenbus_probe.c	Tue Jul 10 08:40:03 2007 -0600
    59.3 @@ -4,6 +4,7 @@
    59.4   * Copyright (C) 2005 Rusty Russell, IBM Corporation
    59.5   * Copyright (C) 2005 Mike Wray, Hewlett-Packard
    59.6   * Copyright (C) 2005, 2006 XenSource Ltd
    59.7 + * Copyright (C) 2007 Solarflare Communications, Inc.
    59.8   * 
    59.9   * This program is free software; you can redistribute it and/or
   59.10   * modify it under the terms of the GNU General Public License version 2
   59.11 @@ -993,6 +994,7 @@ static int is_disconnected_device(struct
   59.12  {
   59.13  	struct xenbus_device *xendev = to_xenbus_device(dev);
   59.14  	struct device_driver *drv = data;
   59.15 +	struct xenbus_driver *xendrv;
   59.16  
   59.17  	/*
   59.18  	 * A device with no driver will never connect. We care only about
   59.19 @@ -1005,7 +1007,9 @@ static int is_disconnected_device(struct
   59.20  	if (drv && (dev->driver != drv))
   59.21  		return 0;
   59.22  
   59.23 -	return (xendev->state != XenbusStateConnected);
   59.24 +	xendrv = to_xenbus_driver(dev->driver);
   59.25 +	return (xendev->state != XenbusStateConnected ||
   59.26 +		(xendrv->is_ready && !xendrv->is_ready(xendev)));
   59.27  }
   59.28  
   59.29  static int exists_disconnected_device(struct device_driver *drv)
   59.30 @@ -1085,3 +1089,9 @@ static int __init boot_wait_for_devices(
   59.31  
   59.32  late_initcall(boot_wait_for_devices);
   59.33  #endif
   59.34 +
   59.35 +int xenbus_for_each_frontend(void *arg, int (*fn)(struct device *, void *))
   59.36 +{
   59.37 +	return bus_for_each_dev(&xenbus_frontend.bus, NULL, arg, fn);
   59.38 +}
   59.39 +EXPORT_SYMBOL_GPL(xenbus_for_each_frontend);
    60.1 --- a/drivers/xen/xenbus/xenbus_probe_backend.c	Mon Jul 09 09:24:03 2007 -0600
    60.2 +++ b/drivers/xen/xenbus/xenbus_probe_backend.c	Tue Jul 10 08:40:03 2007 -0600
    60.3 @@ -4,6 +4,7 @@
    60.4   * Copyright (C) 2005 Rusty Russell, IBM Corporation
    60.5   * Copyright (C) 2005 Mike Wray, Hewlett-Packard
    60.6   * Copyright (C) 2005, 2006 XenSource Ltd
    60.7 + * Copyright (C) 2007 Solarflare Communications, Inc.
    60.8   * 
    60.9   * This program is free software; you can redistribute it and/or
   60.10   * modify it under the terms of the GNU General Public License version 2
   60.11 @@ -285,3 +286,9 @@ void xenbus_backend_device_register(void
   60.12  		       xenbus_backend.error);
   60.13  	}
   60.14  }
   60.15 +
   60.16 +int xenbus_for_each_backend(void *arg, int (*fn)(struct device *, void *))
   60.17 +{
   60.18 +	return bus_for_each_dev(&xenbus_backend.bus, NULL, arg, fn);
   60.19 +}
   60.20 +EXPORT_SYMBOL_GPL(xenbus_for_each_backend);
    61.1 --- a/fs/compat_ioctl.c	Mon Jul 09 09:24:03 2007 -0600
    61.2 +++ b/fs/compat_ioctl.c	Tue Jul 10 08:40:03 2007 -0600
    61.3 @@ -124,6 +124,11 @@
    61.4  #include <linux/dvb/video.h>
    61.5  #include <linux/lp.h>
    61.6  
    61.7 +#include <xen/interface/xen.h>
    61.8 +#include <xen/public/evtchn.h>
    61.9 +#include <xen/public/privcmd.h>
   61.10 +#include <xen/compat_ioctl.h>
   61.11 +
   61.12  /* Aiee. Someone does not find a difference between int and long */
   61.13  #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
   61.14  #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
   61.15 @@ -2948,6 +2953,18 @@ COMPATIBLE_IOCTL(LPRESET)
   61.16  /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
   61.17  COMPATIBLE_IOCTL(LPGETFLAGS)
   61.18  HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)
   61.19 +
   61.20 +#ifdef CONFIG_XEN
   61.21 +HANDLE_IOCTL(IOCTL_PRIVCMD_MMAP_32, privcmd_ioctl_32)
   61.22 +HANDLE_IOCTL(IOCTL_PRIVCMD_MMAPBATCH_32, privcmd_ioctl_32)
   61.23 +COMPATIBLE_IOCTL(IOCTL_PRIVCMD_HYPERCALL)
   61.24 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_BIND_VIRQ)
   61.25 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_BIND_INTERDOMAIN)
   61.26 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_BIND_UNBOUND_PORT)
   61.27 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_UNBIND)
   61.28 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_NOTIFY)
   61.29 +COMPATIBLE_IOCTL(IOCTL_EVTCHN_RESET)
   61.30 +#endif
   61.31  };
   61.32  
   61.33  int ioctl_table_size = ARRAY_SIZE(ioctl_start);
    62.1 --- a/include/asm-i386/mach-xen/asm/dma-mapping.h	Mon Jul 09 09:24:03 2007 -0600
    62.2 +++ b/include/asm-i386/mach-xen/asm/dma-mapping.h	Tue Jul 10 08:40:03 2007 -0600
    62.3 @@ -23,11 +23,11 @@ address_needs_mapping(struct device *hwd
    62.4  }
    62.5  
    62.6  static inline int
    62.7 -range_straddles_page_boundary(void *p, size_t size)
    62.8 +range_straddles_page_boundary(paddr_t p, size_t size)
    62.9  {
   62.10  	extern unsigned long *contiguous_bitmap;
   62.11 -	return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
   62.12 -		!test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
   62.13 +	return ((((p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
   62.14 +		!test_bit(p >> PAGE_SHIFT, contiguous_bitmap));
   62.15  }
   62.16  
   62.17  #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
    63.1 --- a/include/asm-i386/mach-xen/asm/io.h	Mon Jul 09 09:24:03 2007 -0600
    63.2 +++ b/include/asm-i386/mach-xen/asm/io.h	Tue Jul 10 08:40:03 2007 -0600
    63.3 @@ -53,8 +53,8 @@
    63.4   * Convert a physical pointer to a virtual kernel pointer for /dev/mem
    63.5   * access
    63.6   */
    63.7 -#define xlate_dev_mem_ptr(p, sz)	ioremap(p, sz)
    63.8 -#define xlate_dev_mem_ptr_unmap(p)	iounmap(p)
    63.9 +#define xen_xlate_dev_mem_ptr(p, sz)	ioremap(p, sz)
   63.10 +#define xen_xlate_dev_mem_ptr_unmap(p)	iounmap(p)
   63.11  
   63.12  /*
   63.13   * Convert a virtual cached pointer to an uncached pointer
    64.1 --- a/include/asm-ia64/uaccess.h	Mon Jul 09 09:24:03 2007 -0600
    64.2 +++ b/include/asm-ia64/uaccess.h	Tue Jul 10 08:40:03 2007 -0600
    64.3 @@ -382,7 +382,7 @@ xlate_dev_mem_ptr (unsigned long p)
    64.4  }
    64.5  #else
    64.6  static __inline__ char *
    64.7 -xlate_dev_mem_ptr (unsigned long p, ssize_t sz)
    64.8 +xen_xlate_dev_mem_ptr (unsigned long p, ssize_t sz)
    64.9  {
   64.10  	unsigned long pfn = p >> PAGE_SHIFT;
   64.11  
   64.12 @@ -393,7 +393,7 @@ xlate_dev_mem_ptr (unsigned long p, ssiz
   64.13  }
   64.14  
   64.15  static __inline__ void
   64.16 -xlate_dev_mem_ptr_unmap (char* v)
   64.17 +xen_xlate_dev_mem_ptr_unmap (char* v)
   64.18  {
   64.19  	if (REGION_NUMBER(v) == RGN_UNCACHED)
   64.20  		iounmap(v);
    65.1 --- a/include/asm-powerpc/io.h	Mon Jul 09 09:24:03 2007 -0600
    65.2 +++ b/include/asm-powerpc/io.h	Tue Jul 10 08:40:03 2007 -0600
    65.3 @@ -457,6 +457,9 @@ out:
    65.4   */
    65.5  #define xlate_dev_mem_ptr(p)	__va(p)
    65.6  
    65.7 +#define xen_xlate_dev_mem_ptr(p,sz)	xlate_dev_mem_ptr(p)
    65.8 +#define xen_xlate_dev_mem_ptr_unmap(p)
    65.9 +
   65.10  /*
   65.11   * Convert a virtual cached pointer to an uncached pointer
   65.12   */
    66.1 --- a/include/asm-powerpc/mpic.h	Mon Jul 09 09:24:03 2007 -0600
    66.2 +++ b/include/asm-powerpc/mpic.h	Tue Jul 10 08:40:03 2007 -0600
    66.3 @@ -305,6 +305,8 @@ struct mpic
    66.4  #define MPIC_SPV_EOI			0x00000020
    66.5  /* No passthrough disable */
    66.6  #define MPIC_NO_PTHROU_DIS		0x00000040
    66.7 +/* Skip reset of IPI vectors during init */
    66.8 +#define MPIC_SKIP_IPI_INIT		0x00000080
    66.9  
   66.10  /* MPIC HW modification ID */
   66.11  #define MPIC_REGSET_MASK		0xf0000000
    67.1 --- a/include/asm-powerpc/page.h	Mon Jul 09 09:24:03 2007 -0600
    67.2 +++ b/include/asm-powerpc/page.h	Tue Jul 10 08:40:03 2007 -0600
    67.3 @@ -194,6 +194,15 @@ extern int page_is_ram(unsigned long pfn
    67.4  struct vm_area_struct;
    67.5  extern const char *arch_vma_name(struct vm_area_struct *vma);
    67.6  
    67.7 +#define arch_free_page(_page, _order)       \
    67.8 +({                      \
    67.9 +	int foreign = PageForeign(_page);   \
   67.10 +	if (foreign) \
   67.11 +		PageForeignDestructor(_page);   \
   67.12 +	foreign; \
   67.13 +})
   67.14 +#define HAVE_ARCH_FREE_PAGE
   67.15 +
   67.16  #include <asm-generic/memory_model.h>
   67.17  #endif /* __ASSEMBLY__ */
   67.18  
    68.1 --- a/include/asm-powerpc/udbg.h	Mon Jul 09 09:24:03 2007 -0600
    68.2 +++ b/include/asm-powerpc/udbg.h	Tue Jul 10 08:40:03 2007 -0600
    68.3 @@ -42,6 +42,7 @@ extern void __init udbg_init_debug_lpar(
    68.4  extern void __init udbg_init_pmac_realmode(void);
    68.5  extern void __init udbg_init_maple_realmode(void);
    68.6  extern void __init udbg_init_iseries(void);
    68.7 +extern void __init udbg_init_xen(void);
    68.8  extern void __init udbg_init_rtas_panel(void);
    68.9  extern void __init udbg_init_rtas_console(void);
   68.10  
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/include/asm-powerpc/xen/asm/gnttab_dma.h	Tue Jul 10 08:40:03 2007 -0600
    69.3 @@ -0,0 +1,29 @@
    69.4 +/*
    69.5 + * This program is free software; you can redistribute it and/or modify
    69.6 + * it under the terms of the GNU General Public License as published by
    69.7 + * the Free Software Foundation; either version 2 of the License, or
    69.8 + * (at your option) any later version.
    69.9 + *
   69.10 + * This program is distributed in the hope that it will be useful,
   69.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   69.13 + * GNU General Public License for more details.
   69.14 + *
   69.15 + * You should have received a copy of the GNU General Public License
   69.16 + * along with this program; if not, write to the Free Software
   69.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   69.18 + *
   69.19 + * Copyright 2007 IBM Corp.
   69.20 + *
   69.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   69.22 + */
   69.23 +
   69.24 +#ifndef _ASM_PPC_GNTTAB_DMA_H
   69.25 +#define _ASM_PPC_GNTTAB_DMA_H
   69.26 +
   69.27 +static inline int gnttab_dma_local_pfn(struct page *page)
   69.28 +{
   69.29 +	return 0;
   69.30 +}
   69.31 +
   69.32 +#endif /* _ASM_PPC_GNTTAB_DMA_H */
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/include/asm-powerpc/xen/asm/hypercall.h	Tue Jul 10 08:40:03 2007 -0600
    70.3 @@ -0,0 +1,90 @@
    70.4 +/******************************************************************************
    70.5 + * hypercall.h
    70.6 + * 
    70.7 + * Linux-specific hypervisor handling.
    70.8 + * 
    70.9 + * Copyright (c) 2002-2004, K A Fraser
   70.10 + * 
   70.11 + * This file may be distributed separately from the Linux kernel, or
   70.12 + * incorporated into other software packages, subject to the following license:
   70.13 + * 
   70.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   70.15 + * of this source file (the "Software"), to deal in the Software without
   70.16 + * restriction, including without limitation the rights to use, copy, modify,
   70.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   70.18 + * and to permit persons to whom the Software is furnished to do so, subject to
   70.19 + * the following conditions:
   70.20 + * 
   70.21 + * The above copyright notice and this permission notice shall be included in
   70.22 + * all copies or substantial portions of the Software.
   70.23 + * 
   70.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   70.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   70.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   70.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   70.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   70.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   70.30 + * IN THE SOFTWARE.
   70.31 + *
   70.32 + * Copyright 2007 IBM Corp.
   70.33 + *
   70.34 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   70.35 + *          Jimi Xenidis <jimix@watson.ibm.com>
   70.36 + */
   70.37 +
   70.38 +#ifndef __HYPERCALL_H__
   70.39 +#define __HYPERCALL_H__
   70.40 +
   70.41 +#include <asm/hvcall.h>
   70.42 +#include <asm/page.h>
   70.43 +#include <xen/xencomm.h>
   70.44 +#include <xen/interface/xen.h>
   70.45 +#include <xen/interface/sched.h>
   70.46 +
   70.47 +#define XEN_MARK(a)((a) | (~0UL << 16))
   70.48 +
   70.49 +extern int HYPERVISOR_console_io(int cmd, int count, char *str);
   70.50 +extern int HYPERVISOR_event_channel_op(int cmd, void *op);
   70.51 +extern int HYPERVISOR_xen_version(int cmd, void *arg);
   70.52 +extern int HYPERVISOR_physdev_op(int cmd, void *op);
   70.53 +extern int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop,
   70.54 +		unsigned int count);
   70.55 +extern int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
   70.56 +extern int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
   70.57 +extern int HYPERVISOR_multicall(void *call_list, int nr_calls);
   70.58 +
   70.59 +extern int HYPERVISOR_sched_op(int cmd, void *arg);
   70.60 +extern int HYPERVISOR_poll(
   70.61 +	evtchn_port_t *ports, unsigned int nr_ports, u64 timeout);
   70.62 +
   70.63 +static inline int HYPERVISOR_shutdown(unsigned int reason)
   70.64 +{
   70.65 +	struct sched_shutdown sched_shutdown = {
   70.66 +		.reason = reason
   70.67 +	};
   70.68 +
   70.69 +	return HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
   70.70 +}
   70.71 +
   70.72 +static inline int HYPERVISOR_set_timer_op(unsigned long arg)
   70.73 +{
   70.74 +	return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_set_timer_op), arg);
   70.75 +}
   70.76 +
   70.77 +extern int HYPERVISOR_suspend(unsigned long srec);
   70.78 +extern int HYPERVISOR_kexec_op(unsigned long op, void *args);
   70.79 +static inline unsigned long HYPERVISOR_hvm_op(int op, void *arg) {
   70.80 +	return -ENOSYS;
   70.81 +}
   70.82 +
   70.83 +static inline int
   70.84 +HYPERVISOR_mmu_update(
   70.85 +	mmu_update_t *req, int count, int *success_count, domid_t domid)
   70.86 +{
   70.87 +	return -ENOSYS;
   70.88 +}
   70.89 +
   70.90 +struct privcmd_hypercall;
   70.91 +extern int privcmd_hypercall(struct privcmd_hypercall *hypercall);
   70.92 +
   70.93 +#endif	/*  __HYPERCALL_H__ */
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/include/asm-powerpc/xen/asm/hypervisor.h	Tue Jul 10 08:40:03 2007 -0600
    71.3 @@ -0,0 +1,276 @@
    71.4 +/******************************************************************************
    71.5 + * hypervisor.h
    71.6 + * 
    71.7 + * Linux-specific hypervisor handling.
    71.8 + * 
    71.9 + * Copyright (c) 2002-2004, K A Fraser
   71.10 + * 
   71.11 + * This file may be distributed separately from the Linux kernel, or
   71.12 + * incorporated into other software packages, subject to the following license:
   71.13 + * 
   71.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   71.15 + * of this source file (the "Software"), to deal in the Software without
   71.16 + * restriction, including without limitation the rights to use, copy, modify,
   71.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   71.18 + * and to permit persons to whom the Software is furnished to do so, subject to
   71.19 + * the following conditions:
   71.20 + * 
   71.21 + * The above copyright notice and this permission notice shall be included in
   71.22 + * all copies or substantial portions of the Software.
   71.23 + * 
   71.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   71.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   71.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   71.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   71.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   71.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   71.30 + * IN THE SOFTWARE.
   71.31 + */
   71.32 +
   71.33 +#ifndef __HYPERVISOR_H__
   71.34 +#define __HYPERVISOR_H__
   71.35 +
   71.36 +#include <linux/config.h>
   71.37 +#include <linux/types.h>
   71.38 +#include <linux/kernel.h>
   71.39 +#include <linux/version.h>
   71.40 +#include <xen/interface/xen.h>
   71.41 +#include <asm/ptrace.h>
   71.42 +#include <asm/page.h>
   71.43 +#include <asm/irq.h>
   71.44 +
   71.45 +extern shared_info_t *HYPERVISOR_shared_info;
   71.46 +
   71.47 +/* arch/xen/i386/kernel/setup.c */
   71.48 +extern start_info_t *xen_start_info;
   71.49 +
   71.50 +#ifdef CONFIG_XEN_PRIVILEGED_GUEST
   71.51 +#define is_initial_xendomain() (xen_start_info && \
   71.52 +				(xen_start_info->flags & SIF_INITDOMAIN))
   71.53 +#else
   71.54 +#define is_initial_xendomain() 0
   71.55 +#endif
   71.56 +
   71.57 +/* arch/xen/kernel/evtchn.c */
   71.58 +/* Force a proper event-channel callback from Xen. */
   71.59 +void force_evtchn_callback(void);
   71.60 +
   71.61 +/* arch/xen/kernel/process.c */
   71.62 +void xen_cpu_idle (void);
   71.63 +
   71.64 +/* arch/xen/i386/kernel/hypervisor.c */
   71.65 +void do_hypervisor_callback(struct pt_regs *regs);
   71.66 +
   71.67 +/* arch/xen/i386/kernel/head.S */
   71.68 +void lgdt_finish(void);
   71.69 +
   71.70 +/* arch/xen/i386/mm/hypervisor.c */
   71.71 +/*
   71.72 + * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
   71.73 + * be MACHINE addresses.
   71.74 + */
   71.75 +
   71.76 +void xen_pt_switch(unsigned long ptr);
   71.77 +void xen_new_user_pt(unsigned long ptr); /* x86_64 only */
   71.78 +void xen_load_gs(unsigned int selector); /* x86_64 only */
   71.79 +void xen_tlb_flush(void);
   71.80 +void xen_invlpg(unsigned long ptr);
   71.81 +
   71.82 +#ifndef CONFIG_XEN_SHADOW_MODE
   71.83 +void xen_l1_entry_update(pte_t *ptr, pte_t val);
   71.84 +void xen_l2_entry_update(pmd_t *ptr, pmd_t val);
   71.85 +void xen_l3_entry_update(pud_t *ptr, pud_t val); /* x86_64/PAE */
   71.86 +void xen_l4_entry_update(pgd_t *ptr, pgd_t val); /* x86_64 only */
   71.87 +void xen_pgd_pin(unsigned long ptr);
   71.88 +void xen_pgd_unpin(unsigned long ptr);
   71.89 +void xen_pud_pin(unsigned long ptr); /* x86_64 only */
   71.90 +void xen_pud_unpin(unsigned long ptr); /* x86_64 only */
   71.91 +void xen_pmd_pin(unsigned long ptr); /* x86_64 only */
   71.92 +void xen_pmd_unpin(unsigned long ptr); /* x86_64 only */
   71.93 +void xen_pte_pin(unsigned long ptr);
   71.94 +void xen_pte_unpin(unsigned long ptr);
   71.95 +#else
   71.96 +#define xen_l1_entry_update(_p, _v) set_pte((_p), (_v))
   71.97 +#define xen_l2_entry_update(_p, _v) set_pgd((_p), (_v))
   71.98 +#define xen_pgd_pin(_p)   ((void)0)
   71.99 +#define xen_pgd_unpin(_p) ((void)0)
  71.100 +#define xen_pte_pin(_p)   ((void)0)
  71.101 +#define xen_pte_unpin(_p) ((void)0)
  71.102 +#endif
  71.103 +
  71.104 +void xen_set_ldt(unsigned long ptr, unsigned long bytes);
  71.105 +void xen_machphys_update(unsigned long mfn, unsigned long pfn);
  71.106 +
  71.107 +#ifdef CONFIG_SMP
  71.108 +#include <linux/cpumask.h>
  71.109 +void xen_tlb_flush_all(void);
  71.110 +void xen_invlpg_all(unsigned long ptr);
  71.111 +void xen_tlb_flush_mask(cpumask_t *mask);
  71.112 +void xen_invlpg_mask(cpumask_t *mask, unsigned long ptr);
  71.113 +#endif
  71.114 +
  71.115 +/* Returns zero on success else negative errno. */
  71.116 +static inline int xen_create_contiguous_region(
  71.117 +    unsigned long vstart, unsigned int order, unsigned int address_bits)
  71.118 +{
  71.119 +	return 0;
  71.120 +}
  71.121 +static inline void xen_destroy_contiguous_region(
  71.122 +    unsigned long vstart, unsigned int order)
  71.123 +{
  71.124 +	return;
  71.125 +}
  71.126 +
  71.127 +#include <asm/hypercall.h>
  71.128 +
  71.129 +/* BEGIN: all of these need a new home */
  71.130 +struct vm_area_struct;
  71.131 +int direct_remap_pfn_range(struct vm_area_struct *vma,  unsigned long address,
  71.132 +			   unsigned long mfn, unsigned long size,
  71.133 +			   pgprot_t prot, domid_t  domid);
  71.134 +#define	pfn_to_mfn(x)	(x)
  71.135 +#define	mfn_to_pfn(x)	(x)
  71.136 +#define phys_to_machine(phys) ((maddr_t)(phys))
  71.137 +#define phys_to_machine_mapping_valid(pfn) (1)
  71.138 +
  71.139 +/* VIRT <-> MACHINE conversion */
  71.140 +#define virt_to_machine(v)	(phys_to_machine(__pa(v)))
  71.141 +#define machine_to_virt(m)	(__va(m))
  71.142 +#define virt_to_mfn(v)		(pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
  71.143 +#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
  71.144 +
  71.145 +
  71.146 +#define PIRQ_BASE		0
  71.147 +#define NR_PIRQS		256
  71.148 +
  71.149 +#define DYNIRQ_BASE		(PIRQ_BASE + NR_PIRQS)
  71.150 +#define NR_DYNIRQS		256
  71.151 +
  71.152 +#define NR_IPIS 4		/* PPC_MSG_DEBUGGER_BREAK + 1 */
  71.153 +
  71.154 +#if NR_IRQS < (NR_PIRQS + NR_DYNIRQS)
  71.155 +#error to many Xen IRQs
  71.156 +#endif
  71.157 +
  71.158 +#define NR_IRQ_VECTORS		NR_IRQS
  71.159 +
  71.160 +#define pirq_to_irq(_x)		((_x) + PIRQ_BASE)
  71.161 +#define irq_to_pirq(_x)		((_x) - PIRQ_BASE)
  71.162 +
  71.163 +#define dynirq_to_irq(_x)	((_x) + DYNIRQ_BASE)
  71.164 +#define irq_to_dynirq(_x)	((_x) - DYNIRQ_BASE)
  71.165 +
  71.166 +
  71.167 +/* END:  all of these need a new home */
  71.168 +
  71.169 +#if defined(CONFIG_X86_64)
  71.170 +#define MULTI_UVMFLAGS_INDEX 2
  71.171 +#define MULTI_UVMDOMID_INDEX 3
  71.172 +#else
  71.173 +#define MULTI_UVMFLAGS_INDEX 3
  71.174 +#define MULTI_UVMDOMID_INDEX 4
  71.175 +#endif
  71.176 +
  71.177 +extern int is_running_on_xen(void);
  71.178 +
  71.179 +static inline void
  71.180 +MULTI_update_va_mapping(
  71.181 +    multicall_entry_t *mcl, unsigned long va,
  71.182 +    pte_t new_val, unsigned long flags)
  71.183 +{
  71.184 +    mcl->op = __HYPERVISOR_update_va_mapping;
  71.185 +    mcl->args[0] = va;
  71.186 +#if defined(CONFIG_X86_64)
  71.187 +    mcl->args[1] = new_val.pte;
  71.188 +    mcl->args[2] = flags;
  71.189 +#elif defined(CONFIG_X86_PAE)
  71.190 +    mcl->args[1] = new_val.pte_low;
  71.191 +    mcl->args[2] = new_val.pte_high;
  71.192 +    mcl->args[3] = flags;
  71.193 +#elif defined(CONFIG_PPC64)
  71.194 +    mcl->args[1] = pte_val(new_val);
  71.195 +    mcl->args[2] = 0;
  71.196 +    mcl->args[3] = flags;
  71.197 +#else
  71.198 +    mcl->args[1] = new_val.pte_low;
  71.199 +    mcl->args[2] = 0;
  71.200 +    mcl->args[3] = flags;
  71.201 +#endif
  71.202 +}
  71.203 +
  71.204 +static inline void
  71.205 +MULTI_update_va_mapping_otherdomain(
  71.206 +    multicall_entry_t *mcl, unsigned long va,
  71.207 +    pte_t new_val, unsigned long flags, domid_t domid)
  71.208 +{
  71.209 +    mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
  71.210 +    mcl->args[0] = va;
  71.211 +#if defined(CONFIG_X86_64)
  71.212 +    mcl->args[1] = new_val.pte;
  71.213 +    mcl->args[2] = flags;
  71.214 +    mcl->args[3] = domid;
  71.215 +#elif defined(CONFIG_X86_PAE)
  71.216 +    mcl->args[1] = new_val.pte_low;
  71.217 +    mcl->args[2] = new_val.pte_high;
  71.218 +    mcl->args[3] = flags;
  71.219 +    mcl->args[4] = domid;
  71.220 +#elif defined(CONFIG_PPC64)
  71.221 +    mcl->args[1] = pte_val(new_val);
  71.222 +    mcl->args[2] = 0;
  71.223 +    mcl->args[3] = flags;
  71.224 +    mcl->args[4] = domid;
  71.225 +#else
  71.226 +    mcl->args[1] = new_val.pte_low;
  71.227 +    mcl->args[2] = 0;
  71.228 +    mcl->args[3] = flags;
  71.229 +    mcl->args[4] = domid;
  71.230 +#endif
  71.231 +}
  71.232 +
  71.233 +#define INVALID_P2M_ENTRY (~0UL)
  71.234 +#define FOREIGN_FRAME(m) (INVALID_P2M_ENTRY)
  71.235 +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
  71.236 +{
  71.237 +	if (pfn != mfn && mfn != INVALID_P2M_ENTRY)
  71.238 +		printk(KERN_EMERG "%s: pfn: 0x%lx mfn: 0x%lx\n",
  71.239 +		       __func__, pfn, mfn);
  71.240 +	
  71.241 +	return;
  71.242 +}
  71.243 +#define pfn_pte_ma(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
  71.244 +
  71.245 +typedef unsigned long maddr_t;
  71.246 +typedef unsigned long paddr_t;
  71.247 +
  71.248 +#ifdef CONFIG_XEN_SCRUB_PAGES
  71.249 +
  71.250 +static inline void scrub_pages(void *p, unsigned n)
  71.251 +{
  71.252 +	unsigned i;
  71.253 +
  71.254 +	for (i = 0; i < n; i++) {
  71.255 +		clear_page(p);
  71.256 +		p += PAGE_SIZE;
  71.257 +	}
  71.258 +}
  71.259 +#else
  71.260 +#define scrub_pages(_p,_n) ((void)0)
  71.261 +#endif
  71.262 +
  71.263 +/*
  71.264 + * for blktap.c
  71.265 + * int create_lookup_pte_addr(struct mm_struct *mm, 
  71.266 + *                            unsigned long address,
  71.267 + *                            uint64_t *ptep);
  71.268 + */
  71.269 +#define create_lookup_pte_addr(mm, address, ptep)			\
  71.270 +	({								\
  71.271 +		printk(KERN_EMERG					\
  71.272 +		       "%s:%d "						\
  71.273 +		       "create_lookup_pte_addr() isn't supported.\n",	\
  71.274 +		       __func__, __LINE__);				\
  71.275 +		BUG();							\
  71.276 +		(-ENOSYS);						\
  71.277 +	})
  71.278 +
  71.279 +#endif /* __HYPERVISOR_H__ */
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/include/asm-powerpc/xen/asm/maddr.h	Tue Jul 10 08:40:03 2007 -0600
    72.3 @@ -0,0 +1,7 @@
    72.4 +#ifndef _POWERPC_MADDR_H
    72.5 +#define _POWERPC_MADDR_H
    72.6 +
    72.7 +#include <xen/features.h>
    72.8 +#include <xen/interface/xen.h>
    72.9 +
   72.10 +#endif
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/include/asm-powerpc/xen/asm/synch_bitops.h	Tue Jul 10 08:40:03 2007 -0600
    73.3 @@ -0,0 +1,100 @@
    73.4 +/*
    73.5 + * This program is free software; you can redistribute it and/or modify
    73.6 + * it under the terms of the GNU General Public License as published by
    73.7 + * the Free Software Foundation; either version 2 of the License, or
    73.8 + * (at your option) any later version.
    73.9 + *
   73.10 + * This program is distributed in the hope that it will be useful,
   73.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   73.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   73.13 + * GNU General Public License for more details.
   73.14 + *
   73.15 + * You should have received a copy of the GNU General Public License
   73.16 + * along with this program; if not, write to the Free Software
   73.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   73.18 + *
   73.19 + * Copyright 2006 IBM Corp.
   73.20 + *
   73.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   73.22 + */
   73.23 +
   73.24 +#ifndef  __SYNCH_BITOPS_H__
   73.25 +#define __SYNCH_BITOPS_H__
   73.26 +
   73.27 +#include <linux/config.h>
   73.28 +#include <xen/interface/xen.h>
   73.29 +
   73.30 +#ifdef CONFIG_SMP
   73.31 +#include <asm/bitops.h>
   73.32 +
   73.33 +#define synch_change_bit(a,b) change_bit(a,b)
   73.34 +#define synch_clear_bit(a,b) clear_bit(a,b)
   73.35 +#define synch_const_test_bit(a,b) const_test_bit(a,b) 
   73.36 +#define synch_set_bit(a,b) set_bit(a,b)
   73.37 +#define synch_test_and_set_bit(a,b) test_and_set_bit(a,b)
   73.38 +#define synch_test_and_change_bit(a,b) test_and_change_bit(a,b)
   73.39 +#define synch_test_and_clear_bit(a,b) test_and_clear_bit(a,b)
   73.40 +#define synch_test_bit(a,b) test_bit(a,b)
   73.41 +
   73.42 +static __inline__ unsigned long
   73.43 +__synch_cmpxchg_u16(volatile unsigned short *p, unsigned long old, unsigned long new)
   73.44 +{
   73.45 +	int idx;
   73.46 +	volatile unsigned int *xp = (unsigned int *)((ulong)p & ~(0x3UL));
   73.47 +	union {
   73.48 +		unsigned int word;
   73.49 +		struct {
   73.50 +			unsigned short s[2];
   73.51 +		}s;
   73.52 +	} xold, xnew;
   73.53 +
   73.54 +	/* we could start the reservation here and copy the u32
   73.55 +	 * assembler, but I don't think it will gain us a whole
   73.56 +	 * lot. */
   73.57 +	xold.word = *xp;
   73.58 +	xnew.word = xold.word;
   73.59 +	idx = ((ulong)p >> 1) & 0x1;
   73.60 +	xold.s.s[idx] = old;
   73.61 +	xnew.s.s[idx] = new;
   73.62 +
   73.63 +	return __cmpxchg_u32(xp, xold.word, xnew.word);
   73.64 +}
   73.65 +
   73.66 +/*
   73.67 + * This function doesn't exist, so you'll get a linker error
   73.68 + * if something tries to do an invalid xchg().
   73.69 + */
   73.70 +extern void __synch_cmpxchg_called_with_bad_pointer(void);
   73.71 +static __inline__ unsigned long
   73.72 +__synch_cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
   73.73 +	       unsigned int size)
   73.74 +{
   73.75 +	switch (size) {
   73.76 +	case 2:
   73.77 +		return __synch_cmpxchg_u16(ptr, old, new);
   73.78 +	case 4:
   73.79 +		return __cmpxchg_u32(ptr, old, new);
   73.80 +#ifdef CONFIG_PPC64
   73.81 +	case 8:
   73.82 +		return __cmpxchg_u64(ptr, old, new);
   73.83 +#endif
   73.84 +	}
   73.85 +	__synch_cmpxchg_called_with_bad_pointer();
   73.86 +	return old;
   73.87 +}
   73.88 +
   73.89 +#define synch_cmpxchg(ptr,o,n)						 \
   73.90 +  ({									 \
   73.91 +     __typeof__(*(ptr)) _o_ = (o);					 \
   73.92 +     __typeof__(*(ptr)) _n_ = (n);					 \
   73.93 +     (__typeof__(*(ptr))) __synch_cmpxchg((ptr), (unsigned long)_o_,		 \
   73.94 +				    (unsigned long)_n_, sizeof(*(ptr))); \
   73.95 +  })
   73.96 +
   73.97 +#define synch_cmpxchg_subword(ptr,o,n) __synch_cmpxchg_u16((ptr), (o), (n))
   73.98 +
   73.99 +#else
  73.100 +#error "this only works for CONFIG_SMP"
  73.101 +#endif
  73.102 +
  73.103 +#endif /* __SYNCH_BITOPS_H__ */
    74.1 --- a/include/asm-x86_64/mach-xen/asm/io.h	Mon Jul 09 09:24:03 2007 -0600
    74.2 +++ b/include/asm-x86_64/mach-xen/asm/io.h	Tue Jul 10 08:40:03 2007 -0600
    74.3 @@ -315,8 +315,8 @@ extern int iommu_bio_merge;
    74.4   * Convert a physical pointer to a virtual kernel pointer for /dev/mem
    74.5   * access
    74.6   */
    74.7 -#define xlate_dev_mem_ptr(p, sz)	ioremap(p, sz)
    74.8 -#define xlate_dev_mem_ptr_unmap(p)	iounmap(p)
    74.9 +#define xen_xlate_dev_mem_ptr(p, sz)	ioremap(p, sz)
   74.10 +#define xen_xlate_dev_mem_ptr_unmap(p)	iounmap(p)
   74.11  
   74.12  /*
   74.13   * Convert a virtual cached pointer to an uncached pointer
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/include/xen/compat_ioctl.h	Tue Jul 10 08:40:03 2007 -0600
    75.3 @@ -0,0 +1,45 @@
    75.4 +/*
    75.5 + * This program is free software; you can redistribute it and/or
    75.6 + * modify it under the terms of the GNU General Public License as
    75.7 + * published by the Free Software Foundation; either version 2 of the
    75.8 + * License, or (at your option) any later version.
    75.9 + *
   75.10 + * This program is distributed in the hope that it will be useful,
   75.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   75.13 + * GNU General Public License for more details.
   75.14 + *
   75.15 + * You should have received a copy of the GNU General Public License
   75.16 + * along with this program; if not, write to the Free Software
   75.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   75.18 + *
   75.19 + * Copyright IBM Corp. 2007
   75.20 + *
   75.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   75.22 + *          Hollis Blanchard <hollisb@us.ibm.com>
   75.23 + */
   75.24 +
   75.25 +#ifndef __LINUX_XEN_COMPAT_H__ 
   75.26 +#define __LINUX_XEN_COMPAT_H__ 
   75.27 +
   75.28 +#include <linux/compat.h>
   75.29 +
   75.30 +extern int privcmd_ioctl_32(int fd, unsigned int cmd, unsigned long arg);
   75.31 +struct privcmd_mmap_32 {
   75.32 +	int num;
   75.33 +	domid_t dom;
   75.34 +	compat_uptr_t entry;
   75.35 +};
   75.36 +
   75.37 +struct privcmd_mmapbatch_32 {
   75.38 +	int num;     /* number of pages to populate */
   75.39 +	domid_t dom; /* target domain */
   75.40 +	__u64 addr;  /* virtual address */
   75.41 +	compat_uptr_t arr; /* array of mfns - top nibble set on err */
   75.42 +};
   75.43 +#define IOCTL_PRIVCMD_MMAP_32                   \
   75.44 +	_IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap_32))
   75.45 +#define IOCTL_PRIVCMD_MMAPBATCH_32                  \
   75.46 +	_IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch_32))
   75.47 +
   75.48 +#endif /* __LINUX_XEN_COMPAT_H__ */
    76.1 --- a/include/xen/gnttab.h	Mon Jul 09 09:24:03 2007 -0600
    76.2 +++ b/include/xen/gnttab.h	Tue Jul 10 08:40:03 2007 -0600
    76.3 @@ -117,6 +117,8 @@ static inline void gnttab_reset_grant_pa
    76.4  int gnttab_suspend(void);
    76.5  int gnttab_resume(void);
    76.6  
    76.7 +void *arch_gnttab_alloc_shared(unsigned long *frames);
    76.8 +
    76.9  static inline void
   76.10  gnttab_set_map_op(struct gnttab_map_grant_ref *map, maddr_t addr,
   76.11  		  uint32_t flags, grant_ref_t ref, domid_t domid)
    77.1 --- a/include/xen/interface/sysctl.h	Mon Jul 09 09:24:03 2007 -0600
    77.2 +++ b/include/xen/interface/sysctl.h	Tue Jul 10 08:40:03 2007 -0600
    77.3 @@ -34,7 +34,7 @@
    77.4  #include "xen.h"
    77.5  #include "domctl.h"
    77.6  
    77.7 -#define XEN_SYSCTL_INTERFACE_VERSION 0x00000003
    77.8 +#define XEN_SYSCTL_INTERFACE_VERSION 0x00000004
    77.9  
   77.10  /*
   77.11   * Read console content from Xen buffer ring.
   77.12 @@ -76,6 +76,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_
   77.13   */
   77.14  #define XEN_SYSCTL_physinfo          3
   77.15  struct xen_sysctl_physinfo {
   77.16 +    /* IN variables. */
   77.17      uint32_t threads_per_core;
   77.18      uint32_t cores_per_socket;
   77.19      uint32_t sockets_per_node;
   77.20 @@ -85,6 +86,23 @@ struct xen_sysctl_physinfo {
   77.21      uint64_aligned_t free_pages;
   77.22      uint64_aligned_t scrub_pages;
   77.23      uint32_t hw_cap[8];
   77.24 +
   77.25 +    /* IN/OUT variables. */
   77.26 +    /*
   77.27 +     * IN: maximum addressable entry in the caller-provided cpu_to_node array.
   77.28 +     * OUT: largest cpu identifier in the system.
   77.29 +     * If OUT is greater than IN then the cpu_to_node array is truncated!
   77.30 +     */
   77.31 +    uint32_t max_cpu_id;
   77.32 +    /*
   77.33 +     * If not NULL, this array is filled with node identifier for each cpu.
   77.34 +     * If a cpu has no node information (e.g., cpu not present) then the
   77.35 +     * sentinel value ~0u is written.
   77.36 +     * The size of this array is specified by the caller in @max_cpu_id.
   77.37 +     * If the actual @max_cpu_id is smaller than the array then the trailing
   77.38 +     * elements of the array will not be written by the sysctl.
   77.39 +     */
   77.40 +    XEN_GUEST_HANDLE_64(uint32_t) cpu_to_node;
   77.41  };
   77.42  typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
   77.43  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
   77.44 @@ -140,9 +158,7 @@ struct xen_sysctl_getdomaininfolist {
   77.45  typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
   77.46  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
   77.47  
   77.48 -/*
   77.49 - * Inject debug keys into Xen.
   77.50 - */
   77.51 +/* Inject debug keys into Xen. */
   77.52  #define XEN_SYSCTL_debug_keys        7
   77.53  struct xen_sysctl_debug_keys {
   77.54      /* IN variables. */
   77.55 @@ -152,6 +168,23 @@ struct xen_sysctl_debug_keys {
   77.56  typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t;
   77.57  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t);
   77.58  
   77.59 +/* Get physical CPU information. */
   77.60 +#define XEN_SYSCTL_getcpuinfo        8
   77.61 +struct xen_sysctl_cpuinfo {
   77.62 +    uint64_t idletime;
   77.63 +};
   77.64 +typedef struct xen_sysctl_cpuinfo xen_sysctl_cpuinfo_t;
   77.65 +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpuinfo_t); 
   77.66 +struct xen_sysctl_getcpuinfo {
   77.67 +    /* IN variables. */
   77.68 +    uint32_t max_cpus;
   77.69 +    XEN_GUEST_HANDLE_64(xen_sysctl_cpuinfo_t) info;
   77.70 +    /* OUT variables. */
   77.71 +    uint32_t nr_cpus;
   77.72 +}; 
   77.73 +typedef struct xen_sysctl_getcpuinfo xen_sysctl_getcpuinfo_t;
   77.74 +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getcpuinfo_t); 
   77.75 +
   77.76  struct xen_sysctl {
   77.77      uint32_t cmd;
   77.78      uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
   77.79 @@ -163,6 +196,7 @@ struct xen_sysctl {
   77.80          struct xen_sysctl_perfc_op          perfc_op;
   77.81          struct xen_sysctl_getdomaininfolist getdomaininfolist;
   77.82          struct xen_sysctl_debug_keys        debug_keys;
   77.83 +        struct xen_sysctl_getcpuinfo        getcpuinfo;
   77.84          uint8_t                             pad[128];
   77.85      } u;
   77.86  };
    78.1 --- a/include/xen/xenbus.h	Mon Jul 09 09:24:03 2007 -0600
    78.2 +++ b/include/xen/xenbus.h	Tue Jul 10 08:40:03 2007 -0600
    78.3 @@ -106,6 +106,7 @@ struct xenbus_driver {
    78.4  	int (*uevent)(struct xenbus_device *, char **, int, char *, int);
    78.5  	struct device_driver driver;
    78.6  	int (*read_otherend_details)(struct xenbus_device *dev);
    78.7 +	int (*is_ready)(struct xenbus_device *dev);
    78.8  };
    78.9  
   78.10  static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
   78.11 @@ -299,4 +300,7 @@ const char *xenbus_strstate(enum xenbus_
   78.12  int xenbus_dev_is_online(struct xenbus_device *dev);
   78.13  int xenbus_frontend_closed(struct xenbus_device *dev);
   78.14  
   78.15 +int xenbus_for_each_backend(void *arg, int (*fn)(struct device *, void *));
   78.16 +int xenbus_for_each_frontend(void *arg, int (*fn)(struct device *, void *));
   78.17 +
   78.18  #endif /* _XEN_XENBUS_H */
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/include/xen/xencomm.h	Tue Jul 10 08:40:03 2007 -0600
    79.3 @@ -0,0 +1,51 @@
    79.4 +/*
    79.5 + * This program is free software; you can redistribute it and/or modify
    79.6 + * it under the terms of the GNU General Public License as published by
    79.7 + * the Free Software Foundation; either version 2 of the License, or
    79.8 + * (at your option) any later version.
    79.9 + * 
   79.10 + * This program is distributed in the hope that it will be useful,
   79.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   79.13 + * GNU General Public License for more details.
   79.14 + * 
   79.15 + * You should have received a copy of the GNU General Public License
   79.16 + * along with this program; if not, write to the Free Software
   79.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   79.18 + *
   79.19 + * Copyright (C) IBM Corp. 2006
   79.20 + *
   79.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   79.22 + *          Jerone Young <jyoung5@us.ibm.com>
   79.23 + */
   79.24 +
   79.25 +#ifndef _LINUX_XENCOMM_H_
   79.26 +#define _LINUX_XENCOMM_H_
   79.27 +
   79.28 +#include <xen/interface/xencomm.h>
   79.29 +
   79.30 +#define XENCOMM_MINI_ADDRS 3
   79.31 +struct xencomm_mini {
   79.32 +	struct xencomm_desc _desc;
   79.33 +	uint64_t address[XENCOMM_MINI_ADDRS];
   79.34 +};
   79.35 +
   79.36 +extern void xencomm_free(void *desc);
   79.37 +extern void *xencomm_map(void *ptr, unsigned long bytes);
   79.38 +extern void *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, 
   79.39 +				struct xencomm_mini *xc_area);
   79.40 +
   79.41 +#define xencomm_map_no_alloc(ptr, bytes) \
   79.42 +	({struct xencomm_mini xc_desc\
   79.43 +		__attribute__((__aligned__(sizeof(struct xencomm_mini))));\
   79.44 +		__xencomm_map_no_alloc(ptr, bytes, &xc_desc);})
   79.45 +
   79.46 +/* provided by architecture code: */
   79.47 +extern unsigned long xencomm_vtop(unsigned long vaddr);
   79.48 +
   79.49 +static inline void *xencomm_pa(void *ptr)
   79.50 +{
   79.51 +	return (void *)xencomm_vtop((unsigned long)ptr);
   79.52 +}
   79.53 +
   79.54 +#endif /* _LINUX_XENCOMM_H_ */