[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID b76e86966e7ee5e8bcdab787701a733cfc78b279 # Parent 4acc6d51f3893d2b0c33c021f459ac12482858d9 # Parent aa1ab056bfbffc28c8f2f8c7142ceb076d9a784d merge with xen-unstable.hg --- tools/ioemu/CVS/Entries | 109 tools/ioemu/CVS/Repository | 1 tools/ioemu/CVS/Root | 1 tools/ioemu/CVS/Tag | 1 tools/ioemu/audio/CVS/Entries | 19 tools/ioemu/audio/CVS/Repository | 1 tools/ioemu/audio/CVS/Root | 1 tools/ioemu/audio/CVS/Tag | 1 tools/ioemu/fpu/CVS/Entries | 7 tools/ioemu/fpu/CVS/Repository | 1 tools/ioemu/fpu/CVS/Root | 1 tools/ioemu/fpu/CVS/Tag | 1 tools/ioemu/hw/CVS/Entries | 72 tools/ioemu/hw/CVS/Repository | 1 tools/ioemu/hw/CVS/Root | 1 tools/ioemu/hw/CVS/Tag | 1 tools/ioemu/keymaps/CVS/Entries | 36 tools/ioemu/keymaps/CVS/Repository | 1 tools/ioemu/keymaps/CVS/Root | 1 tools/ioemu/keymaps/CVS/Tag | 1 tools/ioemu/pc-bios/CVS/Entries | 15 tools/ioemu/pc-bios/CVS/Repository | 1 tools/ioemu/pc-bios/CVS/Root | 1 tools/ioemu/pc-bios/CVS/Tag | 1 tools/ioemu/target-i386/CVS/Entries | 13 tools/ioemu/target-i386/CVS/Repository | 1 tools/ioemu/target-i386/CVS/Root | 1 tools/ioemu/target-i386/CVS/Tag | 1 tools/ioemu/tests/CVS/Entries | 18 tools/ioemu/tests/CVS/Repository | 1 tools/ioemu/tests/CVS/Root | 1 tools/ioemu/tests/CVS/Tag | 1 .hgignore | 1 buildconfigs/linux-defconfig_xen0_ia64 | 14 buildconfigs/linux-defconfig_xenU_ia64 | 16 buildconfigs/linux-defconfig_xen_ia64 | 14 docs/figs/acm_ezpolicy.eps | 650 +++++ docs/figs/acm_overview.eps | 1459 +++++++++++ docs/src/user.tex | 982 +++++++ linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c | 1 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c | 2 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c | 3 linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c | 3 linux-2.6-xen-sparse/drivers/xen/netback/common.h | 16 linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 48 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 541 +++- linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 27 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 474 ++- linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c | 4 linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c | 3 linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c | 9 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c | 114 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 4 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h | 3 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h | 1 tools/blktap/drivers/blktapctrl.c | 21 tools/firmware/hvmloader/hvmloader.c | 10 tools/firmware/vmxassist/vm86.c | 31 tools/ioemu/.CVS/Entries | 109 tools/ioemu/.CVS/Repository | 1 tools/ioemu/.CVS/Root | 1 tools/ioemu/.CVS/Tag | 1 tools/ioemu/audio/.CVS/Entries | 19 tools/ioemu/audio/.CVS/Repository | 1 tools/ioemu/audio/.CVS/Root | 1 tools/ioemu/audio/.CVS/Tag | 1 tools/ioemu/fpu/.CVS/Entries | 7 tools/ioemu/fpu/.CVS/Repository | 1 tools/ioemu/fpu/.CVS/Root | 1 tools/ioemu/fpu/.CVS/Tag | 1 tools/ioemu/hw/.CVS/Entries | 72 tools/ioemu/hw/.CVS/Repository | 1 tools/ioemu/hw/.CVS/Root | 1 tools/ioemu/hw/.CVS/Tag | 1 tools/ioemu/keymaps/.CVS/Entries | 36 tools/ioemu/keymaps/.CVS/Repository | 1 tools/ioemu/keymaps/.CVS/Root | 1 tools/ioemu/keymaps/.CVS/Tag | 1 tools/ioemu/patches/ioemu-ia64 | 15 tools/ioemu/pc-bios/.CVS/Entries | 15 tools/ioemu/pc-bios/.CVS/Repository | 1 tools/ioemu/pc-bios/.CVS/Root | 1 tools/ioemu/pc-bios/.CVS/Tag | 1 tools/ioemu/target-i386/.CVS/Entries | 13 tools/ioemu/target-i386/.CVS/Repository | 1 tools/ioemu/target-i386/.CVS/Root | 1 tools/ioemu/target-i386/.CVS/Tag | 1 tools/ioemu/tests/.CVS/Entries | 18 tools/ioemu/tests/.CVS/Repository | 1 tools/ioemu/tests/.CVS/Root | 1 tools/ioemu/tests/.CVS/Tag | 1 tools/misc/lomount/lomount.c | 6 tools/python/xen/util/auxbin.py | 4 tools/python/xen/xm/main.py | 4 tools/security/Makefile | 2 tools/security/xensec_ezpolicy | 1628 +++++++++++++ tools/xenstore/Makefile | 4 tools/xenstore/xenstore_client.c | 106 tools/xenstore/xenstored_core.c | 9 tools/xenstore/xenstored_core.h | 1 tools/xenstore/xenstored_transaction.c | 10 tools/xenstore/xsls.c | 103 xen/Makefile | 22 xen/Rules.mk | 7 xen/arch/ia64/xen/dom_fw.c | 14 xen/arch/ia64/xen/domain.c | 5 xen/arch/ia64/xen/xensetup.c | 10 xen/arch/powerpc/boot_of.c | 8 xen/arch/powerpc/domain_build.c | 4 xen/arch/powerpc/mpic_init.c | 1 xen/arch/powerpc/ofd_fixup.c | 4 xen/arch/powerpc/powerpc64/traps.c | 4 xen/arch/x86/dom0_ops.c | 2 xen/arch/x86/domain.c | 2 xen/arch/x86/domain_build.c | 7 xen/arch/x86/hvm/hvm.c | 60 xen/arch/x86/hvm/i8259.c | 4 xen/arch/x86/hvm/io.c | 5 xen/arch/x86/hvm/platform.c | 1 xen/arch/x86/hvm/svm/intr.c | 18 xen/arch/x86/hvm/svm/svm.c | 102 xen/arch/x86/hvm/vioapic.c | 37 xen/arch/x86/hvm/vlapic.c | 557 ++-- xen/arch/x86/hvm/vmx/io.c | 17 xen/arch/x86/hvm/vmx/vmx.c | 111 xen/arch/x86/setup.c | 22 xen/arch/x86/shadow32.c | 6 xen/arch/x86/shadow_public.c | 6 xen/arch/x86/traps.c | 122 xen/arch/x86/x86_32/traps.c | 14 xen/arch/x86/x86_64/traps.c | 16 xen/common/Makefile | 3 xen/common/kernel.c | 16 xen/common/sched_credit.c | 17 xen/common/version.c | 56 xen/drivers/char/Makefile | 3 xen/drivers/char/console.c | 12 xen/include/asm-ia64/vmx_platform.h | 11 xen/include/asm-x86/domain.h | 2 xen/include/asm-x86/hvm/hvm.h | 5 xen/include/asm-x86/hvm/support.h | 4 xen/include/asm-x86/hvm/svm/vmmcall.h | 8 xen/include/asm-x86/hvm/vlapic.h | 113 xen/include/asm-x86/hvm/vmx/vmcs.h | 1 xen/include/asm-x86/hvm/vmx/vmx.h | 2 xen/include/asm-x86/processor.h | 4 xen/include/public/io/netif.h | 8 xen/include/xen/version.h | 16 148 files changed, 7164 insertions(+), 1274 deletions(-) diff -r 4acc6d51f389 -r b76e86966e7e .hgignore --- a/.hgignore Tue Aug 01 14:58:20 2006 -0600 +++ b/.hgignore Wed Aug 02 13:39:47 2006 -0600 @@ -156,6 +156,7 @@ ^tools/xenstat/xentop/xentop$ ^tools/xenstore/testsuite/tmp/.*$ ^tools/xenstore/xen$ +^tools/xenstore/xenstore-chmod$ ^tools/xenstore/xenstore-exists$ ^tools/xenstore/xenstore-list$ ^tools/xenstore/xenstore-read$ diff -r 4acc6d51f389 -r b76e86966e7e buildconfigs/linux-defconfig_xen0_ia64 --- a/buildconfigs/linux-defconfig_xen0_ia64 Tue Aug 01 14:58:20 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Wed Aug 02 13:39:47 2006 -0600 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16.13-xen0 -# Fri Jun 30 12:59:19 2006 +# Fri Jul 28 16:33:47 2006 # # @@ -92,6 +92,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_XEN=y CONFIG_XEN_IA64_DOM0_VP=y +CONFIG_XEN_IA64_VDSO_PARAVIRT=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_IS_DMA32=y # CONFIG_IA64_GENERIC is not set @@ -180,6 +181,8 @@ CONFIG_ACPI_CONTAINER=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_XEN_PCIDEV_FRONTEND=y +# CONFIG_XEN_PCIDEV_FE_DEBUG is not set CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set @@ -1513,7 +1516,7 @@ CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_DEVMEM is not set -# CONFIG_XEN_REBOOT is not set +CONFIG_XEN_REBOOT=y # CONFIG_XEN_SMPBOOT is not set CONFIG_XEN_INTERFACE_VERSION=0x00030202 @@ -1523,13 +1526,16 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -# CONFIG_XEN_PCIDEV_BACKEND is not set CONFIG_XEN_BLKDEV_BACKEND=y -CONFIG_XEN_XENBUS_DEV=y # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=y +CONFIG_XEN_PCIDEV_BACKEND_VPCI=y +# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y # CONFIG_XEN_SCRUB_PAGES is not set diff -r 4acc6d51f389 -r b76e86966e7e buildconfigs/linux-defconfig_xenU_ia64 --- a/buildconfigs/linux-defconfig_xenU_ia64 Tue Aug 01 14:58:20 2006 -0600 +++ b/buildconfigs/linux-defconfig_xenU_ia64 Wed Aug 02 13:39:47 2006 -0600 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16.13-xenU -# Mon May 22 15:05:32 2006 +# Fri Jul 28 16:32:18 2006 # # @@ -89,6 +89,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_XEN=y CONFIG_XEN_IA64_DOM0_VP=y +CONFIG_XEN_IA64_VDSO_PARAVIRT=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_IS_DMA32=y # CONFIG_IA64_GENERIC is not set @@ -177,6 +178,8 @@ CONFIG_ACPI_SYSTEM=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_XEN_PCIDEV_FRONTEND=y +# CONFIG_XEN_PCIDEV_FE_DEBUG is not set CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set @@ -1380,8 +1383,15 @@ CONFIG_CRYPTO_DES=y # # Hardware crypto devices # +# CONFIG_XEN_UTIL is not set CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_NETDEV_FRONTEND=y +# CONFIG_XEN_DEVMEM is not set +CONFIG_XEN_REBOOT=y +# CONFIG_XEN_SMPBOOT is not set CONFIG_XEN_INTERFACE_VERSION=0x00030202 # @@ -1389,13 +1399,15 @@ CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # CONFIG_XEN_PRIVILEGED_GUEST is not set CONFIG_XEN_UNPRIVILEGED_GUEST=y +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y # CONFIG_XEN_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y -CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_SCRUB_PAGES is not set # CONFIG_XEN_DISABLE_SERIAL is not set CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y diff -r 4acc6d51f389 -r b76e86966e7e buildconfigs/linux-defconfig_xen_ia64 --- a/buildconfigs/linux-defconfig_xen_ia64 Tue Aug 01 14:58:20 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_ia64 Wed Aug 02 13:39:47 2006 -0600 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16.13-xen -# Thu Jun 29 16:23:48 2006 +# Fri Jul 28 16:33:08 2006 # # @@ -92,6 +92,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_XEN=y CONFIG_XEN_IA64_DOM0_VP=y +CONFIG_XEN_IA64_VDSO_PARAVIRT=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_IS_DMA32=y # CONFIG_IA64_GENERIC is not set @@ -180,6 +181,8 @@ CONFIG_ACPI_CONTAINER=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_XEN_PCIDEV_FRONTEND=y +# CONFIG_XEN_PCIDEV_FE_DEBUG is not set CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set @@ -1519,7 +1522,7 @@ CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_DEVMEM is not set -# CONFIG_XEN_REBOOT is not set +CONFIG_XEN_REBOOT=y # CONFIG_XEN_SMPBOOT is not set CONFIG_XEN_INTERFACE_VERSION=0x00030202 @@ -1529,13 +1532,16 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -# CONFIG_XEN_PCIDEV_BACKEND is not set CONFIG_XEN_BLKDEV_BACKEND=y -CONFIG_XEN_XENBUS_DEV=y # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=y +CONFIG_XEN_PCIDEV_BACKEND_VPCI=y +# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y # CONFIG_XEN_SCRUB_PAGES is not set diff -r 4acc6d51f389 -r b76e86966e7e docs/src/user.tex --- a/docs/src/user.tex Tue Aug 01 14:58:20 2006 -0600 +++ b/docs/src/user.tex Wed Aug 02 13:39:47 2006 -0600 @@ -2059,6 +2059,988 @@ iptables: # this command disables all access to the Xen relocation port iptables -A INPUT -p tcp -{}-destination-port 8002 -j REJECT \end{verbatim} + +%% Chapter Xen Mandatory Access Control Framework +\chapter{sHype/Xen Access Control} + +The Xen mandatory access control framework is an implementation of the +sHype Hypervisor Security Architecture +(www.research.ibm.com/ssd\_shype). It permits or denies communication +and resource access of domains based on a security policy. The +mandatory access controls are enforced in addition to the Xen core +controls, such as memory protection. They are designed to remain +transparent during normal operation of domains (policy-conform +behavior) but to intervene when domains move outside their intended +sharing behavior. This chapter will describe how the sHype access +controls in Xen can be configured to prevent viruses from spilling +over from one into another workload type and secrets from leaking from +one workload type to another. sHype/Xen depends on the correct +behavior of Domain0 (cf previous chapter). + +Benefits of configuring sHype/ACM in Xen include: +\begin{itemize} +\item robust workload and resource protection effective against rogue + user domains +\item simple, platform- and operating system-independent security + policies (ideal for heterogeneous distributed environments) +\item safety net with minimal performance overhead in case operating + system security is missing, does not scale, or fails +\end{itemize} + +These benefits are very valuable because today's operating systems +become increasingly complex and often have no or insufficient +mandatory access controls. (Discretionary access controls, supported +by of most operating systems, are not effective against viruses or +misbehaving programs.) Where mandatory access control exists (e.g., +SELinux), they usually deploy complex and difficult to understand +security policies. Additionally, multi-tier applications in business +environments usually require different types of operating systems +(e.g., AIX, Windows, Linux) which cannot be configured with compatible +security policies. Related distributed transactions and workloads +cannot be easily protected on the OS level. The Xen access control +framework steps in to offer a coarse-grained but very robust security +layer and safety net in case operating system security fails or is +missing. + +To control sharing between domains, Xen mediates all inter-domain +communication (shared memory, events) as well as the access of domains +to resources such as disks. Thus, Xen can confine distributed +workloads (domain payloads) by permitting sharing among domains +running the same type of workload and denying sharing between pairs of +domains that run different workload types. We assume that--from a Xen +perspective--only one workload type is running per user domain. To +enable Xen to associate domains and resources with workload types, +security labels including the workload types are attached to domains +and resources. These labels and the hypervisor sHype controls cannot +be manipulated or bypassed and are effective even against rogue +domains. + +\section{Overview} +This section gives an overview of how workloads can be protected using +the sHype mandatory access control framework in Xen. +Figure~\ref{fig:acmoverview} shows the necessary steps in activating +the Xen workload protection. These steps are described in detail in +Section~\ref{section:acmexample}. + +\begin{figure} +\centering +\includegraphics[width=13cm]{figs/acm_overview.eps} +\caption{Overview of activating sHype workload protection in Xen. + Section numbers point to representative examples.} +\label{fig:acmoverview} +\end{figure} + +First, the sHype/ACM access control must be enabled in the Xen +distribution and the distribution must be built and installed (cf +Subsection~\ref{subsection:acmexampleconfigure}). Before we can +enforce security, a Xen security policy must be created (cf +Subsection~\ref{subsection:acmexamplecreate}) and deployed (cf +Subsection~\ref{subsection:acmexampleinstall}). This policy defines +the workload types differentiated during access control. It also +defines the rules that compare workload types of domains and resources +to provide access decisions. Workload types are represented by +security labels that can be attached to domains and resources (cf +Subsections~\ref{subsection:acmexamplelabeldomains} +and~\ref{subsection:acmexamplelabelresources}). The functioning of +the active sHype/Xen workload protection is demonstrated using simple +resource assignment, and domain creation tests in +Subsection~\ref{subsection:acmexampletest}. +Section~\ref{section:acmpolicy} describes the syntax and semantics of +the sHype/Xen security policy in detail and introduces briefly the +tools that are available to help create valid security policies. + +The next section describes all the necessary steps to create, deploy, +and test a simple workload protection policy. It is meant to enable +anybody to quickly try out the sHype/Xen workload protection. Those +readers who are interested in learning more about how the sHype access +control in Xen works and how it is configured using the XML security +policy should read Section~\ref{section:acmpolicy} as well. +Section~\ref{section:acmlimitations} concludes this chapter with +current limitations of the sHype implementation for Xen. + +\section{Xen Workload Protection Step-by-Step} +\label{section:acmexample} + +What you are about to do consists of the following sequence: +\begin{itemize} +\item configure and install sHype/Xen +\item create a simple workload protection security policy +\item deploy the sHype/Xen security policy +\item associate domains and resources with workload labels, +\item test the workload protection +\end{itemize} +The essential commands to create and deploy a sHype/Xen security +policy are numbered throughout the following sections. If you want a +quick-guide or return at a later time to go quickly through this +demonstration, simply look for the numbered commands and apply them in +order. + +\subsection{Configuring/Building sHype Support into Xen} +\label{subsection:acmexampleconfigure} +First, we need to configure the access control module in Xen and +install the ACM-enabled Xen hypervisor. This step installs security +tools and compiles sHype/ACM controls into the Xen hypervisor. + +To enable sHype/ACM in Xen, please edit the Config.mk file in the top +Xen directory. + +\begin{verbatim} + (1) In Config.mk + Change: ACM_SECURITY ?= n + To: ACM_SECURITY ?= y +\end{verbatim} + +Then install the security-enabled Xen environment as follows: + +\begin{verbatim} + (2) # make world + # make install +\end{verbatim} + +\subsection{Creating A WLP Policy in 3 Simple Steps with ezPolicy} +\label{subsection:acmexamplecreate} + +We will use the ezPolicy tool to quickly create a policy that protects +workloads. You will need both the Python and wxPython packages to run +this tool. To run the tool in Domain0, you can download the wxPython +package from www.wxpython.org or use the command +\verb|yum install wxPython| in Redhat/Fedora. To run the tool on MS +Windows, you also need to download the Python package from +www.python.org. After these packages are installed, start the ezPolicy +tool with the following command: + +\begin{verbatim} + (3) # xensec_ezpolicy +\end{verbatim} + +Figure~\ref{fig:acmezpolicy} shows a screen-shot of the tool. The +following steps show you how to create the policy shown in +Figure~\ref{fig:acmezpolicy}. You can use \verb|<CTRL>-h| to pop up a +help window at any time. The indicators (a), (b), and (c) in +Figure~\ref{fig:acmezpolicy} show the buttons that are used during the +3 steps of creating a policy: +\begin{enumerate} +\item defining workloads +\item defining run-time conflicts +\item translating the workload definition into a sHype/Xen access + control policy +\end{enumerate} + +\paragraph{Defining workloads.} Workloads are defined for each +organization and department that you enter in the left panel. Please +use the ``New Org'' button (a) to create the organizations ``Avis'', +``Hertz'', ``CocaCola'', and ``PepsiCo''. + +You can refine an organization to differentiate between multiple +department workloads by right-clicking the organization and selecting +\verb|Add Department| (or selecting an organization and pressing +\verb|<CRTL>-a|). Create department workloads ``Intranet'', +``Extranet'', ``HumanResources'', and ``Payroll'' for the ``CocaCola'' +organization and department workloads ``Intranet'' and ``Extranet'' +for the ``PepsiCo'' organization. The resulting layout of the tool +should be similar to the left panel shown in +Figure~\ref{fig:acmezpolicy}. + +\paragraph{Defining run-time conflicts.} Workloads that shall be +prohibited from running concurrently on the same hypervisor platform +are grouped into ``Run-time Exclusion rules'' on the right panel of +the window. + +To prevent PepsiCo and CocaCola workloads (including their +departmental workloads) from running simultaneously on the same +hypervisor system, select the organization ``PepsiCo'' and, while +pressing the \verb|<CTRL>|-key, select the organization ``CocaCola''. +Now press the button (b) named ``Create run-time exclusion rule from +selection''. A popup window will ask for the name for this run-time +exclusion rule (enter a name or just hit \verb|<ENTER>|). A rule will +appear on the right panel. The name is used as reference only and does +not affect the hypervisor policy. + +Repeat the process to create a run-time exclusion rule just for the +department workloads CocaCola.Extranet and CocaCola.Payroll. + +\begin{figure}[htb] +\centering +\includegraphics[width=13cm]{figs/acm_ezpolicy.eps} +\caption{Final layout including workload definition and Run-time Exclusion rules.} +\label{fig:acmezpolicy} +\end{figure} + +The resulting layout of your window should be similar to +Figure~\ref{fig:acmezpolicy}. Save this workload definition by +selecting ``Save Workload Definition as ...'' in the ``File'' menu +(c). This workload definition can be later refined if required. + +\paragraph{Translating the workload definition into a sHype/Xen access + control policy.} To translate the workload definition into a access +control policy understood by Xen, please select the ``Save as Xen ACM +Security Policy'' in the ``File'' menu (c). Enter the following policy +name in the popup window: \verb|example.chwall_ste.test-wld|. If you +are running ezPolicy in Domain0, the resulting policy file +test-wld\_security-policy.xml will automatically be placed into the +right directory (/etc/xen/acm-security/ policies/example/chwall\_ste). +If you run the tool on another system, then you need to copy the +resulting policy file into Domain0 before continuing. See +Section~\ref{subsection:acmnaming} for naming conventions of security +policies. + +\subsection{Deploying a WLP Policy} +\label{subsection:acmexampleinstall} +To deploy the workload protection policy we created in +Section~\ref{subsection:acmexamplecreate}, we create a policy +representation (test-wld.bin) that can be loaded into the Xen +hypervisor and we configure Xen to actually load this policy at +startup time. + +The following command translates the source policy representation +into a format that can be loaded into Xen with sHype/ACM support. +Refer to the \verb|xm| man page for further details: + +\begin{verbatim} + (4) # xm makepolicy example.chwall_ste.test-wld +\end{verbatim} + +The easiest way to install a security policy for Xen is to include the +policy in the boot sequence. The following command does just this: + +\begin{verbatim} + (5) # xm cfgbootpolicy example.chwall_ste.test-wld +\end{verbatim} + +\textit{Alternatively, if this command fails} (e.g., because it cannot +identify the Xen boot entry), you can manually install the policy in 2 +steps. First, manually copy the policy binary file into the boot +directory: + +\begin{scriptsize} +\begin{verbatim} + # cp /etc/xen/acm-security/policies/example/chwall_ste/test-wld.bin \ + /boot/example.chwall_ste.test-wld.bin +\end{verbatim} +\end{scriptsize} + +Second, manually add a module line to your Xen boot entry so that grub +loads this policy file during startup: + +\begin{scriptsize} +\begin{verbatim} + title Xen (2.6.16.13) + root (hd0,0) + kernel /xen.gz dom0_mem=2000000 console=vga + module /vmlinuz-2.6.16.13-xen ro root=/dev/hda3 + module /initrd-2.6.16.13-xen.img + module /example.chwall_ste.test-wld.bin +\end{verbatim} +\end{scriptsize} + +Now reboot into this Xen boot entry to activate the policy and the +security-enabled Xen hypervisor. + +\begin{verbatim} + (6) # reboot +\end{verbatim} + +After reboot, check if security is enabled: + +\begin{scriptsize} +\begin{verbatim} + # xm list --label + Name ID Mem(MiB) VCPUs State Time(s) Label + Domain-0 0 1949 4 r----- 163.9 SystemManagement +\end{verbatim} +\end{scriptsize} + +If the security label at the end of the line says ``INACTIV'' then the +security is not enabled. Verify the previous steps. Note: Domain0 is +assigned a default label (see \verb|bootstrap| policy attribute +explained in Section~\ref{section:acmpolicy}). All other domains must +be labeled in order to start on this sHype/ACM-enabled Xen hypervisor +(see following sections for labeling domains and resources). + +\subsection{Labeling Domains} +\label{subsection:acmexamplelabeldomains} +You should have a Xen domain configuration file that looks like the +following (Note: www.jailtime.org or www.xen-get.org might be good +places to look for example domU images). The following configuration +file defines \verb|domain1|: + +\begin{scriptsize} +\begin{verbatim} + # cat domain1.xm + kernel = "/boot/vmlinuz-2.6.16.13-xen" + memory = 128 + name = "domain1" + vif = [ '' ] + dhcp = "dhcp" + disk = ['file:/home/xen/dom_fc5/fedora.fc5.img,sda1,w', \ + 'file:/home/xen/dom_fc5/fedora.swap,sda2,w'] + root = "/dev/sda1 ro" +\end{verbatim} +\end{scriptsize} + +If you try to start domain1, you will get the following error: + +\begin{scriptsize} +\begin{verbatim} + # xm create domain1.xm + Using config file "domain1.xm". + domain1: DENIED + --> Domain not labeled + Checking resources: (skipped) + Security configuration prevents domain from starting +\end{verbatim} +\end{scriptsize} + +Every domain must be associated with a security label before it can +start on sHype/Xen. Otherwise, sHype/Xen would not be able to enforce +the policy consistently. The following command prints all domain +labels available in the active policy: + +\begin{scriptsize} +\begin{verbatim} + # xm labels type=dom + Avis + CocaCola + CocaCola.Extranet + CocaCola.HumanResources + CocaCola.Intranet + CocaCola.Payroll + Hertz + PepsiCo + PepsiCo.Extranet + PepsiCo.Intranet + SystemManagement +\end{verbatim} +\end{scriptsize} + +Now label domain1 with the CocaCola label and another domain2 with the +PepsiCo.Extranet label. Please refer to the xm man page for further +information. + +\begin{verbatim} + (7) # xm addlabel CocaCola dom domain1.xm + # xm addlabel PepsiCo.Extranet dom domain2.xm +\end{verbatim} + +Let us try to start the domain again: + +\begin{scriptsize} +\begin{verbatim} + # xm create domain1.xm + Using config file "domain1.xm". + file:/home/xen/dom_fc5/fedora.fc5.img: DENIED + --> res:__NULL_LABEL__ (NULL) + --> dom:CocaCola (example.chwall_ste.test-wld) + file:/home/xen/dom_fc5/fedora.swap: DENIED + --> res:__NULL_LABEL__ (NULL) + --> dom:CocaCola (example.chwall_ste.test-wld) + Security configuration prevents domain from starting +\end{verbatim} +\end{scriptsize} + +This error indicates that domain1, if started, would not be able to +access its image and swap files because they are not labeled. This +makes sense because to confine workloads, access of domains to +resources must be controlled. Otherwise, domains that are not allowed +to communicate or run simultaneously could share data through storage +resources. + +\subsection{Labeling Resources} +\label{subsection:acmexamplelabelresources} +You can use the \verb|xm labels type=res| command to list available +resource labels. Let us assign the CocaCola resource label to the domain1 +image file representing \verb|/dev/sda1| and to its swap file: + +\begin{verbatim} + (8) # xm addlabel CocaCola res \ + file:/home/xen/dom_fc5/fedora.fc5.img + Resource file not found, creating new file at: + /etc/xen/acm-security/policies/resource_labels + # xm addlabel CocaCola res \ + file:/home/xen/dom_fc5/fedora.swap +\end{verbatim} + +Starting \verb|domain1| now will succeed: + +\begin{scriptsize} +\begin{verbatim} + # xm create domain1.xm + # xm list --label + Name ID Mem(MiB) VCPUs State Time(s) Label + domain1 1 128 1 r----- 2.8 CocaCola + Domain-0 0 1949 4 r----- 387.7 SystemManagement +\end{verbatim} +\end{scriptsize} + +The following command lists all labeled resources on the +system, e.g., to lookup or verify the labeling: + +\begin{scriptsize} +\begin{verbatim} + # xm resources + file:/home/xen/dom_fc5/fedora.swap + policy: example.chwall_ste.test-wld + label: CocaCola + file:/home/xen/dom_fc5/fedora.fc5.img + policy: example.chwall_ste.test-wld + label: CocaCola +\end{verbatim} +\end{scriptsize} + +Currently, if a labeled resource is moved to another location, the +label must first be manually removed, and after the move re-attached +using the xm commands \verb|xm rmlabel| and \verb|xm addlabel| +respectively. Please see Section~\ref{section:acmlimitations} for +further details. + +\begin{verbatim} + (9) Label the resources of domain2 as PepsiCo.Extranet + Do not try to start this domain yet +\end{verbatim} + +\subsection{Testing The Xen Workload Protection} +\label{subsection:acmexampletest} +We are about to demonstrate how the workload protection works by +verifying: +\begin{itemize} +\item that domains with conflicting workloads cannot run + simultaneously +\item that domains cannot access resources of other workloads +\item that domains cannot exchange network packets if they are not + associated with the same workload type +\end{itemize} + +\paragraph{Test 1: Run-time exclusion rules.} We assume that domain1 +with the CocaCola label is still running. While domain1 is running, +the run-time exclusion set of our policy says that domain2 cannot +start because the label of domain1 includes the CHWALL type CocaCola +and the label of domain2 includes the CHWALL type PepsiCo. The +run-time exclusion rule of our policy enforces that PepsiCo and +CocaCola cannot run at the same time on the same hypervisor platform. +Once domain1 is stopped or saved, domain2 can start but domain1 can no +longer start or be resumed. The ezPolicy tool, when creating the +Chinese Wall types for the workload labels, ensures that department +workloads inherit the organization type (and with it any organization +exclusions). + +\begin{scriptsize} +\begin{verbatim} +# xm list --label +Name ID Mem(MiB) VCPUs State Time(s) Label +domain1 2 128 1 -b---- 6.9 CocaCola +Domain-0 0 1949 4 r----- 273.1 SystemManagement + +# xm create domain2.xm +Using config file "domain2.xm". +Error: (1, 'Operation not permitted') + +# xm destroy domain1 +# xm create domain2.xm +Using config file "domain2.xm". +Started domain domain2 + +# xm list --label +Name ID Mem(MiB) VCPUs State Time(s) Label +domain2 4 164 1 r----- 4.3 PepsiCo.Extranet +Domain-0 0 1949 4 r----- 298.4 SystemManagement + +# xm create domain1.xm +Using config file "domain1.xm". +Error: (1, 'Operation not permitted') + +# xm destroy domain2 +# xm list +Name ID Mem(MiB) VCPUs State Time(s) +Domain-0 0 1949 4 r----- 391.2 +\end{verbatim} +\end{scriptsize} + +You can verify that domains with Avis label can run together with +domains labeled CocaCola, PepsiCo, or Hertz. + +\paragraph{Test2: Resource access.} In this test, we will re-label the +swap file for domain1 with the Avis resource label. We expect that +Domain1 will no longer start because it cannot access this resource. +This test checks the sharing abilities of domains, which are defined +by the Simple Type Enforcement Policy component. + +\begin{scriptsize} +\begin{verbatim} +# xm rmlabel res file:/home/xen/dom_fc5/fedora.swap +# xm addlabel Avis res file:/home/xen/dom_fc5/fedora.swap +# xm resources +file:/home/xen/dom_fc5/fedora.swap + policy: example.chwall_ste.test-wld + label: Avis +file:/home/xen/dom_fc5/fedora.fc5.img + policy: example.chwall_ste.test-wld + label: CocaCola + +# xm create domain1.xm +Using config file "domain1.xm". + file:/home/xen/dom_fc4/fedora.swap: DENIED + --> res:Avis (example.chwall_ste.test-wld) + --> dom:CocaCola (example.chwall_ste.test-wld) +Security configuration prevents domain from starting +\end{verbatim} +\end{scriptsize} + +\paragraph{Test 3: Communication.} In this test we would verify that +two domains with labels Hertz and Avis cannot exchange network packets +by using the 'ping' connectivity test. It is also related to the STE +policy.{\bf Note:} sHype/Xen does control direct communication between +domains. However, domains associated with different workloads can +currently still communicate through the Domain0 virtual network. We +are working on the sHype/ACM controls for local and remote network +traffic through Domain0. Please monitor the xen-devel mailing list +for updated information. + +\section{Xen Access Control Policy} +\label{section:acmpolicy} + +This section describes the sHype/Xen access control policy in detail. +It gives enough information to enable the reader to write custom +access control policies and to use the available Xen policy tools. The +policy language is expressive enough to specify most symmetric access +relationships between domains and resources efficiently. + +The Xen access control policy consists of two policy components. The +first component, called Chinese Wall (CHWALL) policy, controls which +domains can run simultaneously on the same virtualized platform. The +second component, called Simple Type Enforcement (STE) policy, +controls the sharing between running domains, i.e., communication or +access to shared resources. The CHWALL and STE policy components can +be configured to run alone, however in our examples we will assume +that both policy components are configured together since they +complement each other. The XML policy file includes all information +needed by Xen to enforce the policies. + +Figures~\ref{fig:acmxmlfilea} and \ref{fig:acmxmlfileb} show a fully +functional but very simple example policy for Xen. The policy can +distinguish two workload types \verb|CocaCola| and \verb|PepsiCo| and +defines the labels necessary to associate domains and resources with +one of these workload types. The XML Policy consists of four parts: +\begin{enumerate} +\item policy header including the policy name +\item Simple Type Enforcement block +\item Chinese Wall Policy block +\item label definition block +\end{enumerate} + +\begin{figure} +\begin{scriptsize} +\begin{verbatim} +01 <?xml version="1.0" encoding="UTF-8"?> +02 <!-- Auto-generated by ezPolicy --> +03 <SecurityPolicyDefinition + xmlns="http://www.ibm.com" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation= + "http://www.ibm.com ../../security_policy.xsd "> +04 <PolicyHeader> +05 <PolicyName>example.chwall_ste.test</PolicyName> +06 <Date>Wed Jul 12 17:32:59 2006</Date> +07 </PolicyHeader> +08 +09 <SimpleTypeEnforcement> +10 <SimpleTypeEnforcementTypes> +11 <Type>SystemManagement</Type> +12 <Type>PepsiCo</Type> +13 <Type>CocaCola</Type> +14 </SimpleTypeEnforcementTypes> +15 </SimpleTypeEnforcement> +16 +17 <ChineseWall priority="PrimaryPolicyComponent"> +18 <ChineseWallTypes> +19 <Type>SystemManagement</Type> +20 <Type>PepsiCo</Type> +21 <Type>CocaCola</Type> +22 </ChineseWallTypes> +23 +24 <ConflictSets> +25 <Conflict name="RER1"> +26 <Type>CocaCola</Type> +27 <Type>PepsiCo</Type> +28 </Conflict> +29 </ConflictSets> +30 </ChineseWall> +31 +\end{verbatim} +\end{scriptsize} +\caption{Example XML security policy file -- Part I: Types and Rules Definition.} +\label{fig:acmxmlfilea} +\end{figure} + +\subsection{Policy Header and Policy Name} +\label{subsection:acmnaming} +Lines 1-2 (cf Figure~\ref{fig:acmxmlfilea}) include the usual XML +header. The security policy definition starts in Line 3 and refers to +the policy schema. The XML-Schema definition for the Xen policy can be +found in the file +\textit{/etc/xen/acm-security/policies/security-policy.xsd}. Examples +for security policies can be found in the example subdirectory. The +acm-security directory is only installed if ACM security is configured +during installation (cf Section~\ref{subsection:acmexampleconfigure}). + +The \verb|Policy Header| spans lines 4-7. It includes a date field and +defines the policy name \verb|example.chwall_ste.test|. It can also +include optional fields that are not shown and are for future use (see +schema definition). + +The policy name serves two purposes: First, it provides a unique name +for the security policy. This name is also exported by the Xen +hypervisor to the Xen management tools in order to ensure that both +enforce the same policy. We plan to extend the policy name with a +digital fingerprint of the policy contents to better protect this +correlation. Second, it implicitly points the xm tools to the +location where the XML policy file is stored on the Xen system. +Replacing the colons in the policy name by slashes yields the local +path to the policy file starting from the global policy directory +\verb|/etc/xen/acm-security/policies|. The last part of the policy +name is the prefix for the XML policy file name, completed by +\verb|-security_policy.xml|. Consequently, the policy with the name +\verb|example.chwall_ste.test| can be found in the XML policy file +named \verb|test-security_policy.xml| that is stored in the local +directory \verb|example/chwall_ste| under the global policy directory. + +\subsection{Simple Type Enforcement Policy Component} + +The Simple Type Enforcement (STE) policy controls which domains can +communicate or share resources. This way, Xen can enforce confinement +of workload types by confining the domains running those workload +types. The mandatory access control framework enforces its policy when +domains access intended ways of communication or cooperation (shared +memory, events, shared resources such as block devices). It builds on +top of the core hypervisor isolation, which restricts the ways of +inter-communication to those intended means. STE does not protect or +intend to protect from covert channels in the hypervisor or hardware; +this is an orthogonal problem that can be mitigated by using the +Run-time Exclusion rules described above or by fixing the problem in +the core hypervisor. + +Xen controls sharing between domains on the resource and domain level +because this is the abstraction the hypervisor and its management +understand naturally. While this is coarse-grained, it is also very +reliable and robust and it requires minimal changes to implement +mandatory access controls in the hypervisor. It enables platform- and +operation system-independent policies as part of a layered security +approach. + +Lines 9-15 (cf Figure~\ref{fig:acmxmlfilea}) define the Simple Type +Enforcement policy component. Essentially, they define the workload +type names \verb|SystemManagement|, \verb|PepsiCo|, and +\verb|CocaCola| that are available in the STE policy component. The +policy rules are implicit: Xen permits a domain to communicate with +another domain if and only if the labels of the domains share an +common STE type. Xen permits a domain to access a resource if and +only if the labels of the domain and the resource share a common STE +workload type. + +\subsection{Chinese Wall Policy Component} + +The Chinese Wall security policy interpretation of sHype enables users +to prevent certain workloads from running simultaneously on the same +hypervisor platform. Run-time Exclusion rules (RER), also called +Conflict Sets, define a set of workload types that are not permitted +to run simultaneously. Of all the workloads specified in a Run-time +Exclusion rule, at most one type can run on the same hypervisor +platform at a time. Run-time Exclusion Rules implement a less +rigorous variant of the original Chinese Wall security component. They +do not implement the *-property of the policy, which would require to +restrict also types that are not part of an exclusion rule once they +are running together with a type in an exclusion rule (please refer to +http://www.gammassl.co.uk/topics/chinesewall.html for more information +on the original Chinese Wall policy). + +Xen considers the \verb|ChineseWallTypes| part of the label for the +enforcement of the Run-time Exclusion rules. It is illegal to define +labels including conflicting Chinese Wall types. + +Lines 17-30 (cf Figure~\ref{fig:acmxmlfilea}) define the Chinese Wall +policy component. Lines 17-22 define the known Chinese Wall types, +which coincide here with the STE types defined above. This usually +holds if the criteria for sharing among domains and sharing of the +hardware platform are the same. Lines 24-29 define one Run-time +Exclusion rule: + +\begin{scriptsize} +\begin{verbatim} + <Conflict name="RER1"> + <Type>CocaCola</Type> + <Type>PepsiCo</Type> + </Conflict> +\end{verbatim} +\end{scriptsize} + +Based on this rule, Xen enforces that only one of the types +\verb|CocaCola| or \verb|PepsiCo| will run on a single hypervisor +platform at a time. For example, once a domain assigned a +\verb|CocaCola| workload type is started, domains with the +\verb|PepsiCo| type will be denied to start. When the former domain +stops and no other domains with the \verb|CocaCola| type are running, +then domains with the \verb|PepsiCo| type can start. + +Xen maintains reference counts on each running workload type to keep +track of which workload types are running. Every time a domain starts +or resumes, the reference count on those Chinese Wall types that are +referenced in the domain's label are incremented. Every time a domain +is destroyed or saved, the reference counts of its Chinese Wall types +are decremented. sHype in Xen covers migration and live-migration, +which is treated the same way as saving a domain on the source +platform and resuming it on the destination platform. + +Reasons why users would want to restrict which workloads or domains +can share the system hardware include: + +\begin{itemize} +\item Imperfect resource management or control might enable a rogue + domain to starve another domain and the workload running in it. +\item Redundant domains might run the same workload to increase + availability; such domains should not run on the same hardware to + avoid single points of failure. +\item Imperfect Xen core domain isolation might enable two rogue + domains running different workload types to use unintended and + unknown ways (covert channels) to exchange some data. This way, they + bypass the policed Xen access control mechanisms. Such + imperfections cannot be completely eliminated and are a result of + trade-offs between security and other design requirements. For a + simple example of a covert channel see + http://www.multicians.org/timing-chn.html. Such covert channels + exist also between workloads running on different platforms if they + are connected through networks. The Xen Chinese Wall policy provides + an approximation of this imperfect ``air-gap'' between selected + workload types. +\end{itemize} + +\subsection{Security Labels} + +To enable Xen to associate domains with workload types running in +them, each domain is assigned a security label that includes the +workload types of the domain. + +\begin{figure} +\begin{scriptsize} +\begin{verbatim} +32 <SecurityLabelTemplate> +33 <SubjectLabels bootstrap="SystemManagement"> +34 <VirtualMachineLabel> +35 <Name>SystemManagement</Name> +36 <SimpleTypeEnforcementTypes> +37 <Type>SystemManagement</Type> +38 <Type>PepsiCo</Type> +39 <Type>CocaCola</Type> +40 </SimpleTypeEnforcementTypes> +41 <ChineseWallTypes> +42 <Type>SystemManagement</Type> +43 </ChineseWallTypes> +44 </VirtualMachineLabel> +45 +46 <VirtualMachineLabel> +47 <Name>PepsiCo</Name> +48 <SimpleTypeEnforcementTypes> +49 <Type>PepsiCo</Type> +50 </SimpleTypeEnforcementTypes> +51 <ChineseWallTypes> +52 <Type>PepsiCo</Type> +53 </ChineseWallTypes> +54 </VirtualMachineLabel> +55 +56 <VirtualMachineLabel> +57 <Name>CocaCola</Name> +58 <SimpleTypeEnforcementTypes> +59 <Type>CocaCola</Type> +60 </SimpleTypeEnforcementTypes> +61 <ChineseWallTypes> +62 <Type>CocaCola</Type> +63 </ChineseWallTypes> +64 </VirtualMachineLabel> +65 </SubjectLabels> +66 +67 <ObjectLabels> +68 <ResourceLabel> +69 <Name>SystemManagement</Name> +70 <SimpleTypeEnforcementTypes> +71 <Type>SystemManagement</Type> +72 </SimpleTypeEnforcementTypes> +73 </ResourceLabel> +74 +75 <ResourceLabel> +76 <Name>PepsiCo</Name> +77 <SimpleTypeEnforcementTypes> +78 <Type>PepsiCo</Type> +79 </SimpleTypeEnforcementTypes> +80 </ResourceLabel> +81 +82 <ResourceLabel> +83 <Name>CocaCola</Name> +84 <SimpleTypeEnforcementTypes> +85 <Type>CocaCola</Type> +86 </SimpleTypeEnforcementTypes> +87 </ResourceLabel> +88 </ObjectLabels> +89 </SecurityLabelTemplate> +90 </SecurityPolicyDefinition> +\end{verbatim} +\end{scriptsize} +\caption{Example XML security policy file -- Part II: Label Definition.} +\label{fig:acmxmlfileb} +\end{figure} + +Lines 32-89 (cf Figure~\ref{fig:acmxmlfileb}) define the +\verb|SecurityLabelTemplate|, which includes the labels that can be +attached to domains and resources when this policy is active. The +domain labels include Chinese Wall types while resource labels do not +include Chinese Wall types. Lines 33-65 define the +\verb|SubjectLabels| that can be assigned to domains. For example, the +virtual machine label \verb|CocaCola| (cf lines 56-64 in +Figure~\ref{fig:acmxmlfileb}) associates the domain that carries it +with the workload type \verb|CocaCola|. + +The \verb|bootstrap| attribute names the label +\verb|SystemManagement|. Xen will assign this label to Domain0 at +boot time. All other domains are assigned labels according to their +domain configuration file (see +Section~\ref{subsection:acmexamplelabeldomains} for examples of how to +label domains). Lines 67-88 define the \verb|ObjectLabels|. Those +labels can be assigned to resources when this policy is active. + +In general, user domains should be assigned labels that have only a +single SimpleTypeEnforcement workload type. This way, workloads remain +confined even if user domains become rogue. Any domain that is +assigned a label with multiple STE types must be trusted to keep +information belonging to the different STE types separate (confined). +For example, Domain0 is assigned the bootstrap label +\verb|SystemsManagement|, which includes all existing STE types. +Therefore, Domain0 must take care not to enable unauthorized +information flow (eg. through block devices or virtual networking) +between domains or resources that are assigned different STE types. + +Security administrators simply use the name of a label (specified in +the \verb|<Name>| field) to associate a label with a domain (cf. +Section~\ref{subsection:acmexamplelabeldomains}). The types inside the +label are used by the Xen access control enforcement. While the name +can be arbitrarily chosen (as long as it is unique), it is advisable +to choose the label name in accordance to the security types included. +While the XML representation in the above label seems unnecessary +flexible, labels in general can consist of multiple types as we will +see in the following example. + +Assume that \verb|PepsiCo| and \verb|CocaCola| workloads use virtual +disks that are provided by a virtual I/O domain hosting a physical +storage device and carrying the following label: + +\begin{scriptsize} +\begin{verbatim} + <VirtualMachineLabel> + <Name>VIO</Name> + <SimpleTypeEnforcementTypes> + <Type>CocaCola</Type> + <Type>PepsiCo</Type> + </SimpleTypeEnforcementTypes> + <ChineseWallTypes> + <Type>VIOServer</Type> + </ChineseWallTypes> + </VirtualMachineLabel> +\end{verbatim} +\end{scriptsize} + +This Virtual I/O domain (VIO) exports its virtualized disks by +communicating both to domains labeled with the \verb|PepsiCo| label +and domains labeled with the \verb|CocaCola| label. This requires the +VIO domain to carry both the STE types \verb|CocaCola| and +\verb|PepsiCo|. In this example, the confinement of \verb|CocaCola| +and \verb|PepsiCo| workload depends on a VIO domain that must keep the +data of those different workloads separate. The virtual disks are +labeled as well (see Section~\ref{subsection:acmexamplelabelresources} +for labeling resources) and enforcement functions inside the VIO +domain must ensure that the labels of the domain mounting a virtual +disk and the virtual disk label share a common STE type. The VIO label +carrying its own VIOServer CHWALL type introduces the flexibility to +permit the trusted VIO server to run together with CocaCola or PepsiCo +workloads. + +Alternatively, a system that has two hard-drives does not need a VIO +domain but can directly assign one hardware storage device to each of +the workloads (if the platform offers an IO-MMU, cf +Section~\ref{s:ddsecurity}. Sharing hardware through virtualization +is a trade-off between the amount of trusted code (size of the trusted +computing base) and the amount of acceptable over-provisioning. This +holds both for peripherals and for system platforms. + +\subsection{Tools For Creating sHype/Xen Security Policies} +To create a security policy for Xen, you can use one of the following +tools: +\begin{itemize} +\item \verb|ezPolicy| GUI tool -- start writing policies +\item \verb|xensec_gen| tool -- refine policies created with \verb|ezPolicy| +\item text or XML editor +\end{itemize} + +We use the \verb|ezPolicy| tool in +Section~\ref{subsection:acmexamplecreate} to quickly create a workload +protection policy. If desired, the resulting XML policy file can be +loaded into the \verb|xensec_gen| tool to refine it. It can also be +directly edited using an XML editor. Any XML policy file is verified +against the security policy schema when it is translated (see +Subsection~\ref{subsection:acmexampleinstall}). + +\section{Current Limitations} +\label{section:acmlimitations} + +The sHype/ACM configuration for Xen is work in progress. There is +ongoing work for protecting virtualized resources and planned and +ongoing work for protecting access to remote resources and domains. +The following sections describe limitations of some of the areas into +which access control is being extended. + +\subsection{Network Traffic} +Local and remote network traffic is currently not controlled. +Solutions to add sHype/ACM policy enforcement to the virtual network +exist but need to be discussed before they can become part of Xen. +Subjecting external network traffic to the ACM security policy is work +in progress. Manually setting up filters in domain 0 is required for +now but does not scale well. + +\subsection{Resource Access and Usage Control} + +Enforcing the security policy across multiple hypervisor systems and +on access to remote shared resources is work in progress. Extending +access control to new types of resources is ongoing work (e.g. network +storage). + +On a single Xen system, information about the association of resources +and security labels is stored in +\verb|/etc/xen/acm-security/policy/resource_labels|. This file relates +a full resource path with a security label. This association is weak +and will break if resources are moved or renamed without adapting the +label file. Improving the protection of label-resource relationships +is ongoing work. + +Controlling resource usage and enforcing resource limits in general is +ongoing work in the Xen community. + +\subsection{Domain Migration} + +Labels on domains are enforced during domain migration and the +destination hypervisor will ensure that the domain label is valid and +the domain is permitted to run (considering the Chinese Wall policy +rules) before it accepts the migration. However, the network between +the source and destination hypervisor as well as both hypervisors must +be trusted. Architectures and prototypes exist that both protect the +network connection and ensure that the hypervisors enforce access +control consistently but patches are not yet available for the main +stream. + +\subsection{Covert Channels} + +The sHype access control aims at system independent security policies. +It builds on top of the core hypervisor isolation. Any covert channels +that exist in the core hypervisor or in the hardware (e.g., shared +processor cache) will be inherited. If those covert channels are not +the result of trade-offs between security and other system properties, +then they are most effectively minimized or eliminated where they are +caused. sHype offers however some means to mitigate their impact +(cf. run-time exclusion rules). \part{Reference} diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c Wed Aug 02 13:39:47 2006 -0600 @@ -109,6 +109,7 @@ int init_new_context(struct task_struct init_MUTEX(&mm->context.sem); mm->context.size = 0; + mm->context.has_foreign_mappings = 0; old_mm = current->mm; if (old_mm && old_mm->context.size > 0) { down(&old_mm->context.sem); diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Wed Aug 02 13:39:47 2006 -0600 @@ -126,6 +126,8 @@ int direct_remap_pfn_range(struct vm_are if (domid == DOMID_SELF) return -EINVAL; + vma->vm_mm->context.has_foreign_mappings = 1; + return __direct_remap_pfn_range( vma->vm_mm, address, mfn, size, prot, domid); } diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Wed Aug 02 13:39:47 2006 -0600 @@ -694,6 +694,7 @@ void _arch_exit_mmap(struct mm_struct *m task_unlock(tsk); if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) && - (atomic_read(&mm->mm_count) == 1)) + (atomic_read(&mm->mm_count) == 1) && + !mm->context.has_foreign_mappings) mm_unpin(mm); } diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Wed Aug 02 13:39:47 2006 -0600 @@ -159,7 +159,8 @@ void _arch_exit_mmap(struct mm_struct *m task_unlock(tsk); - if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) ) + if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) && + !mm->context.has_foreign_mappings ) mm_unpin(mm); } diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 02 13:39:47 2006 -0600 @@ -76,6 +76,10 @@ typedef struct netif_st { struct vm_struct *tx_comms_area; struct vm_struct *rx_comms_area; + /* Set of features that can be turned on in dev->features. */ + int features; + int can_queue; + /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */ RING_IDX rx_req_cons_peek; @@ -119,4 +123,16 @@ struct net_device_stats *netif_be_get_st struct net_device_stats *netif_be_get_stats(struct net_device *dev); irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs); +static inline int netbk_can_queue(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + return netif->can_queue; +} + +static inline int netbk_can_sg(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + return netif->features & NETIF_F_SG; +} + #endif /* __NETIF__BACKEND__COMMON_H__ */ diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Aug 02 13:39:47 2006 -0600 @@ -51,23 +51,59 @@ static int net_open(struct net_device *d netif_t *netif = netdev_priv(dev); if (netif_carrier_ok(dev)) __netif_up(netif); - netif_start_queue(dev); return 0; } static int net_close(struct net_device *dev) { netif_t *netif = netdev_priv(dev); - netif_stop_queue(dev); if (netif_carrier_ok(dev)) __netif_down(netif); return 0; } +static int netbk_change_mtu(struct net_device *dev, int mtu) +{ + int max = netbk_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; + + if (mtu > max) + return -EINVAL; + dev->mtu = mtu; + return 0; +} + +static int netbk_set_sg(struct net_device *dev, u32 data) +{ + if (data) { + netif_t *netif = netdev_priv(dev); + + if (!(netif->features & NETIF_F_SG)) + return -ENOSYS; + } + + return ethtool_op_set_sg(dev, data); +} + +static int netbk_set_tso(struct net_device *dev, u32 data) +{ + if (data) { + netif_t *netif = netdev_priv(dev); + + if (!(netif->features & NETIF_F_TSO)) + return -ENOSYS; + } + + return ethtool_op_set_tso(dev, data); +} + static struct ethtool_ops network_ethtool_ops = { .get_tx_csum = ethtool_op_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = netbk_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = netbk_set_tso, .get_link = ethtool_op_get_link, }; @@ -103,12 +139,16 @@ netif_t *netif_alloc(domid_t domid, unsi dev->get_stats = netif_be_get_stats; dev->open = net_open; dev->stop = net_close; + dev->change_mtu = netbk_change_mtu; dev->features = NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(dev, &network_ethtool_ops); - /* Disable queuing. */ - dev->tx_queue_len = 0; + /* + * Reduce default TX queuelen so that each guest interface only + * allows it to eat around 6.4MB of host memory. + */ + dev->tx_queue_len = 100; for (i = 0; i < ETH_ALEN; i++) if (be_mac[i] != 0) diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 02 13:39:47 2006 -0600 @@ -40,17 +40,22 @@ /*#define NETBE_DEBUG_INTERRUPT*/ +struct netbk_rx_meta { + skb_frag_t frag; + int id; +}; + static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); static void make_tx_response(netif_t *netif, netif_tx_request_t *txp, s8 st); -static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - u16 offset, - u16 size, - u16 flags); +static netif_rx_response_t *make_rx_response(netif_t *netif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags); static void net_tx_action(unsigned long unused); static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); @@ -100,21 +105,27 @@ static unsigned long mfn_list[MAX_MFN_AL static unsigned long mfn_list[MAX_MFN_ALLOC]; static unsigned int alloc_index = 0; -static unsigned long alloc_mfn(void) -{ - unsigned long mfn = 0; +static inline unsigned long alloc_mfn(void) +{ + return mfn_list[--alloc_index]; +} + +static int check_mfn(int nr) +{ struct xen_memory_reservation reservation = { - .nr_extents = MAX_MFN_ALLOC, .extent_order = 0, .domid = DOMID_SELF }; - set_xen_guest_handle(reservation.extent_start, mfn_list); - if ( unlikely(alloc_index == 0) ) - alloc_index = HYPERVISOR_memory_op( - XENMEM_increase_reservation, &reservation); - if ( alloc_index != 0 ) - mfn = mfn_list[--alloc_index]; - return mfn; + + if (likely(alloc_index >= nr)) + return 0; + + set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index); + reservation.nr_extents = MAX_MFN_ALLOC - alloc_index; + alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation, + &reservation); + + return alloc_index >= nr ? 0 : -ENOMEM; } static inline void maybe_schedule_tx_action(void) @@ -136,6 +147,96 @@ static inline int is_xen_skb(struct sk_b return (cp == skbuff_cachep); } +static struct sk_buff *netbk_copy_skb(struct sk_buff *skb) +{ + struct skb_shared_info *ninfo; + struct sk_buff *nskb; + unsigned long offset; + int ret; + int len; + int headlen; + + nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC); + if (unlikely(!nskb)) + goto err; + + skb_reserve(nskb, 16); + headlen = nskb->end - nskb->data; + if (headlen > skb_headlen(skb)) + headlen = skb_headlen(skb); + ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen); + BUG_ON(ret); + + ninfo = skb_shinfo(nskb); + ninfo->gso_size = skb_shinfo(skb)->gso_size; + ninfo->gso_type = skb_shinfo(skb)->gso_type; + + offset = headlen; + len = skb->len - headlen; + + nskb->len = skb->len; + nskb->data_len = len; + nskb->truesize += len; + + while (len) { + struct page *page; + int copy; + int zero; + + if (unlikely(ninfo->nr_frags >= MAX_SKB_FRAGS)) { + dump_stack(); + goto err_free; + } + + copy = len >= PAGE_SIZE ? PAGE_SIZE : len; + zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO; + + page = alloc_page(GFP_ATOMIC | zero); + if (unlikely(!page)) + goto err_free; + + ret = skb_copy_bits(skb, offset, page_address(page), copy); + BUG_ON(ret); + + ninfo->frags[ninfo->nr_frags].page = page; + ninfo->frags[ninfo->nr_frags].page_offset = 0; + ninfo->frags[ninfo->nr_frags].size = copy; + ninfo->nr_frags++; + + offset += copy; + len -= copy; + } + + offset = nskb->data - skb->data; + + nskb->h.raw = skb->h.raw + offset; + nskb->nh.raw = skb->nh.raw + offset; + nskb->mac.raw = skb->mac.raw + offset; + + return nskb; + + err_free: + kfree_skb(nskb); + err: + return NULL; +} + +static inline int netbk_max_required_rx_slots(netif_t *netif) +{ + if (netif->features & (NETIF_F_SG|NETIF_F_TSO)) + return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */ + return 1; /* all in one */ +} + +static inline int netbk_queue_full(netif_t *netif) +{ + RING_IDX peek = netif->rx_req_cons_peek; + RING_IDX needed = netbk_max_required_rx_slots(netif); + + return ((netif->rx.sring->req_prod - peek) < needed) || + ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed); +} + int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { netif_t *netif = netdev_priv(dev); @@ -143,30 +244,26 @@ int netif_be_start_xmit(struct sk_buff * BUG_ON(skb->dev != dev); /* Drop the packet if the target domain has no receive buffers. */ - if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev)) || - (netif->rx_req_cons_peek == netif->rx.sring->req_prod) || - ((netif->rx_req_cons_peek - netif->rx.rsp_prod_pvt) == - NET_RX_RING_SIZE)) + if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev))) goto drop; + + if (unlikely(netbk_queue_full(netif))) { + /* Not a BUG_ON() -- misbehaving netfront can trigger this. */ + if (netbk_can_queue(dev)) + DPRINTK("Queue full but not stopped!\n"); + goto drop; + } /* * We do not copy the packet unless: * 1. The data is shared; or * 2. The data is not allocated from our special cache. - * NB. We also couldn't cope with fragmented packets, but we won't get - * any because we not advertise the NETIF_F_SG feature. + * 3. The data is fragmented. */ - if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { - int hlen = skb->data - skb->head; - int ret; - struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); + if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) { + struct sk_buff *nskb = netbk_copy_skb(skb); if ( unlikely(nskb == NULL) ) goto drop; - skb_reserve(nskb, hlen); - __skb_put(nskb, skb->len); - ret = skb_copy_bits(skb, -hlen, nskb->data - hlen, - skb->len + hlen); - BUG_ON(ret); /* Copy only the header fields we use in this driver. */ nskb->dev = skb->dev; nskb->ip_summed = skb->ip_summed; @@ -175,8 +272,17 @@ int netif_be_start_xmit(struct sk_buff * skb = nskb; } - netif->rx_req_cons_peek++; + netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 + + !!skb_shinfo(skb)->gso_size; netif_get(netif); + + if (netbk_can_queue(dev) && netbk_queue_full(netif)) { + netif->rx.sring->req_event = netif->rx_req_cons_peek + + netbk_max_required_rx_slots(netif); + mb(); /* request notification /then/ check & stop the queue */ + if (netbk_queue_full(netif)) + netif_stop_queue(dev); + } skb_queue_tail(&rx_queue, skb); tasklet_schedule(&net_rx_tasklet); @@ -208,116 +314,85 @@ int xen_network_done(void) } #endif -static void net_rx_action(unsigned long unused) -{ - netif_t *netif = NULL; - s8 status; - u16 size, id, irq, flags; - multicall_entry_t *mcl; - mmu_update_t *mmu; - gnttab_transfer_t *gop; - unsigned long vdata, old_mfn, new_mfn; - struct sk_buff_head rxq; - struct sk_buff *skb; - int notify_nr = 0; - int ret; +static u16 netbk_gop_frag(netif_t *netif, struct page *page, int count, int i) +{ + multicall_entry_t *mcl = rx_mcl + count; + mmu_update_t *mmu = rx_mmu + count; + gnttab_transfer_t *gop = grant_rx_op + count; + netif_rx_request_t *req; + unsigned long old_mfn, new_mfn; + + old_mfn = virt_to_mfn(page_address(page)); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + new_mfn = alloc_mfn(); + + /* + * Set the new P2M table entry before reassigning + * the old data page. Heed the comment in + * pgtable-2level.h:pte_page(). :-) + */ + set_phys_to_machine(page_to_pfn(page), new_mfn); + + MULTI_update_va_mapping(mcl, (unsigned long)page_address(page), + pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); + + mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE; + mmu->val = page_to_pfn(page); + } + + req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons + i); + gop->mfn = old_mfn; + gop->domid = netif->domid; + gop->ref = req->gref; + return req->id; +} + +static void netbk_gop_skb(struct sk_buff *skb, struct netbk_rx_meta *meta, + int count) +{ + netif_t *netif = netdev_priv(skb->dev); + int nr_frags = skb_shinfo(skb)->nr_frags; + int i; + int extra; + + meta[count].frag.page_offset = skb_shinfo(skb)->gso_type; + meta[count].frag.size = skb_shinfo(skb)->gso_size; + extra = !!meta[count].frag.size + 1; + + for (i = 0; i < nr_frags; i++) { + meta[++count].frag = skb_shinfo(skb)->frags[i]; + meta[count].id = netbk_gop_frag(netif, meta[count].frag.page, + count, i + extra); + } + /* - * Putting hundreds of bytes on the stack is considered rude. - * Static works because a tasklet can only be on one CPU at any time. + * This must occur at the end to ensure that we don't trash + * skb_shinfo until we're done. */ - static u16 notify_list[NET_RX_RING_SIZE]; - - skb_queue_head_init(&rxq); - - mcl = rx_mcl; - mmu = rx_mmu; - gop = grant_rx_op; - - while ((skb = skb_dequeue(&rx_queue)) != NULL) { - netif = netdev_priv(skb->dev); - vdata = (unsigned long)skb->data; - old_mfn = virt_to_mfn(vdata); - - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - /* Memory squeeze? Back off for an arbitrary while. */ - if ((new_mfn = alloc_mfn()) == 0) { - if ( net_ratelimit() ) - WPRINTK("Memory squeeze in netback " - "driver.\n"); - mod_timer(&net_timer, jiffies + HZ); - skb_queue_head(&rx_queue, skb); - break; - } - /* - * Set the new P2M table entry before reassigning - * the old data page. Heed the comment in - * pgtable-2level.h:pte_page(). :-) - */ - set_phys_to_machine( - __pa(skb->data) >> PAGE_SHIFT, - new_mfn); - - MULTI_update_va_mapping(mcl, vdata, - pfn_pte_ma(new_mfn, - PAGE_KERNEL), 0); - mcl++; - - mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) | - MMU_MACHPHYS_UPDATE; - mmu->val = __pa(vdata) >> PAGE_SHIFT; - mmu++; - } - - gop->mfn = old_mfn; - gop->domid = netif->domid; - gop->ref = RING_GET_REQUEST( - &netif->rx, netif->rx.req_cons)->gref; - netif->rx.req_cons++; - gop++; - - __skb_queue_tail(&rxq, skb); - - /* Filled the batch queue? */ - if ((gop - grant_rx_op) == ARRAY_SIZE(grant_rx_op)) - break; - } - - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - if (mcl == rx_mcl) - return; - - mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; - - if (mmu - rx_mmu) { - mcl->op = __HYPERVISOR_mmu_update; - mcl->args[0] = (unsigned long)rx_mmu; - mcl->args[1] = mmu - rx_mmu; - mcl->args[2] = 0; - mcl->args[3] = DOMID_SELF; - mcl++; - } - - ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); - BUG_ON(ret != 0); - } - - ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, - gop - grant_rx_op); - BUG_ON(ret != 0); - - mcl = rx_mcl; - gop = grant_rx_op; - while ((skb = __skb_dequeue(&rxq)) != NULL) { - netif = netdev_priv(skb->dev); - size = skb->tail - skb->data; - - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; - - netif->stats.tx_bytes += size; - netif->stats.tx_packets++; - + meta[count - nr_frags].id = netbk_gop_frag(netif, + virt_to_page(skb->data), + count - nr_frags, 0); + netif->rx.req_cons += nr_frags + extra; +} + +static inline void netbk_free_pages(int nr_frags, struct netbk_rx_meta *meta) +{ + int i; + + for (i = 0; i < nr_frags; i++) + put_page(meta[i].frag.page); +} + +static int netbk_check_gop(int nr_frags, domid_t domid, int count) +{ + multicall_entry_t *mcl = rx_mcl + count; + gnttab_transfer_t *gop = grant_rx_op + count; + int status = NETIF_RSP_OKAY; + int i; + + for (i = 0; i <= nr_frags; i++) { if (!xen_feature(XENFEAT_auto_translated_physmap)) { /* The update_va_mapping() must not fail. */ BUG_ON(mcl->result != 0); @@ -325,10 +400,9 @@ static void net_rx_action(unsigned long } /* Check the reassignment error code. */ - status = NETIF_RSP_OKAY; if (gop->status != 0) { DPRINTK("Bad status %d from grant transfer to DOM%u\n", - gop->status, netif->domid); + gop->status, domid); /* * Page no longer belongs to us unless GNTST_bad_page, * but that should be a fatal error anyway. @@ -336,24 +410,166 @@ static void net_rx_action(unsigned long BUG_ON(gop->status == GNTST_bad_page); status = NETIF_RSP_ERROR; } - irq = netif->irq; - id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id; - flags = 0; + gop++; + } + + return status; +} + +static void netbk_add_frag_responses(netif_t *netif, int status, + struct netbk_rx_meta *meta, int nr_frags) +{ + int i; + + for (i = 0; i < nr_frags; i++) { + int id = meta[i].id; + int flags = (i == nr_frags - 1) ? 0 : NETRXF_more_data; + + make_rx_response(netif, id, status, meta[i].frag.page_offset, + meta[i].frag.size, flags); + } +} + +static void net_rx_action(unsigned long unused) +{ + netif_t *netif = NULL; + s8 status; + u16 id, irq, flags; + netif_rx_response_t *resp; + struct netif_extra_info *extra; + multicall_entry_t *mcl; + struct sk_buff_head rxq; + struct sk_buff *skb; + int notify_nr = 0; + int ret; + int nr_frags; + int count; + + /* + * Putting hundreds of bytes on the stack is considered rude. + * Static works because a tasklet can only be on one CPU at any time. + */ + static u16 notify_list[NET_RX_RING_SIZE]; + static struct netbk_rx_meta meta[NET_RX_RING_SIZE]; + + skb_queue_head_init(&rxq); + + count = 0; + + while ((skb = skb_dequeue(&rx_queue)) != NULL) { + nr_frags = skb_shinfo(skb)->nr_frags; + *(int *)skb->cb = nr_frags; + + if (!xen_feature(XENFEAT_auto_translated_physmap) && + check_mfn(nr_frags + 1)) { + /* Memory squeeze? Back off for an arbitrary while. */ + if ( net_ratelimit() ) + WPRINTK("Memory squeeze in netback " + "driver.\n"); + mod_timer(&net_timer, jiffies + HZ); + skb_queue_head(&rx_queue, skb); + break; + } + + netbk_gop_skb(skb, meta, count); + + count += nr_frags + 1; + + __skb_queue_tail(&rxq, skb); + + /* Filled the batch queue? */ + if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE) + break; + } + + if (!count) + return; + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + mcl = rx_mcl + count; + + mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; + + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)rx_mmu; + mcl->args[1] = count; + mcl->args[2] = 0; + mcl->args[3] = DOMID_SELF; + + ret = HYPERVISOR_multicall(rx_mcl, count + 1); + BUG_ON(ret != 0); + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, count); + BUG_ON(ret != 0); + + count = 0; + while ((skb = __skb_dequeue(&rxq)) != NULL) { + nr_frags = *(int *)skb->cb; + + atomic_set(&(skb_shinfo(skb)->dataref), 1); + skb_shinfo(skb)->nr_frags = 0; + skb_shinfo(skb)->frag_list = NULL; + + netif = netdev_priv(skb->dev); + netif->stats.tx_bytes += skb->len; + netif->stats.tx_packets++; + + netbk_free_pages(nr_frags, meta + count + 1); + status = netbk_check_gop(nr_frags, netif->domid, count); + + id = meta[count].id; + flags = nr_frags ? NETRXF_more_data : 0; + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ flags |= NETRXF_csum_blank | NETRXF_data_validated; else if (skb->proto_data_valid) /* remote but checksummed? */ flags |= NETRXF_data_validated; - if (make_rx_response(netif, id, status, - (unsigned long)skb->data & ~PAGE_MASK, - size, flags) && - (rx_notify[irq] == 0)) { + + resp = make_rx_response(netif, id, status, + offset_in_page(skb->data), + skb_headlen(skb), flags); + + extra = NULL; + + if (meta[count].frag.size) { + struct netif_extra_info *gso = + (struct netif_extra_info *) + RING_GET_RESPONSE(&netif->rx, + netif->rx.rsp_prod_pvt++); + + if (extra) + extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE; + else + resp->flags |= NETRXF_extra_info; + + gso->u.gso.size = meta[count].frag.size; + gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; + gso->u.gso.pad = 0; + gso->u.gso.features = 0; + + gso->type = XEN_NETIF_EXTRA_TYPE_GSO; + gso->flags = 0; + extra = gso; + } + + netbk_add_frag_responses(netif, status, meta + count + 1, + nr_frags); + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret); + irq = netif->irq; + if (ret && !rx_notify[irq]) { rx_notify[irq] = 1; notify_list[notify_nr++] = irq; } + if (netif_queue_stopped(netif->dev) && + !netbk_queue_full(netif)) + netif_wake_queue(netif->dev); + netif_put(netif); dev_kfree_skb(skb); - gop++; + count += nr_frags + 1; } while (notify_nr != 0) { @@ -974,8 +1190,13 @@ irqreturn_t netif_be_int(int irq, void * irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) { netif_t *netif = dev_id; + add_to_net_schedule_list_tail(netif); maybe_schedule_tx_action(); + + if (netif_queue_stopped(netif->dev) && !netbk_queue_full(netif)) + netif_wake_queue(netif->dev); + return IRQ_HANDLED; } @@ -1009,16 +1230,15 @@ static void make_tx_response(netif_t *ne #endif } -static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - u16 offset, - u16 size, - u16 flags) +static netif_rx_response_t *make_rx_response(netif_t *netif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags) { RING_IDX i = netif->rx.rsp_prod_pvt; netif_rx_response_t *resp; - int notify; resp = RING_GET_RESPONSE(&netif->rx, i); resp->offset = offset; @@ -1029,9 +1249,8 @@ static int make_rx_response(netif_t *net resp->status = (s16)st; netif->rx.rsp_prod_pvt = ++i; - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, notify); - - return notify; + + return resp; } #ifdef NETBE_DEBUG_INTERRUPT diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Aug 02 13:39:47 2006 -0600 @@ -101,14 +101,12 @@ static int netback_probe(struct xenbus_d goto abort_transaction; } -#if 0 /* KAF: After the protocol is finalised. */ err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); if (err) { message = "writing feature-gso-tcpv4"; goto abort_transaction; } -#endif err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); @@ -353,6 +351,7 @@ static int connect_rings(struct backend_ unsigned long tx_ring_ref, rx_ring_ref; unsigned int evtchn; int err; + int val; DPRINTK(""); @@ -365,6 +364,30 @@ static int connect_rings(struct backend_ "reading %s/ring-ref and event-channel", dev->otherend); return err; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d", + &val) < 0) + val = 0; + if (val) + be->netif->can_queue = 1; + else + /* Must be non-zero for pfifo_fast to work. */ + be->netif->dev->tx_queue_len = 1; + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0) + val = 0; + if (val) { + be->netif->features |= NETIF_F_SG; + be->netif->dev->features |= NETIF_F_SG; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", "%d", + &val) < 0) + val = 0; + if (val) { + be->netif->features |= NETIF_F_TSO; + be->netif->dev->features |= NETIF_F_TSO; } /* Map the shared frame, irq etc. */ diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 02 13:39:47 2006 -0600 @@ -46,11 +46,11 @@ #include <linux/ethtool.h> #include <linux/in.h> #include <linux/if_ether.h> +#include <linux/io.h> #include <net/sock.h> #include <net/pkt_sched.h> #include <net/arp.h> #include <net/route.h> -#include <asm/io.h> #include <asm/uaccess.h> #include <xen/evtchn.h> #include <xen/xenbus.h> @@ -62,17 +62,12 @@ #include <xen/interface/grant_table.h> #include <xen/gnttab.h> +#define RX_COPY_THRESHOLD 256 + #define GRANT_INVALID_REF 0 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE) #define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE) - -static inline void init_skb_shinfo(struct sk_buff *skb) -{ - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; -} struct netfront_info { struct list_head list; @@ -119,6 +114,11 @@ struct netfront_info { unsigned long rx_pfn_array[NET_RX_RING_SIZE]; struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; struct mmu_update rx_mmu[NET_RX_RING_SIZE]; +}; + +struct netfront_rx_info { + struct netif_rx_response rx; + struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; }; /* @@ -329,6 +329,18 @@ again: err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1); if (err) { message = "writing feature-rx-notify"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); + if (err) { + message = "writing feature-sg"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); + if (err) { + message = "writing feature-gso-tcpv4"; goto abort_transaction; } @@ -575,10 +587,13 @@ static void network_alloc_rx_buffers(str unsigned short id; struct netfront_info *np = netdev_priv(dev); struct sk_buff *skb; + struct page *page; int i, batch_target, notify; RING_IDX req_prod = np->rx.req_prod_pvt; struct xen_memory_reservation reservation; grant_ref_t ref; + unsigned long pfn; + void *vaddr; if (unlikely(!netif_carrier_ok(dev))) return; @@ -591,15 +606,16 @@ static void network_alloc_rx_buffers(str */ batch_target = np->rx_target - (req_prod - np->rx.rsp_cons); for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { - /* - * Subtract dev_alloc_skb headroom (16 bytes) and shared info - * tailroom then round down to SKB_DATA_ALIGN boundary. - */ - skb = __dev_alloc_skb( - ((PAGE_SIZE - sizeof(struct skb_shared_info)) & - (-SKB_DATA_ALIGN(1))) - 16, - GFP_ATOMIC|__GFP_NOWARN); - if (skb == NULL) { + /* Allocate an skb and a page. */ + skb = __dev_alloc_skb(RX_COPY_THRESHOLD, + GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(!skb)) + goto no_skb; + + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + if (!page) { + kfree_skb(skb); +no_skb: /* Any skbuffs queued for refill? Force them out. */ if (i != 0) goto refill; @@ -608,6 +624,9 @@ static void network_alloc_rx_buffers(str jiffies + (HZ/10)); break; } + + skb_shinfo(skb)->frags[0].page = page; + skb_shinfo(skb)->nr_frags = 1; __skb_queue_tail(&np->rx_batch, skb); } @@ -639,18 +658,20 @@ static void network_alloc_rx_buffers(str ref = gnttab_claim_grant_reference(&np->gref_rx_head); BUG_ON((signed short)ref < 0); np->grant_rx_ref[id] = ref; + + pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page); + vaddr = page_address(skb_shinfo(skb)->frags[0].page); + gnttab_grant_foreign_transfer_ref(ref, - np->xbdev->otherend_id, - __pa(skb->head)>>PAGE_SHIFT); + np->xbdev->otherend_id, pfn); RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref; - np->rx_pfn_array[i] = virt_to_mfn(skb->head); + np->rx_pfn_array[i] = pfn_to_mfn(pfn); if (!xen_feature(XENFEAT_auto_translated_physmap)) { /* Remove this page before passing back to Xen. */ - set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, - INVALID_P2M_ENTRY); + set_phys_to_machine(pfn, INVALID_P2M_ENTRY); MULTI_update_va_mapping(np->rx_mcl+i, - (unsigned long)skb->head, + (unsigned long)vaddr, __pte(0), 0); } } @@ -889,41 +910,76 @@ static void xennet_move_rx_slot(struct n np->rx.req_prod_pvt++; } -static int netif_poll(struct net_device *dev, int *pbudget) -{ - struct netfront_info *np = netdev_priv(dev); - struct sk_buff *skb, *nskb; - struct netif_rx_response *rx; - RING_IDX i, rp; - struct mmu_update *mmu = np->rx_mmu; - struct multicall_entry *mcl = np->rx_mcl; - int work_done, budget, more_to_do = 1; - struct sk_buff_head rxq; - unsigned long flags; - unsigned long mfn; - grant_ref_t ref; - - spin_lock(&np->rx_lock); - - if (unlikely(!netif_carrier_ok(dev))) { - spin_unlock(&np->rx_lock); - return 0; - } - - skb_queue_head_init(&rxq); - - if ((budget = *pbudget) > dev->quota) - budget = dev->quota; - rp = np->rx.sring->rsp_prod; - rmb(); /* Ensure we see queued responses up to 'rp'. */ - - for (i = np->rx.rsp_cons, work_done = 0; - (i != rp) && (work_done < budget); - i++, work_done++) { - rx = RING_GET_RESPONSE(&np->rx, i); - - skb = xennet_get_rx_skb(np, i); - ref = xennet_get_rx_ref(np, i); +int xennet_get_extras(struct netfront_info *np, + struct netif_extra_info *extras, RING_IDX rp) + +{ + struct netif_extra_info *extra; + RING_IDX cons = np->rx.rsp_cons; + int err = 0; + + do { + struct sk_buff *skb; + grant_ref_t ref; + + if (unlikely(cons + 1 == rp)) { + if (net_ratelimit()) + WPRINTK("Missing extra info\n"); + err = -EBADR; + break; + } + + extra = (struct netif_extra_info *) + RING_GET_RESPONSE(&np->rx, ++cons); + + if (unlikely(!extra->type || + extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + if (net_ratelimit()) + WPRINTK("Invalid extra type: %d\n", + extra->type); + err = -EINVAL; + } else + memcpy(&extras[extra->type - 1], extra, sizeof(*extra)); + + skb = xennet_get_rx_skb(np, cons); + ref = xennet_get_rx_ref(np, cons); + xennet_move_rx_slot(np, skb, ref); + } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); + + np->rx.rsp_cons = cons; + return err; +} + +static int xennet_get_responses(struct netfront_info *np, + struct netfront_rx_info *rinfo, RING_IDX rp, + struct sk_buff_head *list, int count) +{ + struct mmu_update *mmu = np->rx_mmu + count; + struct multicall_entry *mcl = np->rx_mcl + count; + struct netif_rx_response *rx = &rinfo->rx; + struct netif_extra_info *extras = rinfo->extras; + RING_IDX cons = np->rx.rsp_cons; + struct sk_buff *skb = xennet_get_rx_skb(np, cons); + grant_ref_t ref = xennet_get_rx_ref(np, cons); + int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD); + int frags = 1; + int err = 0; + + if (rx->flags & NETRXF_extra_info) { + err = xennet_get_extras(np, extras, rp); + cons = np->rx.rsp_cons; + } + + for (;;) { + unsigned long mfn; + + if (unlikely(rx->status < 0 || + rx->offset + rx->status > PAGE_SIZE)) { + if (net_ratelimit()) + WPRINTK("rx->offset: %x, size: %u\n", + rx->offset, rx->status); + err = -EINVAL; + } /* * This definitely indicates a bug, either in this driver or in @@ -932,8 +988,8 @@ static int netif_poll(struct net_device */ if (ref == GRANT_INVALID_REF) { WPRINTK("Bad rx response id %d.\n", rx->id); - work_done--; - continue; + err = -EINVAL; + goto next; } /* Memory pressure, insufficient buffer headroom, ... */ @@ -942,16 +998,200 @@ static int netif_poll(struct net_device WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n", rx->id, rx->status); xennet_move_rx_slot(np, skb, ref); + err = -ENOMEM; + goto next; + } + + gnttab_release_grant_reference(&np->gref_rx_head, ref); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* Remap the page. */ + struct page *page = skb_shinfo(skb)->frags[0].page; + unsigned long pfn = page_to_pfn(page); + void *vaddr = page_address(page); + + MULTI_update_va_mapping(mcl, (unsigned long)vaddr, + pfn_pte_ma(mfn, PAGE_KERNEL), + 0); + mcl++; + mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) + | MMU_MACHPHYS_UPDATE; + mmu->val = pfn; + mmu++; + + set_phys_to_machine(pfn, mfn); + } + + __skb_queue_tail(list, skb); + +next: + if (!(rx->flags & NETRXF_more_data)) + break; + + if (cons + frags == rp) { + if (net_ratelimit()) + WPRINTK("Need more frags\n"); + err = -ENOENT; + break; + } + + rx = RING_GET_RESPONSE(&np->rx, cons + frags); + skb = xennet_get_rx_skb(np, cons + frags); + ref = xennet_get_rx_ref(np, cons + frags); + frags++; + } + + if (unlikely(frags > max)) { + if (net_ratelimit()) + WPRINTK("Too many frags\n"); + err = -E2BIG; + } + + return err; +} + +static RING_IDX xennet_fill_frags(struct netfront_info *np, + struct sk_buff *skb, + struct sk_buff_head *list) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + RING_IDX cons = np->rx.rsp_cons; + skb_frag_t *frag = shinfo->frags + nr_frags; + struct sk_buff *nskb; + + while ((nskb = __skb_dequeue(list))) { + struct netif_rx_response *rx = + RING_GET_RESPONSE(&np->rx, ++cons); + + frag->page = skb_shinfo(nskb)->frags[0].page; + frag->page_offset = rx->offset; + frag->size = rx->status; + + skb->data_len += rx->status; + + skb_shinfo(nskb)->nr_frags = 0; + kfree_skb(nskb); + + frag++; + nr_frags++; + } + + shinfo->nr_frags = nr_frags; + return cons; +} + +static int xennet_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso) +{ + if (!gso->u.gso.size) { + if (net_ratelimit()) + WPRINTK("GSO size must not be zero.\n"); + return -EINVAL; + } + + /* Currently only TCPv4 S.O. is supported. */ + if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { + if (net_ratelimit()) + WPRINTK("Bad GSO type %d.\n", gso->u.gso.type); + return -EINVAL; + } + + skb_shinfo(skb)->gso_size = gso->u.gso.size; + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + + return 0; +} + +static int netif_poll(struct net_device *dev, int *pbudget) +{ + struct netfront_info *np = netdev_priv(dev); + struct sk_buff *skb; + struct netfront_rx_info rinfo; + struct netif_rx_response *rx = &rinfo.rx; + struct netif_extra_info *extras = rinfo.extras; + RING_IDX i, rp; + struct multicall_entry *mcl; + int work_done, budget, more_to_do = 1; + struct sk_buff_head rxq; + struct sk_buff_head errq; + struct sk_buff_head tmpq; + unsigned long flags; + unsigned int len; + int pages_done; + int err; + + spin_lock(&np->rx_lock); + + if (unlikely(!netif_carrier_ok(dev))) { + spin_unlock(&np->rx_lock); + return 0; + } + + skb_queue_head_init(&rxq); + skb_queue_head_init(&errq); + skb_queue_head_init(&tmpq); + + if ((budget = *pbudget) > dev->quota) + budget = dev->quota; + rp = np->rx.sring->rsp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for (i = np->rx.rsp_cons, work_done = 0, pages_done = 0; + (i != rp) && (work_done < budget); + np->rx.rsp_cons = ++i, work_done++) { + memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx)); + memset(extras, 0, sizeof(extras)); + + err = xennet_get_responses(np, &rinfo, rp, &tmpq, pages_done); + pages_done += skb_queue_len(&tmpq); + + if (unlikely(err)) { +err: + i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1; work_done--; + while ((skb = __skb_dequeue(&tmpq))) + __skb_queue_tail(&errq, skb); + np->stats.rx_errors++; continue; } - gnttab_release_grant_reference(&np->gref_rx_head, ref); - - /* NB. We handle skb overflow later. */ - skb->data = skb->head + rx->offset; - skb->len = rx->status; - skb->tail = skb->data + skb->len; + skb = __skb_dequeue(&tmpq); + + if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { + struct netif_extra_info *gso; + gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; + + if (unlikely(xennet_set_skb_gso(skb, gso))) { + __skb_queue_head(&tmpq, skb); + goto err; + } + } + + skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page; + skb->h.raw = skb->nh.raw + rx->offset; + + len = rx->status; + if (len > RX_COPY_THRESHOLD) + len = RX_COPY_THRESHOLD; + skb_put(skb, len); + + if (rx->status > len) { + skb_shinfo(skb)->frags[0].page_offset = + rx->offset + len; + skb_shinfo(skb)->frags[0].size = rx->status - len; + skb->data_len = rx->status - len; + } else { + skb_shinfo(skb)->frags[0].page = NULL; + skb_shinfo(skb)->nr_frags = 0; + } + + i = xennet_fill_frags(np, skb, &tmpq); + skb->truesize += skb->data_len; + skb->len += skb->data_len; /* * Old backends do not assert data_validated but we @@ -967,96 +1207,38 @@ static int netif_poll(struct net_device skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank); np->stats.rx_packets++; - np->stats.rx_bytes += rx->status; - - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - /* Remap the page. */ - MULTI_update_va_mapping(mcl, (unsigned long)skb->head, - pfn_pte_ma(mfn, PAGE_KERNEL), - 0); - mcl++; - mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) - | MMU_MACHPHYS_UPDATE; - mmu->val = __pa(skb->head) >> PAGE_SHIFT; - mmu++; - - set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, - mfn); - } + np->stats.rx_bytes += skb->len; __skb_queue_tail(&rxq, skb); } /* Some pages are no longer absent... */ - balloon_update_driver_allowance(-work_done); + balloon_update_driver_allowance(-pages_done); /* Do all the remapping work, and M2P updates, in one big hypercall. */ - if (likely((mcl - np->rx_mcl) != 0)) { + if (likely(pages_done)) { + mcl = np->rx_mcl + pages_done; mcl->op = __HYPERVISOR_mmu_update; mcl->args[0] = (unsigned long)np->rx_mmu; - mcl->args[1] = mmu - np->rx_mmu; + mcl->args[1] = pages_done; mcl->args[2] = 0; mcl->args[3] = DOMID_SELF; - mcl++; - (void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl); - } + (void)HYPERVISOR_multicall(np->rx_mcl, pages_done + 1); + } + + while ((skb = __skb_dequeue(&errq))) + kfree_skb(skb); while ((skb = __skb_dequeue(&rxq)) != NULL) { - if (skb->len > (dev->mtu + ETH_HLEN + 4)) { - if (net_ratelimit()) - printk(KERN_INFO "Received packet too big for " - "MTU (%d > %d)\n", - skb->len - ETH_HLEN - 4, dev->mtu); - skb->len = 0; - skb->tail = skb->data; - init_skb_shinfo(skb); - dev_kfree_skb(skb); - continue; - } - - /* - * Enough room in skbuff for the data we were passed? Also, - * Linux expects at least 16 bytes headroom in each rx buffer. - */ - if (unlikely(skb->tail > skb->end) || - unlikely((skb->data - skb->head) < 16)) { - if (net_ratelimit()) { - if (skb->tail > skb->end) - printk(KERN_INFO "Received packet " - "is %zd bytes beyond tail.\n", - skb->tail - skb->end); - else - printk(KERN_INFO "Received packet " - "is %zd bytes before head.\n", - 16 - (skb->data - skb->head)); - } - - nskb = __dev_alloc_skb(skb->len + 2, - GFP_ATOMIC|__GFP_NOWARN); - if (nskb != NULL) { - skb_reserve(nskb, 2); - skb_put(nskb, skb->len); - memcpy(nskb->data, skb->data, skb->len); - /* Copy any other fields we already set up. */ - nskb->dev = skb->dev; - nskb->ip_summed = skb->ip_summed; - nskb->proto_data_valid = skb->proto_data_valid; - nskb->proto_csum_blank = skb->proto_csum_blank; - } - - /* Reinitialise and then destroy the old skbuff. */ - skb->len = 0; - skb->tail = skb->data; - init_skb_shinfo(skb); - dev_kfree_skb(skb); - - /* Switch old for new, if we copied the buffer. */ - if ((skb = nskb) == NULL) - continue; - } - - /* Set the shinfo area, which is hidden behind the data. */ - init_skb_shinfo(skb); + struct page *page = (struct page *)skb->nh.raw; + void *vaddr = page_address(page); + + memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw), + skb_headlen(skb)); + + if (page != skb_shinfo(skb)->frags[0].page) + __free_page(page); + /* Ethernet work: Delayed to here as it peeks the header. */ skb->protocol = eth_type_trans(skb, dev); @@ -1064,8 +1246,6 @@ static int netif_poll(struct net_device netif_receive_skb(skb); dev->last_rx = jiffies; } - - np->rx.rsp_cons = i; /* If we get a callback with very few responses, reduce fill target. */ /* NB. Note exponential increase, linear decrease. */ @@ -1145,9 +1325,7 @@ static int xennet_set_tso(struct net_dev if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-gso-tcpv4", "%d", &val) < 0) val = 0; -#if 0 /* KAF: After the protocol is finalised. */ if (!val) -#endif return -ENOSYS; } @@ -1210,7 +1388,7 @@ static void network_connect(struct net_d gnttab_grant_foreign_transfer_ref( ref, np->xbdev->otherend_id, - __pa(skb->data) >> PAGE_SHIFT); + page_to_pfn(skb_shinfo(skb)->frags->page)); RING_GET_REQUEST(&np->rx, requeue_idx)->gref = ref; RING_GET_REQUEST(&np->rx, requeue_idx)->id = requeue_idx; diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Wed Aug 02 13:39:47 2006 -0600 @@ -232,6 +232,10 @@ static int __devinit pcistub_match_one(s && dev->bus->number == pdev_id->bus && dev->devfn == pdev_id->devfn) return 1; + + /* Sometimes topmost bridge links to itself. */ + if (dev == dev->bus->self) + break; } return 0; diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Wed Aug 02 13:39:47 2006 -0600 @@ -445,6 +445,9 @@ static struct xenbus_driver xenbus_pciba int __init pciback_xenbus_register(void) { + if (!is_running_on_xen()) + return -ENODEV; + return xenbus_register_backend(&xenbus_pciback_driver); } diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Wed Aug 02 13:39:47 2006 -0600 @@ -284,11 +284,10 @@ static struct xenbus_driver xenbus_pcifr static int __init pcifront_init(void) { - int err = 0; - - err = xenbus_register_frontend(&xenbus_pcifront_driver); - - return err; + if (!is_running_on_xen()) + return -ENODEV; + + return xenbus_register_frontend(&xenbus_pcifront_driver); } /* Initialize after the Xen PCI Frontend Stub is initialized */ diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Aug 02 13:39:47 2006 -0600 @@ -58,6 +58,9 @@ struct xenbus_dev_data { /* In-progress transaction. */ struct list_head transactions; + /* Active watches. */ + struct list_head watches; + /* Partial request. */ unsigned int len; union { @@ -70,6 +73,8 @@ struct xenbus_dev_data { char read_buffer[PAGE_SIZE]; unsigned int read_cons, read_prod; wait_queue_head_t read_waitq; + + struct mutex reply_mutex; }; static struct proc_dir_entry *xenbus_dev_intf; @@ -100,13 +105,59 @@ static void queue_reply(struct xenbus_de { int i; + mutex_lock(&u->reply_mutex); + for (i = 0; i < len; i++, u->read_prod++) u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i]; BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer)); + mutex_unlock(&u->reply_mutex); + wake_up(&u->read_waitq); } + +struct watch_adapter +{ + struct list_head list; + struct xenbus_watch watch; + struct xenbus_dev_data *dev_data; + char *token; +}; + +static void free_watch_adapter (struct watch_adapter *watch) +{ + kfree(watch->watch.node); + kfree(watch->token); + kfree(watch); +} + +static void watch_fired(struct xenbus_watch *watch, + const char **vec, + unsigned int len) +{ + struct watch_adapter *adap = + container_of(watch, struct watch_adapter, watch); + struct xsd_sockmsg hdr; + const char *path, *token; + int path_len, tok_len, body_len; + + path = vec[XS_WATCH_PATH]; + token = adap->token; + + path_len = strlen(path) + 1; + tok_len = strlen(token) + 1; + body_len = path_len + tok_len; + + hdr.type = XS_WATCH_EVENT; + hdr.len = body_len; + + queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr)); + queue_reply(adap->dev_data, (char *)path, path_len); + queue_reply(adap->dev_data, (char *)token, tok_len); +} + +static LIST_HEAD(watch_list); static ssize_t xenbus_dev_write(struct file *filp, const char __user *ubuf, @@ -116,6 +167,9 @@ static ssize_t xenbus_dev_write(struct f struct xenbus_dev_transaction *trans = NULL; uint32_t msg_type; void *reply; + char *path, *token; + struct watch_adapter *watch, *tmp_watch; + int err; if ((len + u->len) > sizeof(u->u.buffer)) return -EINVAL; @@ -169,6 +223,56 @@ static ssize_t xenbus_dev_write(struct f kfree(reply); break; + case XS_WATCH: + case XS_UNWATCH: + path = u->u.buffer + sizeof(u->u.msg); + token = memchr(path, 0, u->u.msg.len); + if (token == NULL) + return -EILSEQ; + token++; + + if (msg_type == XS_WATCH) { + static const char * XS_WATCH_RESP = "OK"; + struct xsd_sockmsg hdr; + + watch = kmalloc(sizeof(*watch), GFP_KERNEL); + watch->watch.node = kmalloc(strlen(path)+1, + GFP_KERNEL); + strcpy((char *)watch->watch.node, path); + watch->watch.callback = watch_fired; + watch->token = kmalloc(strlen(token)+1, GFP_KERNEL); + strcpy(watch->token, token); + watch->dev_data = u; + + err = register_xenbus_watch(&watch->watch); + if (err) { + free_watch_adapter(watch); + return err; + } + + list_add(&watch->list, &u->watches); + + hdr.type = XS_WATCH; + hdr.len = strlen(XS_WATCH_RESP) + 1; + queue_reply(u, (char *)&hdr, sizeof(hdr)); + queue_reply(u, (char *)XS_WATCH_RESP, hdr.len); + } else { + list_for_each_entry_safe(watch, tmp_watch, + &u->watches, list) { + if (!strcmp(watch->token, token) && + !strcmp(watch->watch.node, path)) + break; + { + unregister_xenbus_watch(&watch->watch); + list_del(&watch->list); + free_watch_adapter(watch); + break; + } + } + } + + break; + default: return -EINVAL; } @@ -191,7 +295,10 @@ static int xenbus_dev_open(struct inode return -ENOMEM; INIT_LIST_HEAD(&u->transactions); + INIT_LIST_HEAD(&u->watches); init_waitqueue_head(&u->read_waitq); + + mutex_init(&u->reply_mutex); filp->private_data = u; @@ -202,11 +309,18 @@ static int xenbus_dev_release(struct ino { struct xenbus_dev_data *u = filp->private_data; struct xenbus_dev_transaction *trans, *tmp; + struct watch_adapter *watch, *tmp_watch; list_for_each_entry_safe(trans, tmp, &u->transactions, list) { xenbus_transaction_end(trans->handle, 1); list_del(&trans->list); kfree(trans); + } + + list_for_each_entry_safe(watch, tmp_watch, &u->watches, list) { + unregister_xenbus_watch(&watch->watch); + list_del(&watch->list); + free_watch_adapter(watch); } kfree(u); diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Aug 02 13:39:47 2006 -0600 @@ -141,7 +141,9 @@ static int read_otherend_details(struct } if (strlen(xendev->otherend) == 0 || !xenbus_exists(XBT_NIL, xendev->otherend, "")) { - xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s", + xenbus_dev_fatal(xendev, -ENOENT, + "unable to read other end from %s. " + "missing or inaccessible.", xendev->nodename); free_otherend_details(xendev); return -ENOENT; diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h Wed Aug 02 13:39:47 2006 -0600 @@ -12,6 +12,9 @@ typedef struct { int size; struct semaphore sem; void *ldt; +#ifdef CONFIG_XEN + int has_foreign_mappings; +#endif } mm_context_t; /* mm/memory.c:exit_mmap hook */ diff -r 4acc6d51f389 -r b76e86966e7e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h Tue Aug 01 14:58:20 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h Wed Aug 02 13:39:47 2006 -0600 @@ -17,6 +17,7 @@ typedef struct { struct semaphore sem; #ifdef CONFIG_XEN unsigned pinned:1; + unsigned has_foreign_mappings:1; struct list_head unpinned; #endif } mm_context_t; diff -r 4acc6d51f389 -r b76e86966e7e tools/blktap/drivers/blktapctrl.c --- a/tools/blktap/drivers/blktapctrl.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/blktap/drivers/blktapctrl.c Wed Aug 02 13:39:47 2006 -0600 @@ -61,6 +61,7 @@ #define MSG_SIZE 4096 #define MAX_TIMEOUT 10 #define MAX_RAND_VAL 0xFFFF +#define MAX_ATTEMPTS 10 int run = 1; int max_timeout = MAX_TIMEOUT; @@ -626,13 +627,14 @@ int main(int argc, char *argv[]) { char *devname; tapdev_info_t *ctlinfo; - int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count; + int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0; struct xs_handle *h; struct pollfd pfd[NUM_POLL_FDS]; pid_t process; __init_blkif(); openlog("BLKTAPCTRL", LOG_CONS|LOG_ODELAY, LOG_DAEMON); + daemon(0,0); print_drivers(); init_driver_list(); @@ -651,18 +653,28 @@ int main(int argc, char *argv[]) goto open_failed; } + retry: /* Set up store connection and watch. */ h = xs_daemon_open(); if (h == NULL) { DPRINTF("xs_daemon_open failed -- " "is xenstore running?\n"); - goto open_failed; + if (count < MAX_ATTEMPTS) { + count++; + sleep(2); + goto retry; + } else goto open_failed; } ret = add_blockdevice_probe_watch(h, "Domain-0"); if (ret != 0) { - DPRINTF("adding device probewatch\n"); - goto open_failed; + DPRINTF("Failed adding device probewatch\n"); + if (count < MAX_ATTEMPTS) { + count++; + sleep(2); + xs_daemon_close(h); + goto retry; + } else goto open_failed; } ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); @@ -691,6 +703,7 @@ int main(int argc, char *argv[]) } } + xs_daemon_close(h); ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH ); close(ctlfd); closelog(); diff -r 4acc6d51f389 -r b76e86966e7e tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Aug 02 13:39:47 2006 -0600 @@ -31,7 +31,7 @@ #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 /* invoke SVM's paged realmode support */ -#define SVM_VMMCALL_RESET_TO_REALMODE 0x00000001 +#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001 /* * C runtime start off @@ -133,15 +133,15 @@ cirrus_check(void) return inb(0x3C5) == 0x12; } -int -vmmcall(int edi, int esi, int edx, int ecx, int ebx) +int +vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx) { int eax; __asm__ __volatile__( ".byte 0x0F,0x01,0xD9" : "=a" (eax) - : "a"(0x58454E00), /* XEN\0 key */ + : "a"(function), "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) ); return eax; @@ -200,7 +200,7 @@ main(void) if (check_amd()) { /* AMD implies this is SVM */ puts("SVM go ...\n"); - vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0); + vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0); } else { puts("Loading VMXAssist ...\n"); memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS, diff -r 4acc6d51f389 -r b76e86966e7e tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/firmware/vmxassist/vm86.c Wed Aug 02 13:39:47 2006 -0600 @@ -52,6 +52,31 @@ static char *rnames[] = { "ax", "cx", "d static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; #endif /* DEBUG */ +#define PT_ENTRY_PRESENT 0x1 + +static unsigned +guest_linear_to_real(unsigned long base, unsigned off) +{ + unsigned int gcr3 = oldctx.cr3; + unsigned int l1_mfn; + unsigned int l0_mfn; + + if (!(oldctx.cr0 & CR0_PG)) + return base + off; + + l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + l1_mfn = l1_mfn & 0xfffff000 ; + + l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn = l0_mfn & 0xfffff000; + + return l0_mfn + off + (base & 0xfff); +} + static unsigned address(struct regs *regs, unsigned seg, unsigned off) { @@ -70,7 +95,7 @@ address(struct regs *regs, unsigned seg, (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg)) return ((seg & 0xFFFF) << 4) + off; - entry = ((unsigned long long *) oldctx.gdtr_base)[seg >> 3]; + entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[seg >> 3]; entry_high = entry >> 32; entry_low = entry & 0xFFFFFFFF; @@ -94,7 +119,7 @@ trace(struct regs *regs, int adjust, cha trace(struct regs *regs, int adjust, char *fmt, ...) { unsigned off = regs->eip - adjust; - va_list ap; + va_list ap; if ((traceset & (1 << mode)) && (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) { @@ -755,7 +780,7 @@ load_seg(unsigned long sel, uint32_t *ba return 1; } - entry = ((unsigned long long *) oldctx.gdtr_base)[sel >> 3]; + entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[sel >> 3]; /* Check the P bit first */ if (!((entry >> (15+32)) & 0x1) && sel != 0) diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/patches/ioemu-ia64 --- a/tools/ioemu/patches/ioemu-ia64 Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/ioemu/patches/ioemu-ia64 Wed Aug 02 13:39:47 2006 -0600 @@ -1,7 +1,7 @@ Index: ioemu/hw/iommu.c Index: ioemu/hw/iommu.c =================================================================== ---- ioemu.orig/hw/iommu.c 2006-07-28 09:56:58.571272016 +0100 -+++ ioemu/hw/iommu.c 2006-07-28 10:02:10.171049510 +0100 +--- ioemu.orig/hw/iommu.c 2006-08-02 09:46:38.774790244 +0100 ++++ ioemu/hw/iommu.c 2006-08-02 09:46:39.030761544 +0100 @@ -82,7 +82,11 @@ #define IOPTE_VALID 0x00000002 /* IOPTE is valid */ #define IOPTE_WAZ 0x00000001 /* Write as zeros */ @@ -16,8 +16,8 @@ Index: ioemu/hw/iommu.c Index: ioemu/cpu-all.h =================================================================== ---- ioemu.orig/cpu-all.h 2006-07-28 09:58:38.815935452 +0100 -+++ ioemu/cpu-all.h 2006-07-28 10:02:10.171049510 +0100 +--- ioemu.orig/cpu-all.h 2006-08-02 09:46:38.969768383 +0100 ++++ ioemu/cpu-all.h 2006-08-02 09:46:39.030761544 +0100 @@ -835,6 +835,31 @@ :"=m" (*(volatile long *)addr) :"dIr" (nr)); @@ -52,8 +52,8 @@ Index: ioemu/cpu-all.h /* memory API */ Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-07-28 09:58:59.672577418 +0100 -+++ ioemu/vl.c 2006-07-28 10:02:10.174049171 +0100 +--- ioemu.orig/vl.c 2006-08-02 09:46:39.020762665 +0100 ++++ ioemu/vl.c 2006-08-02 09:47:02.896085814 +0100 @@ -5578,6 +5578,7 @@ exit(-1); } @@ -82,7 +82,7 @@ Index: ioemu/vl.c + } + + if (xc_ia64_get_pfn_list(xc_handle, domid, page_array, -+ nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1)!= 1){ ++ IO_PAGE_START >> PAGE_SHIFT, 1) != 1){ + fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno); + exit(-1); + } @@ -91,7 +91,7 @@ Index: ioemu/vl.c + PROT_READ|PROT_WRITE, + page_array[0]); + -+ fprintf(logfile, "shared page at pfn:%lx, mfn: %l016x\n", ++ fprintf(logfile, "shared page at pfn:%lx, mfn: %016lx\n", + IO_PAGE_START >> PAGE_SHIFT, page_array[0]); +#endif #else /* !CONFIG_DM */ @@ -99,8 +99,8 @@ Index: ioemu/vl.c #ifdef CONFIG_SOFTMMU Index: ioemu/target-i386-dm/exec-dm.c =================================================================== ---- ioemu.orig/target-i386-dm/exec-dm.c 2006-07-28 09:58:22.882736989 +0100 -+++ ioemu/target-i386-dm/exec-dm.c 2006-07-28 10:03:19.972165675 +0100 +--- ioemu.orig/target-i386-dm/exec-dm.c 2006-08-02 09:46:38.903775782 +0100 ++++ ioemu/target-i386-dm/exec-dm.c 2006-08-02 09:46:39.034761096 +0100 @@ -341,6 +341,23 @@ return io_mem_read[io_index >> IO_MEM_SHIFT]; } @@ -137,8 +137,8 @@ Index: ioemu/target-i386-dm/exec-dm.c memset(buf, 0xff, len); Index: ioemu/exec-all.h =================================================================== ---- ioemu.orig/exec-all.h 2006-07-28 09:56:58.572271903 +0100 -+++ ioemu/exec-all.h 2006-07-28 10:02:10.175049059 +0100 +--- ioemu.orig/exec-all.h 2006-08-02 09:46:38.881778248 +0100 ++++ ioemu/exec-all.h 2006-08-02 09:46:39.034761096 +0100 @@ -462,12 +462,13 @@ } #endif @@ -158,8 +158,8 @@ Index: ioemu/exec-all.h Index: ioemu/target-i386-dm/cpu.h =================================================================== ---- ioemu.orig/target-i386-dm/cpu.h 2006-07-28 09:56:58.572271903 +0100 -+++ ioemu/target-i386-dm/cpu.h 2006-07-28 10:02:10.175049059 +0100 +--- ioemu.orig/target-i386-dm/cpu.h 2006-08-02 09:46:38.902775894 +0100 ++++ ioemu/target-i386-dm/cpu.h 2006-08-02 09:46:39.034761096 +0100 @@ -80,7 +80,11 @@ /* helper2.c */ int main_loop(void); @@ -175,7 +175,7 @@ Index: ioemu/ia64_intrinsic.h Index: ioemu/ia64_intrinsic.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/ia64_intrinsic.h 2006-07-28 10:02:10.176048946 +0100 ++++ ioemu/ia64_intrinsic.h 2006-08-02 09:46:39.035760983 +0100 @@ -0,0 +1,276 @@ +#ifndef IA64_INTRINSIC_H +#define IA64_INTRINSIC_H diff -r 4acc6d51f389 -r b76e86966e7e tools/misc/lomount/lomount.c --- a/tools/misc/lomount/lomount.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/misc/lomount/lomount.c Wed Aug 02 13:39:47 2006 -0600 @@ -158,7 +158,7 @@ load_gpt (const char *diskimage, struct entry_size = read_le4 (&data[84]); #ifdef DEBUG - fprintf(stderr, "lba entries: %lu, nbr_part: %u, entry_size: %lu\n", + fprintf(stderr, "lba entries: %llu, nbr_part: %u, entry_size: %lu\n", entries_lba, nbr_part, entry_size); #endif part = malloc (nbr_part * sizeof (struct pentry)); @@ -404,7 +404,7 @@ int main(int argc, char ** argv) value is off by (larger than) a value less than one. */ sec = 512; /* TODO: calculate real sector size */ #ifdef DEBUG - printf("sec: %d\n", sec); + printf("sec: %llu\n", sec); #endif if (partition > nbr_part) { @@ -421,7 +421,7 @@ int main(int argc, char ** argv) pnum = sec * num; #ifdef DEBUG - printf("offset = %d\n", pnum); + printf("offset = %llu\n", pnum); #endif snprintf(buf, sizeof(buf), "mount -oloop,offset=%lld %s %s", pnum, diskimage, argv2); diff -r 4acc6d51f389 -r b76e86966e7e tools/python/xen/util/auxbin.py --- a/tools/python/xen/util/auxbin.py Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/python/xen/util/auxbin.py Wed Aug 02 13:39:47 2006 -0600 @@ -21,8 +21,8 @@ LIB_BIN_SUFFIX = "xen/bin" LIB_BIN_SUFFIX = "xen/bin" ## The architectures on which the LIB_64 directory is used. This -# deliberately excludes ia64. -LIB_64_ARCHS = [ 'x86_64', 'ppc64', 's390x', 'sparc64'] +# deliberately excludes ia64 and ppc64. +LIB_64_ARCHS = [ 'x86_64', 's390x', 'sparc64'] import os diff -r 4acc6d51f389 -r b76e86966e7e tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/python/xen/xm/main.py Wed Aug 02 13:39:47 2006 -0600 @@ -78,7 +78,9 @@ sysrq_help = "sysrq <DomId> <letter> sysrq_help = "sysrq <DomId> <letter> Send a sysrq to a domain" domid_help = "domid <DomName> Converts a domain name to a domain id" domname_help = "domname <DomId> Convert a domain id to a domain name" -vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of VCPUs for a domain""" +vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of active VCPUs for a domain + within the range allowed by the domain + configuration""" vcpu_list_help = "vcpu-list <DomId> List the VCPUs for a domain (or all domains)" vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs> Set which cpus a VCPU can use" dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buffer" diff -r 4acc6d51f389 -r b76e86966e7e tools/security/Makefile --- a/tools/security/Makefile Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/security/Makefile Wed Aug 02 13:39:47 2006 -0600 @@ -32,6 +32,7 @@ OBJS_XML2BIN := $(patsubst %.c,%.o,$(fil OBJS_XML2BIN := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_XML2BIN))) ACM_INST_TOOLS = xensec_tool xensec_xml2bin xensec_gen +ACM_EZPOLICY = xensec_ezpolicy ACM_OBJS = $(OBJS_TOOL) $(OBJS_XML2BIN) $(OBJS_GETD) ACM_SCRIPTS = python/xensec_tools/acm_getlabel @@ -56,6 +57,7 @@ install: all $(ACM_CONFIG_FILE) install: all $(ACM_CONFIG_FILE) $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin $(INSTALL_PROG) -p $(ACM_INST_TOOLS) $(DESTDIR)/usr/sbin + $(INSTALL_PROG) -p $(ACM_EZPOLICY) $(DESTDIR)/usr/sbin $(INSTALL_DIR) -p $(DESTDIR)$(ACM_CONFIG_DIR) $(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR) $(INSTALL_DATA) -p policies/$(ACM_SCHEMA) $(DESTDIR)$(ACM_POLICY_DIR) diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/Makefile --- a/tools/xenstore/Makefile Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/Makefile Wed Aug 02 13:39:47 2006 -0600 @@ -26,7 +26,7 @@ TESTFLAGS= -DTESTING TESTFLAGS= -DTESTING TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR) -CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm +CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod CLIENTS += xenstore-write CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS)) @@ -102,7 +102,7 @@ libxenstore.a: xs.o xs_lib.o .PHONY: clean clean: testsuite-clean - rm -f *.o *.opic *.so* + rm -f *.a *.o *.opic *.so* rm -f xenstored xs_random xs_stress xs_crashme rm -f xs_test xenstored_test xs_tdb_dump xenstore-control xenstore-ls rm -f $(CLIENTS) diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/xenstore_client.c --- a/tools/xenstore/xenstore_client.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/xenstore_client.c Wed Aug 02 13:39:47 2006 -0600 @@ -60,6 +60,8 @@ usage(const char *progname) errx(1, "Usage: %s [-h] [-s] [-t] key [...]", progname); #elif defined(CLIENT_exists) || defined(CLIENT_list) errx(1, "Usage: %s [-h] [-s] key [...]", progname); +#elif defined(CLIENT_chmod) + errx(1, "Usage: %s [-h] [-s] key <mode [modes...]>", progname); #endif } @@ -78,10 +80,61 @@ do_rm(char *path, struct xs_handle *xsh, } #endif +#if defined(CLIENT_chmod) +#define PATH_SEP '/' +#define MAX_PATH_LEN 256 + +static void +do_chmod(char *path, struct xs_permissions *perms, int nperms, int upto, + int recurse, struct xs_handle *xsh, xs_transaction_t xth) +{ + int ret; + + if (!path[0]) + return; + + ret = xs_set_permissions(xsh, xth, path, perms, nperms); + if (!ret) + err(1, "Error occurred setting permissions on '%s'", path); + + if (upto) { + /* apply same permissions to all parent entries: */ + char *path_sep_ptr = strrchr(path, PATH_SEP); + if (!path_sep_ptr) + errx(1, "Unable to locate path separator '%c' in '%s'", + PATH_SEP, path); + + *path_sep_ptr = '\0'; /* truncate path */ + + do_chmod(path, perms, nperms, 1, 0, xsh, xth); + + *path_sep_ptr = PATH_SEP; + } + + if (recurse) { + char buf[MAX_PATH_LEN]; + + /* apply same permissions to all child entries: */ + unsigned int xsval_n; + char **xsval = xs_directory(xsh, xth, path, &xsval_n); + + if (xsval) { + int i; + for (i = 0; i < xsval_n; i++) { + snprintf(buf, MAX_PATH_LEN, "%s/%s", path, xsval[i]); + + do_chmod(buf, perms, nperms, 0, 1, xsh, xth); + } + + free(xsval); + } + } +} +#endif static int perform(int optind, int argc, char **argv, struct xs_handle *xsh, - xs_transaction_t xth, int prefix, int tidy) + xs_transaction_t xth, int prefix, int tidy, int upto, int recurse) { while (optind < argc) { #if defined(CLIENT_read) @@ -168,6 +221,41 @@ perform(int optind, int argc, char **arg } free(list); optind++; +#elif defined(CLIENT_chmod) +#define MAX_PERMS 16 + struct xs_permissions perms[MAX_PERMS]; + int nperms = 0; + /* save path pointer: */ + char *path = argv[optind++]; + for (; argv[optind]; optind++, nperms++) + { + if (MAX_PERMS <= nperms) + errx(1, "Too many permissions specified. " + "Maximum per invocation is %d.", MAX_PERMS); + + perms[nperms].id = atoi(argv[optind]+1); + + switch (argv[optind][0]) + { + case 'n': + perms[nperms].perms = XS_PERM_NONE; + break; + case 'r': + perms[nperms].perms = XS_PERM_READ; + break; + case 'w': + perms[nperms].perms = XS_PERM_WRITE; + break; + case 'b': + perms[nperms].perms = XS_PERM_READ | XS_PERM_WRITE; + break; + default: + errx(1, "Invalid permission specification: '%c'", + argv[optind][0]); + } + } + + do_chmod(path, perms, nperms, upto, recurse, xsh, xth); #endif } @@ -183,6 +271,8 @@ main(int argc, char **argv) int ret = 0, socket = 0; int prefix = 0; int tidy = 0; + int upto = 0; + int recurse = 0; while (1) { int c, index = 0; @@ -193,6 +283,9 @@ main(int argc, char **argv) {"prefix", 0, 0, 'p'}, #elif defined(CLIENT_rm) {"tidy", 0, 0, 't'}, +#elif defined(CLIENT_chmod) + {"upto", 0, 0, 'u'}, + {"recurse", 0, 0, 'r'}, #endif {0, 0, 0, 0} }; @@ -202,6 +295,8 @@ main(int argc, char **argv) "p" #elif defined(CLIENT_rm) "t" +#elif defined(CLIENT_chmod) + "ur" #endif , long_options, &index); if (c == -1) @@ -222,6 +317,13 @@ main(int argc, char **argv) case 't': tidy = 1; break; +#elif defined(CLIENT_chmod) + case 'u': + upto = 1; + break; + case 'r': + recurse = 1; + break; #endif } } @@ -246,7 +348,7 @@ main(int argc, char **argv) if (xth == XBT_NULL) errx(1, "couldn't start transaction"); - ret = perform(optind, argc, argv, xsh, xth, prefix, tidy); + ret = perform(optind, argc, argv, xsh, xth, prefix, tidy, upto, recurse); if (!xs_transaction_end(xsh, xth, ret)) { if (ret == 0 && errno == EAGAIN) { diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/xenstored_core.c Wed Aug 02 13:39:47 2006 -0600 @@ -80,6 +80,7 @@ int quota_nb_entry_per_domain = 1000; int quota_nb_entry_per_domain = 1000; int quota_nb_watch_per_domain = 128; int quota_max_entry_size = 2048; /* 2K */ +int quota_max_transaction = 10; #ifdef TESTING static bool failtest = false; @@ -1342,6 +1343,7 @@ struct connection *new_connection(connwr new->write = write; new->read = read; new->can_write = true; + new->transaction_started = 0; INIT_LIST_HEAD(&new->out_list); INIT_LIST_HEAD(&new->watches); INIT_LIST_HEAD(&new->transaction_list); @@ -1739,6 +1741,7 @@ static void usage(void) " --entry-nb <nb> limit the number of entries per domain,\n" " --entry-size <size> limit the size of entry per domain, and\n" " --entry-watch <nb> limit the number of watches per domain,\n" +" --transaction <nb> limit the number of transaction allowed per domain,\n" " --no-recovery to request that no recovery should be attempted when\n" " the store is corrupted (debug only),\n" " --preserve-local to request that /local is preserved on start-up,\n" @@ -1755,6 +1758,7 @@ static struct option options[] = { { "output-pid", 0, NULL, 'P' }, { "entry-size", 1, NULL, 'S' }, { "trace-file", 1, NULL, 'T' }, + { "transaction", 1, NULL, 't' }, { "no-recovery", 0, NULL, 'R' }, { "preserve-local", 0, NULL, 'L' }, { "verbose", 0, NULL, 'V' }, @@ -1774,7 +1778,7 @@ int main(int argc, char *argv[]) const char *pidfile = NULL; int evtchn_fd = -1; - while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options, + while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, NULL)) != -1) { switch (opt) { case 'D': @@ -1804,6 +1808,9 @@ int main(int argc, char *argv[]) case 'S': quota_max_entry_size = strtol(optarg, NULL, 10); break; + case 't': + quota_max_transaction = strtol(optarg, NULL, 10); + break; case 'T': tracefile = optarg; break; diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/xenstored_core.h --- a/tools/xenstore/xenstored_core.h Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/xenstored_core.h Wed Aug 02 13:39:47 2006 -0600 @@ -79,6 +79,7 @@ struct connection /* List of in-progress transactions. */ struct list_head transaction_list; uint32_t next_transaction_id; + unsigned int transaction_started; /* The domain I'm associated with, if any. */ struct domain *domain; diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/xenstored_transaction.c --- a/tools/xenstore/xenstored_transaction.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/xenstored_transaction.c Wed Aug 02 13:39:47 2006 -0600 @@ -66,6 +66,7 @@ struct transaction struct list_head changes; }; +extern int quota_max_transaction; static unsigned int generation; /* Return tdb context to use for this connection. */ @@ -125,7 +126,6 @@ void do_transaction_start(struct connect { struct transaction *trans, *exists; char id_str[20]; - int started; /* We don't support nested transactions. */ if (conn->transaction) { @@ -133,11 +133,7 @@ void do_transaction_start(struct connect return; } - started = 0; - list_for_each_entry(trans, &conn->transaction_list, list) - started++; - - if (started > 5) { + if (conn->transaction_started > quota_max_transaction) { send_error(conn, ENOSPC); return; } @@ -166,6 +162,7 @@ void do_transaction_start(struct connect list_add_tail(&trans->list, &conn->transaction_list); talloc_steal(conn, trans); talloc_set_destructor(trans, destroy_transaction); + conn->transaction_started++; sprintf(id_str, "%u", trans->id); send_reply(conn, XS_TRANSACTION_START, id_str, strlen(id_str)+1); @@ -188,6 +185,7 @@ void do_transaction_end(struct connectio conn->transaction = NULL; list_del(&trans->list); + conn->transaction_started--; /* Attach transaction to arg for auto-cleanup */ talloc_steal(arg, trans); diff -r 4acc6d51f389 -r b76e86966e7e tools/xenstore/xsls.c --- a/tools/xenstore/xsls.c Tue Aug 01 14:58:20 2006 -0600 +++ b/tools/xenstore/xsls.c Wed Aug 02 13:39:47 2006 -0600 @@ -3,8 +3,19 @@ #include <string.h> #include <err.h> #include <xs.h> +#include <getopt.h> +#include <unistd.h> +#include <sys/ioctl.h> -void print_dir(struct xs_handle *h, char *path, int cur_depth) +static int max_width = 80; +static int desired_width = 60; + +#define TAG " = \"...\"" +#define TAG_LEN strlen(TAG) + +#define MIN(a, b) (((a) < (b))? (a) : (b)) + +void print_dir(struct xs_handle *h, char *path, int cur_depth, int show_perms) { char **e; char newpath[512], *val; @@ -16,33 +27,103 @@ void print_dir(struct xs_handle *h, char err(1, "xs_directory (%s)", path); for (i = 0; i<num; i++) { - int j; - for (j=0; j<cur_depth; j++) printf(" "); - printf("%s", e[i]); + char buf[MAX_STRLEN(unsigned int)+1]; + struct xs_permissions *perms; + unsigned int nperms; + int linewid; + + for (linewid=0; linewid<cur_depth; linewid++) putchar(' '); + linewid += printf("%.*s", + (int) (max_width - TAG_LEN - linewid), e[i]); sprintf(newpath, "%s%s%s", path, path[strlen(path)-1] == '/' ? "" : "/", e[i]); val = xs_read(h, XBT_NULL, newpath, &len); - if (val == NULL) + if (val == NULL) { printf(":\n"); - else if ((unsigned)len > (151 - strlen(e[i]))) - printf(" = \"%.*s...\"\n", (int)(148 - strlen(e[i])), val); - else - printf(" = \"%s\"\n", val); + } + else { + if (max_width < (linewid + len + TAG_LEN)) { + printf(" = \"%.*s...\"", + (int)(max_width - TAG_LEN - linewid), val); + } + else { + linewid += printf(" = \"%s\"", val); + if (show_perms) { + putchar(' '); + for (linewid++; + linewid < MIN(desired_width, max_width); + linewid++) + putchar((linewid & 1)? '.' : ' '); + } + } + } free(val); - print_dir(h, newpath, cur_depth+1); + + if (show_perms) { + perms = xs_get_permissions(h, XBT_NULL, newpath, &nperms); + if (perms == NULL) { + warn("\ncould not access permissions for %s", e[i]); + } + else { + int i; + fputs(" (", stdout); + for (i = 0; i < nperms; i++) { + if (i) + putchar(','); + xs_perm_to_string(perms+i, buf); + fputs(buf, stdout); + } + putchar(')'); + } + } + + putchar('\n'); + + print_dir(h, newpath, cur_depth+1, show_perms); } free(e); } +void usage(int argc, char *argv[]) +{ + fprintf(stderr, "Usage: %s [-p] [path]\n", argv[0]); +} + int main(int argc, char *argv[]) { + struct winsize ws; + int ret; + int c; + int show_perm = 0; + struct xs_handle *xsh = xs_daemon_open(); if (xsh == NULL) err(1, "xs_daemon_open"); - print_dir(xsh, argc == 1 ? "/" : argv[1], 0); +#define PAD 2 + + memset(&ws, 0, sizeof(ws)); + ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + if (!ret) + max_width = ws.ws_col - PAD; + + while (0 < (c = getopt(argc, argv, "p"))) { + switch (c) { + case 'p': + show_perm = 1; + max_width -= 16; + break; + case ':': + case '?': + default: + usage(argc, argv); + return 0; + } + } + + print_dir(xsh, (argc - optind) == 1 ? argv[optind] : "/", 0, show_perm); return 0; } diff -r 4acc6d51f389 -r b76e86966e7e xen/Makefile --- a/xen/Makefile Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/Makefile Wed Aug 02 13:39:47 2006 -0600 @@ -72,7 +72,7 @@ _distclean: clean .PHONY: delete-unfresh-files delete-unfresh-files: @if [ ! -r include/xen/compile.h -o -O include/xen/compile.h ]; then \ - rm -f include/xen/{banner,compile}.h; \ + rm -f include/xen/compile.h; \ fi # acm_policy.h contains security policy for Xen @@ -91,7 +91,7 @@ include/xen/acm_policy.h: # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. include/xen/compile.h: LANG=C -include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h +include/xen/compile.h: include/xen/compile.h.in @sed -e 's/@@date@@/$(shell date)/g' \ -e 's/@@time@@/$(shell date +%T)/g' \ -e 's/@@whoami@@/$(shell whoami)/g' \ @@ -103,11 +103,7 @@ include/xen/compile.h: include/xen/compi -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ -e 's!@@changeset@@!$(shell ((hg parents || head -n 7 ../ChangeLog || echo date: unavailable) | awk '{FS="changeset:[ ]+"}/^changeset/{CS=$$2};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null)!g' \ < include/xen/compile.h.in > $@.new - @cat include/xen/banner.h >> $@.new - @mv -f $@.new $@ - -include/xen/banner.h: - tools/figlet/figlet -d tools/figlet Xen $(XEN_FULLVERSION) > $@.new + tools/figlet/figlet -d tools/figlet Xen $(XEN_FULLVERSION) >> $@.new @mv -f $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s @@ -150,3 +146,15 @@ _cscope: .PHONY: MAP MAP: $(NM) $(TARGET) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map + +.PHONY: FORCE +FORCE: + +%.o %.i: %.c FORCE + $(MAKE) -f $(BASEDIR)/Rules.mk -C $(*D) $(@F) + +%.o %.s: %.S FORCE + $(MAKE) -f $(BASEDIR)/Rules.mk -C $(*D) $(@F) + +%/: FORCE + $(MAKE) -f $(BASEDIR)/Rules.mk -C $* built_in.o diff -r 4acc6d51f389 -r b76e86966e7e xen/Rules.mk --- a/xen/Rules.mk Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/Rules.mk Wed Aug 02 13:39:47 2006 -0600 @@ -43,7 +43,6 @@ include $(BASEDIR)/arch/$(TARGET_ARCH)/R # Do not depend on auto-generated header files. HDRS := $(subst $(BASEDIR)/include/asm-$(TARGET_ARCH)/asm-offsets.h,,$(HDRS)) -HDRS := $(subst $(BASEDIR)/include/xen/banner.h,,$(HDRS)) HDRS := $(subst $(BASEDIR)/include/xen/compile.h,,$(HDRS)) # Note that link order matters! @@ -106,3 +105,9 @@ _clean_%/: FORCE %.o: %.S $(HDRS) Makefile $(CC) $(CFLAGS) $(AFLAGS) -c $< -o $@ + +%.i: %.c $(HDRS) Makefile + $(CPP) $(CFLAGS) $< -o $@ + +%.s: %.S $(HDRS) Makefile + $(CPP) $(CFLAGS) $(AFLAGS) $< -o $@ diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/ia64/xen/dom_fw.c Wed Aug 02 13:39:47 2006 -0600 @@ -19,7 +19,7 @@ #include <asm/sal.h> #include <asm/meminit.h> #include <asm/fpswa.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/acpi.h> #include <asm/dom_fw.h> @@ -353,7 +353,8 @@ dom_fw_fake_acpi(struct domain *d, struc strcpy(xsdt->oem_id, "XEN"); strcpy(xsdt->oem_table_id, "Xen/ia64"); strcpy(xsdt->asl_compiler_id, "XEN"); - xsdt->asl_compiler_revision = (XEN_VERSION<<16)|(XEN_SUBVERSION); + xsdt->asl_compiler_revision = (xen_major_version() << 16) | + xen_minor_version(); xsdt->table_offset_entry[0] = dom_pa((unsigned long) fadt); tables->madt_ptr = dom_pa((unsigned long) madt); @@ -367,7 +368,8 @@ dom_fw_fake_acpi(struct domain *d, struc strcpy(fadt->oem_id, "XEN"); strcpy(fadt->oem_table_id, "Xen/ia64"); strcpy(fadt->asl_compiler_id, "XEN"); - fadt->asl_compiler_revision = (XEN_VERSION<<16)|(XEN_SUBVERSION); + fadt->asl_compiler_revision = (xen_major_version() << 16) | + xen_minor_version(); strncpy(facs->signature, FACS_SIG, 4); facs->version = 1; @@ -413,7 +415,8 @@ dom_fw_fake_acpi(struct domain *d, struc strcpy(dsdt->oem_id, "XEN"); strcpy(dsdt->oem_table_id, "Xen/ia64"); strcpy(dsdt->asl_compiler_id, "XEN"); - dsdt->asl_compiler_revision = (XEN_VERSION<<16)|(XEN_SUBVERSION); + dsdt->asl_compiler_revision = (xen_major_version() << 16) | + xen_minor_version(); /* Trivial namespace, avoids ACPI CA complaints */ tables->aml[0] = 0x10; /* Scope */ @@ -454,7 +457,8 @@ dom_fw_fake_acpi(struct domain *d, struc strcpy(madt->header.oem_id, "XEN"); strcpy(madt->header.oem_table_id, "Xen/ia64"); strcpy(madt->header.asl_compiler_id, "XEN"); - madt->header.asl_compiler_revision = (XEN_VERSION<<16)|(XEN_SUBVERSION); + madt->header.asl_compiler_revision = (xen_major_version() << 16) | + xen_minor_version(); /* An LSAPIC entry describes a CPU. */ for (i = 0; i < MAX_VIRT_CPUS; i++) { diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Wed Aug 02 13:39:47 2006 -0600 @@ -30,7 +30,7 @@ #include <asm/processor.h> #include <xen/event.h> #include <xen/console.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/elf.h> #include <asm/pgalloc.h> #include <asm/offsets.h> /* for IA64_THREAD_INFO_SIZE */ @@ -1069,7 +1069,8 @@ int construct_dom0(struct domain *d, panic("can't allocate start info page"); si = page_to_virt(start_info_page); memset(si, 0, PAGE_SIZE); - sprintf(si->magic, "xen-%i.%i-ia64", XEN_VERSION, XEN_SUBVERSION); + sprintf(si->magic, "xen-%i.%i-ia64", + xen_major_version(), xen_minor_version()); si->nr_pages = max_pages; si->flags = SIF_INITDOMAIN|SIF_PRIVILEGED; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/ia64/xen/xensetup.c Wed Aug 02 13:39:47 2006 -0600 @@ -13,7 +13,7 @@ #include <xen/mm.h> #include <public/version.h> #include <xen/gdbstub.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/console.h> #include <xen/domain.h> #include <xen/serial.h> @@ -547,11 +547,13 @@ void arch_get_xen_caps(xen_capabilities_ void arch_get_xen_caps(xen_capabilities_info_t info) { char *p=info; - - p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION); + int major = xen_major_version(); + int minor = xen_minor_version(); + + p += sprintf(p,"xen-%d.%d-ia64 ", major, minor); if (vmx_enabled) - p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p,"hvm-%d.%d-ia64 ", major, minor); *(p-1) = 0; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/powerpc/boot_of.c --- a/xen/arch/powerpc/boot_of.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/powerpc/boot_of.c Wed Aug 02 13:39:47 2006 -0600 @@ -22,7 +22,7 @@ #include <xen/init.h> #include <xen/lib.h> #include <xen/multiboot.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/spinlock.h> #include <xen/serial.h> #include <xen/time.h> @@ -976,9 +976,9 @@ multiboot_info_t __init *boot_of_init( of_printf("%s\n", "---------------------------------------------------"); of_printf("OF: Xen/PPC version %d.%d%s (%s@%s) (%s) %s\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, - XEN_COMPILE_BY, XEN_COMPILE_DOMAIN, - XEN_COMPILER, XEN_COMPILE_DATE); + xen_major_version(), xen_minor_version(), xen_extra_version(), + xen_compile_by(), xen_compile_domain(), + xen_compiler(), xen_compile_date()); of_printf("%s args: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n" "boot msr: 0x%lx\n", diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/powerpc/domain_build.c --- a/xen/arch/powerpc/domain_build.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/powerpc/domain_build.c Wed Aug 02 13:39:47 2006 -0600 @@ -25,7 +25,7 @@ #include <xen/init.h> #include <xen/ctype.h> #include <xen/iocap.h> -#include <xen/compile.h> +#include <xen/version.h> #include <asm/processor.h> #include <asm/papr.h> #include "oftree.h" @@ -153,7 +153,7 @@ int construct_dom0(struct domain *d, printk("xen_start_info: %p\n", si); sprintf(si->magic, "xen-%i.%i-powerpc%d%s", - XEN_VERSION, XEN_SUBVERSION, BITS_PER_LONG, "HV"); + xen_major_version(), xen_minor_version(), BITS_PER_LONG, "HV"); si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; si->shared_info = ((ulong)d->shared_info) - rma; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/powerpc/mpic_init.c --- a/xen/arch/powerpc/mpic_init.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/powerpc/mpic_init.c Wed Aug 02 13:39:47 2006 -0600 @@ -21,7 +21,6 @@ #include <xen/config.h> #include <xen/init.h> #include <xen/lib.h> -#include <xen/compile.h> #include <asm/mpic.h> #include "mpic_init.h" #include "oftree.h" diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/powerpc/ofd_fixup.c --- a/xen/arch/powerpc/ofd_fixup.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/powerpc/ofd_fixup.c Wed Aug 02 13:39:47 2006 -0600 @@ -21,7 +21,7 @@ #include <xen/config.h> #include <xen/lib.h> #include <xen/sched.h> -#include <xen/compile.h> +#include <xen/version.h> #include <public/xen.h> #include "of-devtree.h" @@ -420,7 +420,7 @@ static ofdn_t ofd_xen_props(void *m, str ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); xl = snprintf(xen, sizeof (xen), "Xen-%d.%d%s", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION); + xen_major_version(), xen_minor_version(), xen_extra_version()); ASSERT(xl < sizeof (xen)); ofd_prop_add(m, n, "version", xen, xl + 1); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/powerpc/powerpc64/traps.c --- a/xen/arch/powerpc/powerpc64/traps.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/traps.c Wed Aug 02 13:39:47 2006 -0600 @@ -22,7 +22,7 @@ #include <xen/lib.h> #include <xen/console.h> #include <public/xen.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/sched.h> void show_registers(struct cpu_user_regs *regs) @@ -32,7 +32,7 @@ void show_registers(struct cpu_user_regs console_start_sync(); printk("----[ Xen-%d.%d%s ]----\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION); + xen_major_version(), xen_minor_version(), xen_extra_version()); printk("CPU: %08x DOMID: %08x\n", smp_processor_id(), current->domain->domain_id); printk("pc %016lx msr %016lx\n" diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/dom0_ops.c --- a/xen/arch/x86/dom0_ops.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/dom0_ops.c Wed Aug 02 13:39:47 2006 -0600 @@ -429,7 +429,7 @@ long arch_do_dom0_op(struct dom0_op *op, ret = 0; hypercall_page = map_domain_page(mfn); - hypercall_page_initialise(hypercall_page); + hypercall_page_initialise(d, hypercall_page); unmap_domain_page(hypercall_page); put_page_and_type(mfn_to_page(mfn)); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/domain.c Wed Aug 02 13:39:47 2006 -0600 @@ -819,7 +819,7 @@ unsigned long hypercall_create_continuat #if defined(__i386__) regs->eax = op; - if ( supervisor_mode_kernel ) + if ( supervisor_mode_kernel || hvm_guest(current) ) regs->eip &= ~31; /* re-execute entire hypercall entry stub */ else regs->eip -= 2; /* re-execute 'int 0x82' */ diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/domain_build.c Wed Aug 02 13:39:47 2006 -0600 @@ -15,7 +15,7 @@ #include <xen/elf.h> #include <xen/kernel.h> #include <xen/domain.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/iocap.h> #include <xen/bitops.h> #include <asm/regs.h> @@ -704,7 +704,7 @@ int construct_dom0(struct domain *d, return -1; } - hypercall_page_initialise((void *)hypercall_page); + hypercall_page_initialise(d, (void *)hypercall_page); } /* Copy the initial ramdisk. */ @@ -726,7 +726,8 @@ int construct_dom0(struct domain *d, si->nr_pt_frames = nr_pt_pages; si->mfn_list = vphysmap_start; sprintf(si->magic, "xen-%i.%i-x86_%d%s", - XEN_VERSION, XEN_SUBVERSION, BITS_PER_LONG, xen_pae ? "p" : ""); + xen_major_version(), xen_minor_version(), + BITS_PER_LONG, xen_pae ? "p" : ""); /* Write the phys->machine and machine->phys table entries. */ for ( pfn = 0; pfn < d->tot_pages; pfn++ ) diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/hvm.c Wed Aug 02 13:39:47 2006 -0600 @@ -27,6 +27,7 @@ #include <xen/softirq.h> #include <xen/domain.h> #include <xen/domain_page.h> +#include <xen/hypercall.h> #include <asm/current.h> #include <asm/io.h> #include <asm/shadow.h> @@ -329,6 +330,65 @@ void hvm_print_line(struct vcpu *v, cons pbuf[(*index)++] = c; } +#if defined(__i386__) + +typedef unsigned long hvm_hypercall_t( + unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); +#define HYPERCALL(x) [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x +static hvm_hypercall_t *hvm_hypercall_table[] = { + HYPERCALL(mmu_update), + HYPERCALL(memory_op), + HYPERCALL(multicall), + HYPERCALL(update_va_mapping), + HYPERCALL(event_channel_op_compat), + HYPERCALL(xen_version), + HYPERCALL(grant_table_op), + HYPERCALL(event_channel_op) + /*HYPERCALL(hvm_op)*/ +}; +#undef HYPERCALL + +void hvm_do_hypercall(struct cpu_user_regs *pregs) +{ + if ( ring_3(pregs) ) + { + pregs->eax = -EPERM; + return; + } + + if ( pregs->eax > ARRAY_SIZE(hvm_hypercall_table) || + !hvm_hypercall_table[pregs->eax] ) + { + DPRINTK("HVM vcpu %d:%d did a bad hypercall %d.\n", + current->domain->domain_id, current->vcpu_id, + pregs->eax); + pregs->eax = -ENOSYS; + } + else + { + pregs->eax = hvm_hypercall_table[pregs->eax]( + pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi); + } +} + +#else /* __x86_64__ */ + +void hvm_do_hypercall(struct cpu_user_regs *pregs) +{ + printk("not supported yet!\n"); +} + +#endif + +/* Initialise a hypercall transfer page for a VMX domain using + paravirtualised drivers. */ +void hvm_hypercall_page_initialise(struct domain *d, + void *hypercall_page) +{ + hvm_funcs.init_hypercall_page(d, hypercall_page); +} + + /* * only called in HVM domain BSP context * when booting, vcpuid is always equal to apic_id diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/i8259.c --- a/xen/arch/x86/hvm/i8259.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/i8259.c Wed Aug 02 13:39:47 2006 -0600 @@ -590,7 +590,7 @@ int cpu_get_pic_interrupt(struct vcpu *v /* read the irq from the PIC */ intno = pic_read_irq(s); - *type = VLAPIC_DELIV_MODE_EXT; + *type = APIC_DM_EXTINT; return intno; } @@ -598,7 +598,7 @@ int is_pit_irq(struct vcpu *v, int irq, { int pit_vec; - if (type == VLAPIC_DELIV_MODE_EXT) + if (type == APIC_DM_EXTINT) pit_vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base; else pit_vec = diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/io.c Wed Aug 02 13:39:47 2006 -0600 @@ -695,12 +695,11 @@ void hvm_io_assist(struct vcpu *v) if ( p->type == IOREQ_TYPE_PIO ) hvm_pio_assist(regs, p, io_opp); - else { + else hvm_mmio_assist(regs, p, io_opp); - hvm_load_cpu_guest_regs(v, regs); - } /* Copy register changes back into current guest state. */ + hvm_load_cpu_guest_regs(v, regs); memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES); } /* else an interrupt send event raced us */ diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/platform.c Wed Aug 02 13:39:47 2006 -0600 @@ -827,7 +827,6 @@ void handle_mmio(unsigned long va, unsig /* Copy current guest state into io instruction state structure. */ memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); - hvm_store_cpu_guest_regs(v, regs, NULL); if ((inst_len = hvm_instruction_length(v)) <= 0) { diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/svm/intr.c Wed Aug 02 13:39:47 2006 -0600 @@ -76,7 +76,7 @@ interrupt_post_injection(struct vcpu * v switch(type) { - case VLAPIC_DELIV_MODE_EXT: + case APIC_DM_EXTINT: break; default: @@ -112,7 +112,7 @@ asmlinkage void svm_intr_assist(void) struct hvm_domain *plat=&v->domain->arch.hvm_domain; struct periodic_time *pt = &plat->pl_time.periodic_tm; struct hvm_virpic *pic= &plat->vpic; - int intr_type = VLAPIC_DELIV_MODE_EXT; + int intr_type = APIC_DM_EXTINT; int intr_vector = -1; int re_injecting = 0; unsigned long rflags; @@ -172,9 +172,9 @@ asmlinkage void svm_intr_assist(void) /* have we got an interrupt to inject? */ if (intr_vector >= 0) { switch (intr_type) { - case VLAPIC_DELIV_MODE_EXT: - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_LPRI: + case APIC_DM_EXTINT: + case APIC_DM_FIXED: + case APIC_DM_LOWEST: /* Re-injecting a PIT interruptt? */ if (re_injecting && is_pit_irq(v, intr_vector, intr_type)) { @@ -185,10 +185,10 @@ asmlinkage void svm_intr_assist(void) svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE); interrupt_post_injection(v, intr_vector, intr_type); break; - case VLAPIC_DELIV_MODE_SMI: - case VLAPIC_DELIV_MODE_NMI: - case VLAPIC_DELIV_MODE_INIT: - case VLAPIC_DELIV_MODE_STARTUP: + case APIC_DM_SMI: + case APIC_DM_NMI: + case APIC_DM_INIT: + case APIC_DM_STARTUP: default: printk("Unsupported interrupt type: %d\n", intr_type); BUG(); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Aug 02 13:39:47 2006 -0600 @@ -456,6 +456,28 @@ void svm_init_ap_context(struct vcpu_gue ctxt->flags = VGCF_HVM_GUEST; } +static void svm_init_hypercall_page(struct domain *d, void *hypercall_page) +{ + char *p; + int i; + + memset(hypercall_page, 0, PAGE_SIZE); + + for ( i = 0; i < (PAGE_SIZE / 32); i++ ) + { + p = (char *)(hypercall_page + (i * 32)); + *(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */ + *(u32 *)(p + 1) = i; + *(u8 *)(p + 5) = 0x0f; /* vmmcall */ + *(u8 *)(p + 6) = 0x01; + *(u8 *)(p + 7) = 0xd9; + *(u8 *)(p + 8) = 0xc3; /* ret */ + } + + /* Don't support HYPERVISOR_iret at the moment */ + *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */ +} + int start_svm(void) { u32 eax, ecx, edx; @@ -503,6 +525,8 @@ int start_svm(void) hvm_funcs.instruction_length = svm_instruction_length; hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg; hvm_funcs.init_ap_context = svm_init_ap_context; + + hvm_funcs.init_hypercall_page = svm_init_hypercall_page; hvm_enabled = 1; @@ -1392,6 +1416,7 @@ static void svm_io_instruction(struct vc /* Copy current guest state into io instruction state structure. */ memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); + hvm_store_cpu_guest_regs(v, regs, NULL); info.bytes = vmcb->exitinfo1; @@ -1459,7 +1484,7 @@ static void svm_io_instruction(struct vc count = (addr & ~PAGE_MASK) / size; } else - vmcb->rip = vmcb->exitinfo2; + regs->eip = vmcb->exitinfo2; send_pio_req(regs, port, count, size, addr, dir, 1); } @@ -1470,7 +1495,7 @@ static void svm_io_instruction(struct vc * On SVM, the RIP of the intruction following the IN/OUT is saved in * ExitInfo2 */ - vmcb->rip = vmcb->exitinfo2; + regs->eip = vmcb->exitinfo2; if (port == 0xe9 && dir == IOREQ_WRITE && size == 1) hvm_print_line(v, regs->eax); /* guest debug output */ @@ -1980,11 +2005,13 @@ static int svm_cr_access(struct vcpu *v, return result; } -static inline void svm_do_msr_access(struct vcpu *v, struct cpu_user_regs *regs) +static inline void svm_do_msr_access( + struct vcpu *v, struct cpu_user_regs *regs) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; int inst_len; u64 msr_content=0; + u32 eax, edx; ASSERT(vmcb); @@ -2018,6 +2045,14 @@ static inline void svm_do_msr_access(str default: if (long_mode_do_msr_read(regs)) goto done; + + if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) ) + { + regs->eax = eax; + regs->edx = edx; + goto done; + } + rdmsr_safe(regs->ecx, regs->eax, regs->edx); break; } @@ -2047,7 +2082,8 @@ static inline void svm_do_msr_access(str vlapic_msr_set(VLAPIC(v), msr_content); break; default: - long_mode_do_msr_write(regs); + if ( !long_mode_do_msr_write(regs) ) + wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx); break; } } @@ -2314,33 +2350,41 @@ static int svm_do_vmmcall(struct vcpu *v inst_len = __get_instruction_length(vmcb, INSTR_VMCALL, NULL); ASSERT(inst_len > 0); - /* VMMCALL sanity check */ - if (vmcb->cpl > get_vmmcall_cpl(regs->edi)) - { - printf("VMMCALL CPL check failed\n"); - return -1; - } - - /* handle the request */ - switch (regs->edi) - { - case VMMCALL_RESET_TO_REALMODE: - if (svm_do_vmmcall_reset_to_realmode(v, regs)) - { - printf("svm_do_vmmcall_reset_to_realmode() failed\n"); + if ( regs->eax & 0x80000000 ) + { + /* VMMCALL sanity check */ + if ( vmcb->cpl > get_vmmcall_cpl(regs->edi) ) + { + printf("VMMCALL CPL check failed\n"); return -1; } - - /* since we just reset the VMCB, return without adjusting the eip */ - return 0; - case VMMCALL_DEBUG: - printf("DEBUG features not implemented yet\n"); - break; - default: - break; - } - - hvm_print_line(v, regs->eax); /* provides the current domain */ + + /* handle the request */ + switch ( regs->eax ) + { + case VMMCALL_RESET_TO_REALMODE: + if ( svm_do_vmmcall_reset_to_realmode(v, regs) ) + { + printf("svm_do_vmmcall_reset_to_realmode() failed\n"); + return -1; + } + /* since we just reset the VMCB, return without adjusting + * the eip */ + return 0; + + case VMMCALL_DEBUG: + printf("DEBUG features not implemented yet\n"); + break; + default: + break; + } + + hvm_print_line(v, regs->eax); /* provides the current domain */ + } + else + { + hvm_do_hypercall(regs); + } __update_guest_eip(vmcb, inst_len); return 0; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/vioapic.c Wed Aug 02 13:39:47 2006 -0600 @@ -197,7 +197,7 @@ static void hvm_vioapic_write_indirect(s redir_content = ((redir_content >> 32) << 32) | (val & 0xffffffff); s->redirtbl[redir_index].value = redir_content; - hvm_vioapic_update_imr(s, redir_index); + hvm_vioapic_update_imr(s, redir_index); } else { printk("hvm_vioapic_write_indirect " "error register %x\n", s->ioregsel); @@ -295,8 +295,8 @@ static int ioapic_inj_irq(hvm_vioapic_t vector, trig_mode, delivery_mode); switch (delivery_mode) { - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_LPRI: + case dest_Fixed: + case dest_LowestPrio: if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1)) printk("<ioapic_inj_irq> level interrupt happen before cleared\n"); result = 1; @@ -314,6 +314,7 @@ static int ioapic_match_logical_addr(hvm static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t dest) { int result = 0; + uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR); ASSERT(s && s->lapic_info[number]); @@ -321,17 +322,17 @@ static int ioapic_match_logical_addr(hvm "number %i dest %x\n", number, dest); - switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) { - case 0xf: + switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR)) + { + case APIC_DFR_FLAT: result = - (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0; - break; - case 0x0: + (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0; + break; + case APIC_DFR_CLUSTER: /* Should we support flat cluster mode ?*/ - if ( ((s->lapic_info[number]->logical_dest >> 28) + if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4 == ((dest >> 0x4) & 0xf)) && - (((s->lapic_info[number]->logical_dest >> 24) & 0xf) - & (dest & 0xf)) ) + (logical_dest & (dest & 0xf)) ) result = 1; break; default: @@ -410,7 +411,7 @@ static void ioapic_deliver(hvm_vioapic_t } switch (delivery_mode) { - case VLAPIC_DELIV_MODE_LPRI: + case dest_LowestPrio: { struct vlapic* target; @@ -430,8 +431,8 @@ static void ioapic_deliver(hvm_vioapic_t break; } - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_EXT: + case dest_Fixed: + case dest_ExtINT: { uint8_t bit; for (bit = 0; bit < s->lapic_count; bit++) { @@ -452,10 +453,10 @@ static void ioapic_deliver(hvm_vioapic_t break; } - case VLAPIC_DELIV_MODE_SMI: - case VLAPIC_DELIV_MODE_NMI: - case VLAPIC_DELIV_MODE_INIT: - case VLAPIC_DELIV_MODE_STARTUP: + case dest_SMI: + case dest_NMI: + case dest_INIT: + case dest__reserved_2: default: printk("Not support delivey mode %d\n", delivery_mode); break; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/vlapic.c Wed Aug 02 13:39:47 2006 -0600 @@ -43,35 +43,43 @@ extern u32 get_apic_bus_cycle(void); static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] = { - 0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff + /* LVTT */ + LVT_MASK | APIC_LVT_TIMER_PERIODIC, + /* LVTTHMR */ + LVT_MASK | APIC_MODE_MASK, + /* LVTPC */ + LVT_MASK | APIC_MODE_MASK, + /* LVT0-1 */ + LINT_MASK, LINT_MASK, + /* LVTERR */ + LVT_MASK }; +int hvm_apic_support(struct domain *d) +{ + return d->arch.hvm_domain.apic_enabled; +} + int vlapic_find_highest_irr(struct vlapic *vlapic) { int result; - result = find_highest_bit(vlapic->irr, MAX_VECTOR); - - if ( result != -1 && result < 16 ) - { - printk("VLAPIC: irr on reserved bits %d\n ", result); - domain_crash_synchronous(); - } - - return result; -} - -int hvm_apic_support(struct domain *d) -{ - return d->arch.hvm_domain.apic_enabled; + result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR), + MAX_VECTOR); + + ASSERT( result == -1 || result > 16); + + return result; } s_time_t get_apictime_scheduled(struct vcpu *v) { struct vlapic *vlapic = VLAPIC(v); - if ( !hvm_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) ) + if ( !hvm_apic_support(v->domain) || + !vlapic_lvt_enabled(vlapic, APIC_LVTT) ) return -1; + return vlapic->vlapic_timer.expires; } @@ -79,16 +87,10 @@ int vlapic_find_highest_isr(struct vlapi { int result; - result = find_highest_bit(vlapic->isr, MAX_VECTOR); - - if ( result != -1 && result < 16 ) - { - int i = 0; - printk("VLAPIC: isr on reserved bits %d, isr is\n ", result); - for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ ) - printk("%d: %p\n", i, (void *)vlapic->isr[i]); - return -1; - } + result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR), + MAX_VECTOR); + + ASSERT( result == -1 || result > 16); return result; } @@ -98,20 +100,21 @@ uint32_t vlapic_update_ppr(struct vlapic uint32_t tpr, isrv, ppr; int isr; - tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */ + tpr = vlapic_get_reg(vlapic, APIC_TASKPRI); isr = vlapic_find_highest_isr(vlapic); + if ( isr != -1 ) isrv = (isr >> 4) & 0xf; /* ditto */ else isrv = 0; - if ( tpr >= isrv ) - ppr = vlapic->task_priority & 0xff; + if ( (tpr >> 4) >= isrv ) + ppr = tpr & 0xff; else ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */ - vlapic->processor_priority = ppr; + vlapic_set_reg(vlapic, APIC_PROCPRI, ppr); HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT, "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.", @@ -133,9 +136,9 @@ static int vlapic_match_dest(struct vcpu target, source, dest, dest_mode, short_hand, delivery_mode); if ( unlikely(target == NULL) && - ((delivery_mode != VLAPIC_DELIV_MODE_INIT) && - (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) && - (delivery_mode != VLAPIC_DELIV_MODE_NMI)) ) + ((delivery_mode != APIC_DM_INIT) && + (delivery_mode != APIC_DM_STARTUP) && + (delivery_mode != APIC_DM_NMI)) ) { HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, " "delivery_mode 0x%x, dest 0x%x.\n", v, delivery_mode, dest); @@ -143,22 +146,27 @@ static int vlapic_match_dest(struct vcpu } switch ( short_hand ) { - case VLAPIC_NO_SHORTHAND: + case APIC_DEST_NOSHORT: /* no shorthand */ if ( !dest_mode ) /* Physical */ { - result = (target != NULL ? target->id : v->vcpu_id) == dest; + result = ( ((target != NULL) ? + GET_APIC_ID(vlapic_get_reg(target, APIC_ID)): + v->vcpu_id)) == dest; } else /* Logical */ { + uint32_t ldr = vlapic_get_reg(target, APIC_LDR); + if ( target == NULL ) break; - if ( ((target->dest_format >> 28) & 0xf) == 0xf ) /* Flat mode */ + /* Flat mode */ + if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT) { - result = (target->logical_dest >> 24) & dest; + result = GET_APIC_LOGICAL_ID(ldr) & dest; } else { - if ( (delivery_mode == VLAPIC_DELIV_MODE_LPRI) && + if ( (delivery_mode == APIC_DM_LOWEST) && (dest == 0xff) ) { /* What shall we do now? */ @@ -166,22 +174,22 @@ static int vlapic_match_dest(struct vcpu "delivery mode\n"); domain_crash_synchronous(); } - result = (target->logical_dest == (dest & 0xf)) ? - ((target->logical_dest >> 4) & (dest >> 4)) : 0; + result = (GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ? + (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0; } } break; - case VLAPIC_SHORTHAND_SELF: + case APIC_DEST_SELF: if ( target == source ) result = 1; break; - case VLAPIC_SHORTHAND_INCLUDE_SELF: + case APIC_DEST_ALLINC: result = 1; break; - case VLAPIC_SHORTHAND_EXCLUDE_SELF: + case APIC_DEST_ALLBUT: if ( target != source ) result = 1; break; @@ -204,13 +212,13 @@ static int vlapic_accept_irq(struct vcpu struct vlapic *vlapic = VLAPIC(v); switch ( delivery_mode ) { - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_LPRI: + case APIC_DM_FIXED: + case APIC_DM_LOWEST: /* FIXME add logic for vcpu on reset */ if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) ) break; - if ( test_and_set_bit(vector, &vlapic->irr[0]) ) + if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) ) { HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "level trig mode repeatedly for vector %d\n", vector); @@ -221,25 +229,25 @@ static int vlapic_accept_irq(struct vcpu { HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "level trig mode for vector %d\n", vector); - set_bit(vector, &vlapic->tmr[0]); + set_bit(vector, vlapic->regs + APIC_TMR); } evtchn_set_pending(v, iopacket_port(v)); result = 1; break; - case VLAPIC_DELIV_MODE_RESERVED: + case APIC_DM_REMRD: printk("Ignore deliver mode 3 in vlapic_accept_irq\n"); break; - case VLAPIC_DELIV_MODE_SMI: - case VLAPIC_DELIV_MODE_NMI: + case APIC_DM_SMI: + case APIC_DM_NMI: /* Fixme */ printk("TODO: for guest SMI/NMI\n"); break; - case VLAPIC_DELIV_MODE_INIT: - if ( !level && trig_mode == 1 ) //Deassert + case APIC_DM_INIT: + if ( level && !(trig_mode & APIC_INT_ASSERT) ) //Deassert printk("This hvm_vlapic is for P4, no work for De-assert init\n"); else { @@ -255,7 +263,7 @@ static int vlapic_accept_irq(struct vcpu } break; - case VLAPIC_DELIV_MODE_STARTUP: + case APIC_DM_STARTUP: if ( v->arch.hvm_vcpu.init_sipi_sipi_state == HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM ) break; @@ -346,22 +354,23 @@ void vlapic_EOI_set(struct vlapic *vlapi if ( vector == -1 ) return ; - clear_bit(vector, &vlapic->isr[0]); + clear_bit(vector, vlapic->regs + APIC_ISR); vlapic_update_ppr(vlapic); - if ( test_and_clear_bit(vector, &vlapic->tmr[0]) ) + if ( test_and_clear_bit(vector, vlapic->regs + APIC_TMR) ) ioapic_update_EOI(vlapic->domain, vector); } -int vlapic_check_vector(struct vlapic *vlapic, - unsigned char dm, int vector) -{ - if ( (dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16) ) +static int vlapic_check_vector(struct vlapic *vlapic, + uint32_t dm, uint32_t vector) +{ + if ( (dm == APIC_DM_FIXED) && (vector < 16) ) { vlapic->err_status |= 0x40; - vlapic_accept_irq(vlapic->vcpu, VLAPIC_DELIV_MODE_FIXED, - vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0); - printk("<vlapic_check_vector>: check failed.\n"); + vlapic_accept_irq(vlapic->vcpu, APIC_DM_FIXED, + vlapic_lvt_vector(vlapic, APIC_LVTERR), 0, 0); + printk("<vlapic_check_vector>: check failed " + " dm %x vector %x\n", dm, vector); return 0; } return 1; @@ -369,13 +378,16 @@ int vlapic_check_vector(struct vlapic *v void vlapic_ipi(struct vlapic *vlapic) { - unsigned int dest = (vlapic->icr_high >> 24) & 0xff; - unsigned int short_hand = (vlapic->icr_low >> 18) & 3; - unsigned int trig_mode = (vlapic->icr_low >> 15) & 1; - unsigned int level = (vlapic->icr_low >> 14) & 1; - unsigned int dest_mode = (vlapic->icr_low >> 11) & 1; - unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7; - unsigned int vector = (vlapic->icr_low & 0xff); + uint32_t icr_low = vlapic_get_reg(vlapic, APIC_ICR); + uint32_t icr_high = vlapic_get_reg(vlapic, APIC_ICR2); + + unsigned int dest = GET_APIC_DEST_FIELD(icr_high); + unsigned int short_hand = icr_low & APIC_SHORT_MASK; + unsigned int trig_mode = icr_low & APIC_INT_ASSERT; + unsigned int level = icr_low & APIC_INT_LEVELTRIG; + unsigned int dest_mode = icr_low & APIC_DEST_MASK; + unsigned int delivery_mode = icr_low & APIC_MODE_MASK; + unsigned int vector = icr_low & APIC_VECTOR_MASK; struct vlapic *target; struct vcpu *v = NULL; @@ -384,7 +396,7 @@ void vlapic_ipi(struct vlapic *vlapic) HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, " "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x.", - vlapic->icr_high, vlapic->icr_low, short_hand, dest, + icr_high, icr_low, short_hand, dest, trig_mode, level, dest_mode, delivery_mode, vector); for_each_vcpu ( vlapic->domain, v ) @@ -392,7 +404,7 @@ void vlapic_ipi(struct vlapic *vlapic) if ( vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode, delivery_mode) ) { - if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) + if ( delivery_mode == APIC_DM_LOWEST) set_bit(v->vcpu_id, &lpr_map); else vlapic_accept_irq(v, delivery_mode, @@ -400,7 +412,7 @@ void vlapic_ipi(struct vlapic *vlapic) } } - if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) + if ( delivery_mode == APIC_DM_LOWEST) { v = vlapic->vcpu; target = apic_round_robin(v->domain, dest_mode, vector, lpr_map); @@ -411,158 +423,73 @@ void vlapic_ipi(struct vlapic *vlapic) } } +static uint32_t vlapic_get_tmcct(struct vlapic *vlapic) +{ + uint32_t counter_passed; + s_time_t passed, now = NOW(); + uint32_t tmcct = vlapic_get_reg(vlapic, APIC_TMCCT); + + ASSERT(vlapic != NULL); + + if ( unlikely(now <= vlapic->timer_last_update) ) + { + passed = ~0x0LL - vlapic->timer_last_update + now; + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed."); + } + else + passed = now - vlapic->timer_last_update; + + counter_passed = passed / + (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count); + + tmcct -= counter_passed; + + if ( tmcct <= 0 ) + { + if ( unlikely(!vlapic_lvtt_period(vlapic)) ) + { + tmcct = 0; + // FIXME: should we add interrupt here? + } + else + { + do { + tmcct += vlapic_get_reg(vlapic, APIC_TMICT); + } while ( tmcct < 0 ); + } + } + + vlapic->timer_last_update = now; + vlapic_set_reg(vlapic, APIC_TMCCT, tmcct); + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, + "timer initial count 0x%x, timer current count 0x%x, " + "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.", + vlapic_get_reg(vlapic, APIC_TMICT), + vlapic_get_reg(vlapic, APIC_TMCCT), + vlapic->timer_last_update, now, counter_passed); + + return tmcct; +} + static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, unsigned int len, unsigned int *result) { - if ( len != 4 ) - printk("<vlapic_read_aligned> read with len=%d (should be 4).\n", len); + ASSERT(len == 4 && offset > 0 && offset <= APIC_TDCR); *result = 0; switch ( offset ) { - case APIC_ID: - *result = vlapic->id << 24; - break; - - case APIC_LVR: - *result = vlapic->version; - break; - - case APIC_TASKPRI: - *result = vlapic->task_priority; - break; - case APIC_ARBPRI: printk("access local APIC ARBPRI register which is for P6\n"); break; - case APIC_PROCPRI: - *result = vlapic->processor_priority; - break; - - case APIC_EOI: /* EOI is write only */ - break; - - case APIC_LDR: - *result = vlapic->logical_dest; - break; - - case APIC_DFR: - *result = vlapic->dest_format; - break; - - case APIC_SPIV: - *result = vlapic->spurious_vec; - break; - - case APIC_ISR: - case 0x110: - case 0x120: - case 0x130: - case 0x140: - case 0x150: - case 0x160: - case 0x170: - *result = vlapic->isr[(offset - APIC_ISR) >> 4]; - break; - - case APIC_TMR: - case 0x190: - case 0x1a0: - case 0x1b0: - case 0x1c0: - case 0x1d0: - case 0x1e0: - case 0x1f0: - *result = vlapic->tmr[(offset - APIC_TMR) >> 4]; - break; - - case APIC_IRR: - case 0x210: - case 0x220: - case 0x230: - case 0x240: - case 0x250: - case 0x260: - case 0x270: - *result = vlapic->irr[(offset - APIC_IRR) >> 4]; - break; - - case APIC_ESR: - if ( vlapic->err_write_count ) - *result = vlapic->err_status; - break; - - case APIC_ICR: - *result = vlapic->icr_low; - break; - - case APIC_ICR2: - *result = vlapic->icr_high; - break; - - case APIC_LVTT: /* LVT Timer Reg */ - case APIC_LVTTHMR: /* LVT Thermal Monitor */ - case APIC_LVTPC: /* LVT Performance Counter */ - case APIC_LVT0: /* LVT LINT0 Reg */ - case APIC_LVT1: /* LVT Lint1 Reg */ - case APIC_LVTERR: /* LVT Error Reg */ - *result = vlapic->lvt[(offset - APIC_LVTT) >> 4]; - break; - - case APIC_TMICT: - *result = vlapic->timer_initial_count; - break; - case APIC_TMCCT: //Timer CCR - { - uint32_t counter_passed; - s_time_t passed, now = NOW(); - - if ( unlikely(now <= vlapic->timer_current_update) ) - { - passed = ~0x0LL - vlapic->timer_current_update + now; - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed."); - } - else - passed = now - vlapic->timer_current_update; - - counter_passed = passed / - (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count); - vlapic->timer_current_count -= counter_passed; - if ( vlapic->timer_current_count <= 0 ) - { - if ( unlikely(!vlapic_lvt_timer_period(vlapic)) ) - { - vlapic->timer_current_count = 0; - // FIXME: should we add interrupt here? - } - else - { - do { - vlapic->timer_current_count += vlapic->timer_initial_count; - } while ( vlapic->timer_current_count < 0 ); - } - } - - *result = vlapic->timer_current_count; - vlapic->timer_current_update = now; - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "timer initial count 0x%x, timer current count 0x%x, " - "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.", - vlapic->timer_initial_count, vlapic->timer_current_count, - vlapic->timer_current_update, now, counter_passed); - } - break; - - case APIC_TDCR: - *result = vlapic->timer_divconf; + *result = vlapic_get_tmcct(vlapic); break; default: - printk("Read local APIC address 0x%x not implemented\n", offset); - *result = 0; + *result = vlapic_get_reg(vlapic, offset); break; } } @@ -575,6 +502,9 @@ static unsigned long vlapic_read(struct unsigned long result; struct vlapic *vlapic = VLAPIC(v); unsigned int offset = address - vlapic->base_address; + + if ( offset > APIC_TDCR) + return 0; /* some bugs on kernel cause read this with byte*/ if ( len != 4 ) @@ -671,11 +601,11 @@ static void vlapic_write(struct vcpu *v, switch ( offset ) { case APIC_ID: /* Local APIC ID */ - vlapic->id = ((val) >> 24) & VAPIC_ID_MASK; + vlapic_set_reg(vlapic, APIC_ID, val); break; case APIC_TASKPRI: - vlapic->task_priority = val & 0xff; + vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff); vlapic_update_ppr(vlapic); break; @@ -684,24 +614,41 @@ static void vlapic_write(struct vcpu *v, break; case APIC_LDR: - vlapic->logical_dest = val & VAPIC_LDR_MASK; + vlapic_set_reg(vlapic, APIC_LDR, val & APIC_LDR_MASK); break; case APIC_DFR: - vlapic->dest_format = val ; + vlapic_set_reg(vlapic, APIC_DFR, val); break; case APIC_SPIV: - vlapic->spurious_vec = val & 0x1ff; - if ( !(vlapic->spurious_vec & 0x100) ) + vlapic_set_reg(vlapic, APIC_SPIV, val & 0x1ff); + + if ( !( val & APIC_SPIV_APIC_ENABLED) ) { int i; + uint32_t lvt_val; + + vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; + for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) - vlapic->lvt[i] |= 0x10000; - vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; + { + lvt_val = vlapic_get_reg(vlapic, APIC_LVT1 + 0x10 * i); + vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, + lvt_val | APIC_LVT_MASKED); + } + + if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK) + == APIC_DM_EXTINT ) + clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); } else + { vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK; + if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK) + == APIC_DM_EXTINT ) + set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); + } break; case APIC_ESR: @@ -712,12 +659,12 @@ static void vlapic_write(struct vcpu *v, case APIC_ICR: /* No delay here, so we always clear the pending bit*/ - vlapic->icr_low = val & ~(1 << 12); + vlapic_set_reg(vlapic, APIC_ICR, val & ~(1 << 12)); vlapic_ipi(vlapic); break; case APIC_ICR2: - vlapic->icr_high = val & 0xff000000; + vlapic_set_reg(vlapic, APIC_ICR2, val & 0xff000000); break; case APIC_LVTT: // LVT Timer Reg @@ -727,26 +674,25 @@ static void vlapic_write(struct vcpu *v, case APIC_LVT1: // LVT Lint1 Reg case APIC_LVTERR: // LVT Error Reg { - int vt = (offset - APIC_LVTT) >> 4; - - vlapic->lvt[vt] = val & vlapic_lvt_mask[vt]; if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK ) - vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK; + val |= APIC_LVT_MASKED; + + val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4]; + + vlapic_set_reg(vlapic, offset, val); /* On hardware, when write vector less than 0x20 will error */ - vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]), - vlapic_lvt_vector(vlapic, vt)); + if ( !(val & APIC_LVT_MASKED) ) + vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic, offset), + vlapic_lvt_vector(vlapic, offset)); if ( !vlapic->vcpu_id && (offset == APIC_LVT0) ) { - if ( (vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD) - == 0x700 ) - { - if ( vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK ) + if ( (val & APIC_MODE_MASK) == APIC_DM_EXTINT ) + if ( val & APIC_LVT_MASKED) clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); else set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); - } else clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); } @@ -758,16 +704,14 @@ static void vlapic_write(struct vcpu *v, { s_time_t now = NOW(), offset; - if ( vlapic_timer_active(vlapic) ) - stop_timer(&vlapic->vlapic_timer); - - vlapic->timer_initial_count = val; - vlapic->timer_current_count = val; - vlapic->timer_current_update = now; + stop_timer(&vlapic->vlapic_timer); + + vlapic_set_reg(vlapic, APIC_TMICT, val); + vlapic_set_reg(vlapic, APIC_TMCCT, val); + vlapic->timer_last_update = now; offset = APIC_BUS_CYCLE_NS * - vlapic->timer_divide_count * - vlapic->timer_initial_count; + vlapic->timer_divide_count * val; set_timer(&vlapic->vlapic_timer, now + offset); @@ -775,7 +719,8 @@ static void vlapic_write(struct vcpu *v, "bus cycle is %"PRId64"ns, now 0x%016"PRIx64", " "timer initial count 0x%x, offset 0x%016"PRIx64", " "expire @ 0x%016"PRIx64".", - APIC_BUS_CYCLE_NS, now, vlapic->timer_initial_count, + APIC_BUS_CYCLE_NS, now, + vlapic_get_reg(vlapic, APIC_TMICT), offset, now + offset); } break; @@ -787,6 +732,8 @@ static void vlapic_write(struct vcpu *v, tmp1 = val & 0xf; tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7); + + vlapic_set_reg(vlapic, APIC_TDCR, val); HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x", vlapic->timer_divide_count); @@ -827,19 +774,18 @@ void vlapic_msr_set(struct vlapic *vlapi value &= ~MSR_IA32_APICBASE_BSP; vlapic->apic_base_msr = value; - vlapic->base_address = vlapic_get_base_address(vlapic); - - if ( !(value & 0x800) ) + vlapic->base_address = vlapic->apic_base_msr & + MSR_IA32_APICBASE_BASE; + + /* with FSB delivery interrupt, we can restart APIC functionality */ + if ( !(value & MSR_IA32_APICBASE_ENABLE) ) set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status ); + else + clear_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status); HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "apic base msr is 0x%016"PRIx64", and base address is 0x%lx.", vlapic->apic_base_msr, vlapic->base_address); -} - -static inline int vlapic_get_init_id(struct vcpu *v) -{ - return v->vcpu_id; } void vlapic_timer_fn(void *data) @@ -850,31 +796,32 @@ void vlapic_timer_fn(void *data) s_time_t now; if ( unlikely(!vlapic_enabled(vlapic) || - !vlapic_lvt_timer_enabled(vlapic)) ) + !vlapic_lvt_enabled(vlapic, APIC_LVTT)) ) return; v = vlapic->vcpu; - timer_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER); + timer_vector = vlapic_lvt_vector(vlapic, APIC_LVTT); now = NOW(); - vlapic->timer_current_update = now; - - if ( test_and_set_bit(timer_vector, &vlapic->irr[0]) ) + vlapic->timer_last_update = now; + + if ( test_and_set_bit(timer_vector, vlapic->regs + APIC_IRR )) vlapic->intr_pending_count[timer_vector]++; - if ( vlapic_lvt_timer_period(vlapic) ) + if ( vlapic_lvtt_period(vlapic) ) { s_time_t offset; - - vlapic->timer_current_count = vlapic->timer_initial_count; + uint32_t tmict = vlapic_get_reg(vlapic, APIC_TMICT); + + vlapic_set_reg(vlapic, APIC_TMCCT, tmict); offset = APIC_BUS_CYCLE_NS * - vlapic->timer_divide_count * - vlapic->timer_initial_count; + vlapic->timer_divide_count * tmict; + set_timer(&vlapic->vlapic_timer, now + offset); } else - vlapic->timer_current_count = 0; + vlapic_set_reg(vlapic, APIC_TMCCT, 0); #if 0 if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) @@ -887,8 +834,8 @@ void vlapic_timer_fn(void *data) "now 0x%016"PRIx64", expire @ 0x%016"PRIx64", " "timer initial count 0x%x, timer current count 0x%x.", now, vlapic->vlapic_timer.expires, - vlapic->timer_initial_count, - vlapic->timer_current_count); + vlapic_get_reg(vlapic, APIC_TMICT), + vlapic_get_reg(vlapic, APIC_TMCCT)); } #if 0 @@ -922,23 +869,24 @@ int cpu_get_apic_interrupt(struct vcpu * { int highest_irr = vlapic_find_highest_irr(vlapic); - if ( highest_irr != -1 && highest_irr >= vlapic->processor_priority ) + if ( highest_irr != -1 && + ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) ) { if ( highest_irr < 0x10 ) { uint32_t err_vector; vlapic->err_status |= 0x20; - err_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR); + err_vector = vlapic_lvt_vector(vlapic, APIC_LVTERR); HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "Sending an illegal vector 0x%x.", highest_irr); - set_bit(err_vector, &vlapic->irr[0]); + set_bit(err_vector, vlapic->regs + APIC_IRR); highest_irr = err_vector; } - *mode = VLAPIC_DELIV_MODE_FIXED; + *mode = APIC_DM_FIXED; return highest_irr; } } @@ -952,7 +900,8 @@ int cpu_has_apic_interrupt(struct vcpu* if (vlapic && vlapic_enabled(vlapic)) { int highest_irr = vlapic_find_highest_irr(vlapic); - if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) { + if ( highest_irr != -1 && + ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) ) { return 1; } } @@ -967,30 +916,30 @@ void vlapic_post_injection(struct vcpu * return; switch ( deliver_mode ) { - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_LPRI: - set_bit(vector, &vlapic->isr[0]); - clear_bit(vector, &vlapic->irr[0]); + case APIC_DM_FIXED: + case APIC_DM_LOWEST: + set_bit(vector, vlapic->regs + APIC_ISR); + clear_bit(vector, vlapic->regs + APIC_IRR); vlapic_update_ppr(vlapic); - if ( vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER) ) + if ( vector == vlapic_lvt_vector(vlapic, APIC_LVTT) ) { vlapic->intr_pending_count[vector]--; if ( vlapic->intr_pending_count[vector] > 0 ) - test_and_set_bit(vector, &vlapic->irr[0]); + test_and_set_bit(vector, vlapic->regs + APIC_IRR); } break; /*XXX deal with these later */ - case VLAPIC_DELIV_MODE_RESERVED: + case APIC_DM_REMRD: printk("Ignore deliver mode 3 in vlapic_post_injection\n"); break; - case VLAPIC_DELIV_MODE_SMI: - case VLAPIC_DELIV_MODE_NMI: - case VLAPIC_DELIV_MODE_INIT: - case VLAPIC_DELIV_MODE_STARTUP: - vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode); + case APIC_DM_SMI: + case APIC_DM_NMI: + case APIC_DM_INIT: + case APIC_DM_STARTUP: + vlapic->direct_intr.deliver_mode &= deliver_mode; break; default: @@ -1002,7 +951,7 @@ static int vlapic_reset(struct vlapic *v static int vlapic_reset(struct vlapic *vlapic) { struct vcpu *v; - int apic_id, i; + int i; ASSERT( vlapic != NULL ); @@ -1010,29 +959,28 @@ static int vlapic_reset(struct vlapic *v ASSERT( v != NULL ); - apic_id = v->vcpu_id; - vlapic->domain = v->domain; - vlapic->id = apic_id; - vlapic->vcpu_id = v->vcpu_id; - vlapic->version = VLAPIC_VERSION; - - vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE; - - if ( apic_id == 0 ) + vlapic_set_reg(vlapic, APIC_ID, v->vcpu_id << 24); + + vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION); + + for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) + vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); + + vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU); + + vlapic_set_reg(vlapic, APIC_SPIV, 0xff); + + vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; + + if ( v->vcpu_id == 0 ) vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; - vlapic->base_address = vlapic_get_base_address(vlapic); - - for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) - vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK; - - vlapic->dest_format = 0xffffffffU; - - vlapic->spurious_vec = 0xff; + vlapic->base_address = vlapic->apic_base_msr & + MSR_IA32_APICBASE_BASE; hvm_vioapic_add_lapic(vlapic, v); @@ -1046,8 +994,8 @@ static int vlapic_reset(struct vlapic *v */ if ( !v->vcpu_id ) { - vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700; - vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500; + vlapic_set_reg(vlapic, APIC_LVT0, APIC_MODE_EXTINT << 8); + vlapic_set_reg(vlapic, APIC_LVT1, APIC_MODE_NMI << 8); set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); } #endif @@ -1055,7 +1003,8 @@ static int vlapic_reset(struct vlapic *v HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vcpu=%p, id=%d, vlapic_apic_base_msr=0x%016"PRIx64", " "base_address=0x%0lx.", - v, vlapic->id, vlapic->apic_base_msr, vlapic->base_address); + v, GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)), + vlapic->apic_base_msr, vlapic->base_address); return 1; } @@ -1077,6 +1026,18 @@ int vlapic_init(struct vcpu *v) memset(vlapic, 0, sizeof(struct vlapic)); + vlapic->regs_page = alloc_domheap_page(NULL); + if ( vlapic->regs_page == NULL ) + { + printk("malloc vlapic regs error for vcpu %x\n", v->vcpu_id); + xfree(vlapic); + return -ENOMEM; + } + + vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page)); + + memset(vlapic->regs, 0, PAGE_SIZE); + VLAPIC(v) = vlapic; vlapic->vcpu = v; diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/vmx/io.c --- a/xen/arch/x86/hvm/vmx/io.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 13:39:47 2006 -0600 @@ -81,7 +81,7 @@ interrupt_post_injection(struct vcpu * v switch(type) { - case VLAPIC_DELIV_MODE_EXT: + case APIC_DM_EXTINT: break; default: @@ -198,16 +198,17 @@ asmlinkage void vmx_intr_assist(void) highest_vector = cpu_get_interrupt(v, &intr_type); switch (intr_type) { - case VLAPIC_DELIV_MODE_EXT: - case VLAPIC_DELIV_MODE_FIXED: - case VLAPIC_DELIV_MODE_LPRI: + case APIC_DM_EXTINT: + case APIC_DM_FIXED: + case APIC_DM_LOWEST: vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE); TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); break; - case VLAPIC_DELIV_MODE_SMI: - case VLAPIC_DELIV_MODE_NMI: - case VLAPIC_DELIV_MODE_INIT: - case VLAPIC_DELIV_MODE_STARTUP: + + case APIC_DM_SMI: + case APIC_DM_NMI: + case APIC_DM_INIT: + case APIC_DM_STARTUP: default: printk("Unsupported interrupt type\n"); BUG(); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 13:39:47 2006 -0600 @@ -137,6 +137,8 @@ static void vmx_relinquish_guest_resourc if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) { kill_timer(&VLAPIC(v)->vlapic_timer); + unmap_domain_page_global(VLAPIC(v)->regs); + free_domheap_page(VLAPIC(v)->regs_page); xfree(VLAPIC(v)); } } @@ -477,7 +479,7 @@ static void vmx_ctxt_switch_to(struct vc vmx_restore_dr(v); } -void stop_vmx(void) +static void stop_vmx(void) { if (read_cr4() & X86_CR4_VMXE) __vmxoff(); @@ -562,7 +564,7 @@ static void fixup_vm86_seg_bases(struct BUG_ON(err); } -void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) +static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) { vmx_vmcs_enter(v); @@ -588,7 +590,7 @@ void vmx_load_cpu_guest_regs(struct vcpu vmx_vmcs_exit(v); } -int vmx_realmode(struct vcpu *v) +static int vmx_realmode(struct vcpu *v) { unsigned long rflags; @@ -596,7 +598,7 @@ int vmx_realmode(struct vcpu *v) return rflags & X86_EFLAGS_VM; } -int vmx_instruction_length(struct vcpu *v) +static int vmx_instruction_length(struct vcpu *v) { unsigned long inst_len; @@ -605,7 +607,7 @@ int vmx_instruction_length(struct vcpu * return inst_len; } -unsigned long vmx_get_ctrl_reg(struct vcpu *v, unsigned int num) +static unsigned long vmx_get_ctrl_reg(struct vcpu *v, unsigned int num) { switch ( num ) { @@ -622,7 +624,7 @@ unsigned long vmx_get_ctrl_reg(struct vc } /* SMP VMX guest support */ -void vmx_init_ap_context(struct vcpu_guest_context *ctxt, +static void vmx_init_ap_context(struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector) { int i; @@ -667,6 +669,50 @@ static int check_vmx_controls(u32 ctrls, return 0; } return 1; +} + +/* Setup HVM interfaces */ +static void vmx_setup_hvm_funcs(void) +{ + if ( hvm_enabled ) + return; + + hvm_funcs.disable = stop_vmx; + + hvm_funcs.initialize_guest_resources = vmx_initialize_guest_resources; + hvm_funcs.relinquish_guest_resources = vmx_relinquish_guest_resources; + + hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs; + hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs; + + hvm_funcs.realmode = vmx_realmode; + hvm_funcs.paging_enabled = vmx_paging_enabled; + hvm_funcs.instruction_length = vmx_instruction_length; + hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg; + + hvm_funcs.init_ap_context = vmx_init_ap_context; +} + +static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page) +{ + char *p; + int i; + + memset(hypercall_page, 0, PAGE_SIZE); + + for ( i = 0; i < (PAGE_SIZE / 32); i++ ) + { + p = (char *)(hypercall_page + (i * 32)); + *(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */ + *(u32 *)(p + 1) = i; + *(u8 *)(p + 5) = 0x0f; /* vmcall */ + *(u8 *)(p + 6) = 0x01; + *(u8 *)(p + 7) = 0xc1; + *(u8 *)(p + 8) = 0xc3; /* ret */ + } + + /* Don't support HYPERVISOR_iret at the moment */ + *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */ } int start_vmx(void) @@ -733,21 +779,9 @@ int start_vmx(void) vmx_save_init_msrs(); - /* Setup HVM interfaces */ - hvm_funcs.disable = stop_vmx; - - hvm_funcs.initialize_guest_resources = vmx_initialize_guest_resources; - hvm_funcs.relinquish_guest_resources = vmx_relinquish_guest_resources; - - hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs; - hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs; - - hvm_funcs.realmode = vmx_realmode; - hvm_funcs.paging_enabled = vmx_paging_enabled; - hvm_funcs.instruction_length = vmx_instruction_length; - hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg; - - hvm_funcs.init_ap_context = vmx_init_ap_context; + vmx_setup_hvm_funcs(); + + hvm_funcs.init_hypercall_page = vmx_init_hypercall_page; hvm_enabled = 1; @@ -1075,10 +1109,12 @@ static void vmx_io_instruction(unsigned /* Copy current guest state into io instruction state structure. */ memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); - - __vmread(GUEST_RIP, &eip); - __vmread(GUEST_CS_SELECTOR, &cs); - __vmread(GUEST_RFLAGS, &eflags); + hvm_store_cpu_guest_regs(current, regs, NULL); + + eip = regs->eip; + cs = regs->cs; + eflags = regs->eflags; + vm86 = eflags & X86_EFLAGS_VM ? 1 : 0; HVM_DBG_LOG(DBG_LEVEL_IO, @@ -1130,7 +1166,7 @@ static void vmx_io_instruction(unsigned else count = (addr & ~PAGE_MASK) / size; } else - __update_guest_eip(inst_len); + regs->eip += inst_len; send_pio_req(regs, port, count, size, addr, dir, 1); } @@ -1138,7 +1174,7 @@ static void vmx_io_instruction(unsigned if (port == 0xe9 && dir == IOREQ_WRITE && size == 1) hvm_print_line(current, regs->eax); /* guest debug output */ - __update_guest_eip(inst_len); + regs->eip += inst_len; send_pio_req(regs, port, 1, size, regs->eax, dir, 0); } } @@ -1877,6 +1913,7 @@ static inline void vmx_do_msr_read(struc static inline void vmx_do_msr_read(struct cpu_user_regs *regs) { u64 msr_content = 0; + u32 eax, edx; struct vcpu *v = current; HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx", @@ -1899,8 +1936,16 @@ static inline void vmx_do_msr_read(struc msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0; break; default: - if(long_mode_do_msr_read(regs)) + if (long_mode_do_msr_read(regs)) return; + + if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) ) + { + regs->eax = eax; + regs->edx = edx; + return; + } + rdmsr_safe(regs->ecx, regs->eax, regs->edx); break; } @@ -1942,7 +1987,8 @@ static inline void vmx_do_msr_write(stru vlapic_msr_set(VLAPIC(v), msr_content); break; default: - long_mode_do_msr_write(regs); + if ( !long_mode_do_msr_write(regs) ) + wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx); break; } @@ -2273,16 +2319,16 @@ asmlinkage void vmx_vmexit_handler(struc __update_guest_eip(inst_len); break; } -#if 0 /* keep this for debugging */ case EXIT_REASON_VMCALL: + { __get_instruction_length(inst_len); __vmread(GUEST_RIP, &eip); __vmread(EXIT_QUALIFICATION, &exit_qualification); - hvm_print_line(v, regs.eax); /* provides the current domain */ + hvm_do_hypercall(®s); __update_guest_eip(inst_len); break; -#endif + } case EXIT_REASON_CR_ACCESS: { __vmread(GUEST_RIP, &eip); @@ -2323,7 +2369,6 @@ asmlinkage void vmx_vmexit_handler(struc case EXIT_REASON_MWAIT_INSTRUCTION: __hvm_bug(®s); break; - case EXIT_REASON_VMCALL: case EXIT_REASON_VMCLEAR: case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD: diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/setup.c Wed Aug 02 13:39:47 2006 -0600 @@ -12,7 +12,7 @@ #include <xen/trace.h> #include <xen/multiboot.h> #include <xen/domain_page.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/gdbstub.h> #include <xen/percpu.h> #include <public/version.h> @@ -612,30 +612,32 @@ void arch_get_xen_caps(xen_capabilities_ void arch_get_xen_caps(xen_capabilities_info_t info) { char *p = info; + int major = xen_major_version(); + int minor = xen_minor_version(); #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) - p += sprintf(p, "xen-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "xen-%d.%d-x86_32 ", major, minor); if ( hvm_enabled ) - p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); #elif defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE) - p += sprintf(p, "xen-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "xen-%d.%d-x86_32p ", major, minor); if ( hvm_enabled ) { - p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION); - p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); + p += sprintf(p, "hvm-%d.%d-x86_32p ", major, minor); } #elif defined(CONFIG_X86_64) - p += sprintf(p, "xen-%d.%d-x86_64 ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "xen-%d.%d-x86_64 ", major, minor); if ( hvm_enabled ) { - p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION); - p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION); - p += sprintf(p, "hvm-%d.%d-x86_64 ", XEN_VERSION, XEN_SUBVERSION); + p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); + p += sprintf(p, "hvm-%d.%d-x86_32p ", major, minor); + p += sprintf(p, "hvm-%d.%d-x86_64 ", major, minor); } #else diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/shadow32.c --- a/xen/arch/x86/shadow32.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/shadow32.c Wed Aug 02 13:39:47 2006 -0600 @@ -990,18 +990,20 @@ alloc_p2m_table(struct domain *d) list_ent = d->page_list.next; - for ( gpfn = 0; list_ent != &d->page_list; gpfn++ ) + while ( list_ent != &d->page_list ) { page = list_entry(list_ent, struct page_info, list); mfn = page_to_mfn(page); + gpfn = get_gpfn_from_mfn(mfn); + if ( !(error = map_p2m_entry(l1tab, gpfn, mfn)) ) { domain_crash(d); break; } - list_ent = frame_table[mfn].list.next; + list_ent = page->list.next; } unmap_domain_page(l1tab); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/shadow_public.c --- a/xen/arch/x86/shadow_public.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/shadow_public.c Wed Aug 02 13:39:47 2006 -0600 @@ -1617,20 +1617,22 @@ alloc_p2m_table(struct domain *d) list_ent = d->page_list.next; - for ( gpfn = 0; list_ent != &d->page_list; gpfn++ ) + while ( list_ent != &d->page_list ) { struct page_info *page; page = list_entry(list_ent, struct page_info, list); mfn = page_to_mfn(page); + gpfn = get_gpfn_from_mfn(mfn); + if ( !(error = map_p2m_entry(top_tab, gpfn, mfn)) ) { domain_crash(d); break; } - list_ent = frame_table[mfn].list.next; + list_ent = page->list.next; } unmap_domain_page(top_tab); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/traps.c Wed Aug 02 13:39:47 2006 -0600 @@ -44,6 +44,7 @@ #include <xen/symbols.h> #include <xen/iocap.h> #include <xen/nmi.h> +#include <xen/version.h> #include <asm/shadow.h> #include <asm/system.h> #include <asm/io.h> @@ -429,18 +430,95 @@ DO_ERROR(17, "alignment check", alignmen DO_ERROR(17, "alignment check", alignment_check) DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) +int rdmsr_hypervisor_regs( + uint32_t idx, uint32_t *eax, uint32_t *edx) +{ + idx -= 0x40000000; + if ( idx > 0 ) + return 0; + + *eax = *edx = 0; + return 1; +} + +int wrmsr_hypervisor_regs( + uint32_t idx, uint32_t eax, uint32_t edx) +{ + struct domain *d = current->domain; + + idx -= 0x40000000; + if ( idx > 0 ) + return 0; + + switch ( idx ) + { + case 0: + { + void *hypercall_page; + unsigned long mfn; + unsigned long gmfn = ((unsigned long)edx << 20) | (eax >> 12); + unsigned int idx = eax & 0xfff; + + if ( idx > 0 ) + { + DPRINTK("Dom%d: Out of range index %u to MSR %08x\n", + d->domain_id, idx, 0x40000000); + return 0; + } + + mfn = gmfn_to_mfn(d, gmfn); + + if ( !mfn_valid(mfn) || + !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) ) + { + DPRINTK("Dom%d: Bad GMFN %lx (MFN %lx) to MSR %08x\n", + d->domain_id, gmfn, mfn, 0x40000000); + return 0; + } + + hypercall_page = map_domain_page(mfn); + hypercall_page_initialise(d, hypercall_page); + unmap_domain_page(hypercall_page); + + put_page_and_type(mfn_to_page(mfn)); + break; + } + + default: + BUG(); + } + + return 1; +} + int cpuid_hypervisor_leaves( uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { - if ( (idx < 0x40000000) || (idx > 0x40000000) ) + idx -= 0x40000000; + if ( idx > 2 ) return 0; - switch ( idx - 0x40000000 ) + switch ( idx ) { case 0: - *eax = 0x40000000; - *ebx = 0x006e6558; /* "Xen\0" */ - *ecx = *edx = 0; + *eax = 0x40000002; /* Largest leaf */ + *ebx = 0x566e6558; /* Signature 1: "XenV" */ + *ecx = 0x65584d4d; /* Signature 2: "MMXe" */ + *edx = 0x4d4d566e; /* Signature 3: "nVMM" */ + break; + + case 1: + *eax = (xen_major_version() << 16) | xen_minor_version(); + *ebx = 0; /* Reserved */ + *ecx = 0; /* Reserved */ + *edx = 0; /* Reserved */ + break; + + case 2: + *eax = 1; /* Number of hypercall-transfer pages */ + *ebx = 0x40000000; /* MSR base address */ + *ecx = 0; /* Features 1 */ + *edx = 0; /* Features 2 */ break; default: @@ -733,7 +811,10 @@ static int __spurious_page_fault( (l2e_get_flags(l2e) & disallowed_flags) ) return 0; if ( l2e_get_flags(l2e) & _PAGE_PSE ) - return 1; + { + l1e = l1e_empty(); /* define before use in debug tracing */ + goto spurious; + } l1t = map_domain_page(mfn); l1e = l1t[l1_table_offset(addr)]; @@ -742,6 +823,22 @@ static int __spurious_page_fault( if ( !(l1e_get_flags(l1e) & required_flags) || (l1e_get_flags(l1e) & disallowed_flags) ) return 0; + + spurious: + DPRINTK("Spurious fault in domain %u:%u at addr %lx, e/c %04x\n", + current->domain->domain_id, current->vcpu_id, + addr, regs->error_code); +#if CONFIG_PAGING_LEVELS >= 4 + DPRINTK(" l4e = %"PRIpte"\n", l4e_get_intpte(l4e)); +#endif +#if CONFIG_PAGING_LEVELS >= 3 + DPRINTK(" l3e = %"PRIpte"\n", l3e_get_intpte(l3e)); +#endif + DPRINTK(" l2e = %"PRIpte"\n", l2e_get_intpte(l2e)); + DPRINTK(" l1e = %"PRIpte"\n", l1e_get_intpte(l1e)); +#ifndef NDEBUG + show_registers(regs); +#endif return 1; } @@ -839,11 +936,7 @@ asmlinkage int do_page_fault(struct cpu_ if ( unlikely(!guest_mode(regs)) ) { if ( spurious_page_fault(addr, regs) ) - { - DPRINTK("Spurious fault in domain %u:%u at addr %lx\n", - current->domain->domain_id, current->vcpu_id, addr); return EXCRET_not_a_fault; - } if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) { @@ -1282,6 +1375,9 @@ static int emulate_privileged_op(struct break; #endif default: + if ( wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx) ) + break; + if ( (rdmsr_safe(regs->ecx, l, h) != 0) || (regs->eax != l) || (regs->edx != h) ) DPRINTK("Domain attempted WRMSR %p from " @@ -1313,6 +1409,12 @@ static int emulate_privileged_op(struct goto fail; break; default: + if ( rdmsr_hypervisor_regs(regs->ecx, &l, &h) ) + { + regs->eax = l; + regs->edx = h; + break; + } /* Everyone can read the MSR space. */ /*DPRINTK("Domain attempted RDMSR %p.\n", _p(regs->ecx));*/ if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) ) diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/x86_32/traps.c --- a/xen/arch/x86/x86_32/traps.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/x86_32/traps.c Wed Aug 02 13:39:47 2006 -0600 @@ -1,6 +1,6 @@ #include <xen/config.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/domain_page.h> #include <xen/init.h> #include <xen/sched.h> @@ -52,7 +52,7 @@ void show_registers(struct cpu_user_regs } printk("----[ Xen-%d.%d%s %s ]----\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, + xen_major_version(), xen_minor_version(), xen_extra_version(), print_tainted(taint_str)); printk("CPU: %d\nEIP: %04x:[<%08x>]", smp_processor_id(), fault_regs.cs, fault_regs.eip); @@ -131,7 +131,7 @@ asmlinkage void do_double_fault(void) /* Find information saved during fault and dump it to the console. */ tss = &init_tss[cpu]; printk("*** DOUBLE FAULT: Xen-%d.%d%s %s\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, + xen_major_version(), xen_minor_version(), xen_extra_version(), print_tainted(taint_str)); printk("CPU: %d\nEIP: %04x:[<%08x>]", cpu, tss->cs, tss->eip); @@ -490,9 +490,11 @@ static void hypercall_page_initialise_ri *(u16 *)(p+ 6) = 0x82cd; /* int $0x82 */ } -void hypercall_page_initialise(void *hypercall_page) -{ - if ( supervisor_mode_kernel ) +void hypercall_page_initialise(struct domain *d, void *hypercall_page) +{ + if ( hvm_guest(d->vcpu[0]) ) + hvm_hypercall_page_initialise(d, hypercall_page); + else if ( supervisor_mode_kernel ) hypercall_page_initialise_ring0_kernel(hypercall_page); else hypercall_page_initialise_ring1_kernel(hypercall_page); diff -r 4acc6d51f389 -r b76e86966e7e xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/arch/x86/x86_64/traps.c Wed Aug 02 13:39:47 2006 -0600 @@ -1,6 +1,6 @@ #include <xen/config.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/init.h> #include <xen/sched.h> #include <xen/lib.h> @@ -45,7 +45,7 @@ void show_registers(struct cpu_user_regs } printk("----[ Xen-%d.%d%s %s ]----\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, + xen_major_version(), xen_minor_version(), xen_extra_version(), print_tainted(taint_str)); printk("CPU: %d\nRIP: %04x:[<%016lx>]", smp_processor_id(), fault_regs.cs, fault_regs.rip); @@ -128,7 +128,7 @@ asmlinkage void do_double_fault(struct c /* Find information saved during fault and dump it to the console. */ printk("*** DOUBLE FAULT: Xen-%d.%d%s %s\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, + xen_major_version(), xen_minor_version(), xen_extra_version(), print_tainted(taint_str)); printk("CPU: %d\nRIP: %04x:[<%016lx>]", cpu, regs->cs, regs->rip); @@ -432,7 +432,7 @@ long do_set_callbacks(unsigned long even return 0; } -void hypercall_page_initialise(void *hypercall_page) +static void hypercall_page_initialise_ring3_kernel(void *hypercall_page) { char *p; int i; @@ -465,6 +465,14 @@ void hypercall_page_initialise(void *hyp *(u16 *)(p+ 9) = 0x050f; /* syscall */ } +void hypercall_page_initialise(struct domain *d, void *hypercall_page) +{ + if ( hvm_guest(d->vcpu[0]) ) + hvm_hypercall_page_initialise(d, hypercall_page); + else + hypercall_page_initialise_ring3_kernel(hypercall_page); +} + /* * Local variables: * mode: C diff -r 4acc6d51f389 -r b76e86966e7e xen/common/Makefile --- a/xen/common/Makefile Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/common/Makefile Wed Aug 02 13:39:47 2006 -0600 @@ -21,6 +21,7 @@ obj-y += symbols.o obj-y += symbols.o obj-y += trace.o obj-y += timer.o +obj-y += version.o obj-y += vsprintf.o obj-y += xmalloc.o @@ -28,4 +29,4 @@ obj-$(crash_debug) += gdbstub.o obj-$(crash_debug) += gdbstub.o # Object file contains changeset and compiler information. -kernel.o: $(BASEDIR)/include/xen/compile.h +version.o: $(BASEDIR)/include/xen/compile.h diff -r 4acc6d51f389 -r b76e86966e7e xen/common/kernel.c --- a/xen/common/kernel.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/common/kernel.c Wed Aug 02 13:39:47 2006 -0600 @@ -8,7 +8,7 @@ #include <xen/init.h> #include <xen/lib.h> #include <xen/errno.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/sched.h> #include <xen/shadow.h> #include <xen/guest_access.h> @@ -125,13 +125,13 @@ long do_xen_version(int cmd, XEN_GUEST_H { case XENVER_version: { - return (XEN_VERSION<<16) | (XEN_SUBVERSION); + return (xen_major_version() << 16) | xen_minor_version(); } case XENVER_extraversion: { xen_extraversion_t extraversion; - safe_strcpy(extraversion, XEN_EXTRAVERSION); + safe_strcpy(extraversion, xen_extra_version()); if ( copy_to_guest(arg, (char *)extraversion, sizeof(extraversion)) ) return -EFAULT; return 0; @@ -140,10 +140,10 @@ long do_xen_version(int cmd, XEN_GUEST_H case XENVER_compile_info: { struct xen_compile_info info; - safe_strcpy(info.compiler, XEN_COMPILER); - safe_strcpy(info.compile_by, XEN_COMPILE_BY); - safe_strcpy(info.compile_domain, XEN_COMPILE_DOMAIN); - safe_strcpy(info.compile_date, XEN_COMPILE_DATE); + safe_strcpy(info.compiler, xen_compiler()); + safe_strcpy(info.compile_by, xen_compile_by()); + safe_strcpy(info.compile_domain, xen_compile_domain()); + safe_strcpy(info.compile_date, xen_compile_date()); if ( copy_to_guest(arg, &info, 1) ) return -EFAULT; return 0; @@ -176,7 +176,7 @@ long do_xen_version(int cmd, XEN_GUEST_H case XENVER_changeset: { xen_changeset_info_t chgset; - safe_strcpy(chgset, XEN_CHANGESET); + safe_strcpy(chgset, xen_changeset()); if ( copy_to_guest(arg, (char *)chgset, sizeof(chgset)) ) return -EFAULT; return 0; diff -r 4acc6d51f389 -r b76e86966e7e xen/common/sched_credit.c --- a/xen/common/sched_credit.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/common/sched_credit.c Wed Aug 02 13:39:47 2006 -0600 @@ -296,11 +296,16 @@ __runq_tickle(unsigned int cpu, struct c cpumask_raise_softirq(mask, SCHEDULE_SOFTIRQ); } -static void +static int csched_pcpu_init(int cpu) { struct csched_pcpu *spc; unsigned long flags; + + /* Allocate per-PCPU info */ + spc = xmalloc(struct csched_pcpu); + if ( spc == NULL ) + return -1; spin_lock_irqsave(&csched_priv.lock, flags); @@ -311,9 +316,6 @@ csched_pcpu_init(int cpu) if ( csched_priv.master >= csched_priv.ncpus ) csched_priv.master = cpu; - /* Allocate per-PCPU info */ - spc = xmalloc(struct csched_pcpu); - BUG_ON( spc == NULL ); INIT_LIST_HEAD(&spc->runq); spc->runq_sort_last = csched_priv.runq_sort; schedule_data[cpu].sched_priv = spc; @@ -323,6 +325,8 @@ csched_pcpu_init(int cpu) cpu_set(cpu, csched_priv.idlers); spin_unlock_irqrestore(&csched_priv.lock, flags); + + return 0; } #ifndef NDEBUG @@ -490,7 +494,10 @@ csched_vcpu_init(struct vcpu *vc) /* Allocate per-PCPU info */ if ( unlikely(!CSCHED_PCPU(vc->processor)) ) - csched_pcpu_init(vc->processor); + { + if ( csched_pcpu_init(vc->processor) != 0 ) + return -1; + } CSCHED_VCPU_CHECK(vc); diff -r 4acc6d51f389 -r b76e86966e7e xen/drivers/char/Makefile --- a/xen/drivers/char/Makefile Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/drivers/char/Makefile Wed Aug 02 13:39:47 2006 -0600 @@ -1,6 +1,3 @@ obj-y += console.o obj-y += console.o obj-y += ns16550.o obj-y += serial.o - -# Object file contains changeset and compiler information. -console.o: $(BASEDIR)/include/xen/compile.h diff -r 4acc6d51f389 -r b76e86966e7e xen/drivers/char/console.c --- a/xen/drivers/char/console.c Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/drivers/char/console.c Wed Aug 02 13:39:47 2006 -0600 @@ -8,7 +8,7 @@ #include <stdarg.h> #include <xen/config.h> -#include <xen/compile.h> +#include <xen/version.h> #include <xen/init.h> #include <xen/lib.h> #include <xen/errno.h> @@ -488,14 +488,14 @@ void init_console(void) serial_set_rx_handler(sercon_handle, serial_rx); /* HELLO WORLD --- start-of-day banner text. */ - printk(XEN_BANNER); + printk(xen_banner()); printk(" http://www.cl.cam.ac.uk/netos/xen\n"); printk(" University of Cambridge Computer Laboratory\n\n"); printk(" Xen version %d.%d%s (%s@%s) (%s) %s\n", - XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION, - XEN_COMPILE_BY, XEN_COMPILE_DOMAIN, - XEN_COMPILER, XEN_COMPILE_DATE); - printk(" Latest ChangeSet: %s\n\n", XEN_CHANGESET); + xen_major_version(), xen_minor_version(), xen_extra_version(), + xen_compile_by(), xen_compile_domain(), + xen_compiler(), xen_compile_date()); + printk(" Latest ChangeSet: %s\n\n", xen_changeset()); set_printk_prefix("(XEN) "); if ( opt_sync_console ) diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-ia64/vmx_platform.h --- a/xen/include/asm-ia64/vmx_platform.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-ia64/vmx_platform.h Wed Aug 02 13:39:47 2006 -0600 @@ -59,6 +59,17 @@ static inline int vlapic_set_irq(struct return vmx_vcpu_pend_interrupt(t->vcpu, vec); } +enum ioapic_irq_destination_types { + dest_Fixed = 0, + dest_LowestPrio = 1, + dest_SMI = 2, + dest__reserved_1 = 3, + dest_NMI = 4, + dest_INIT = 5, + dest__reserved_2 = 6, + dest_ExtINT = 7 +}; + /* As long as we register vlsapic to ioapic controller, it's said enabled */ #define vlapic_enabled(l) 1 #define hvm_apic_support(d) 1 diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/domain.h Wed Aug 02 13:39:47 2006 -0600 @@ -55,7 +55,7 @@ extern void toggle_guest_mode(struct vcp * Initialise a hypercall-transfer page. The given pointer must be mapped * in Xen virtual address space (accesses are not validated or checked). */ -extern void hypercall_page_initialise(void *); +extern void hypercall_page_initialise(struct domain *d, void *); struct arch_domain { diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/hvm.h Wed Aug 02 13:39:47 2006 -0600 @@ -61,6 +61,8 @@ struct hvm_function_table { void (*init_ap_context)(struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector); + + void (*init_hypercall_page)(struct domain *d, void *hypercall_page); }; extern struct hvm_function_table hvm_funcs; @@ -121,6 +123,9 @@ hvm_instruction_length(struct vcpu *v) return hvm_funcs.instruction_length(v); } +void hvm_hypercall_page_initialise(struct domain *d, + void *hypercall_page); + static inline unsigned long hvm_get_guest_ctrl_reg(struct vcpu *v, unsigned int num) { diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/support.h Wed Aug 02 13:39:47 2006 -0600 @@ -29,7 +29,7 @@ #ifndef NDEBUG #define HVM_DEBUG 1 #else -#define HVM_DEBUG 0 +#define HVM_DEBUG 1 #endif #define hvm_guest(v) ((v)->arch.guest_context.flags & VGCF_HVM_GUEST) @@ -148,4 +148,6 @@ extern void hvm_print_line(struct vcpu * extern void hvm_print_line(struct vcpu *v, const char c); extern void hlt_timer_fn(void *data); +void hvm_do_hypercall(struct cpu_user_regs *pregs); + #endif /* __ASM_X86_HVM_SUPPORT_H__ */ diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/svm/vmmcall.h --- a/xen/include/asm-x86/hvm/svm/vmmcall.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/svm/vmmcall.h Wed Aug 02 13:39:47 2006 -0600 @@ -23,11 +23,11 @@ #define __ASM_X86_HVM_SVM_VMMCALL_H__ /* VMMCALL command fields */ -#define VMMCALL_CODE_CPL_MASK 0xC0000000 -#define VMMCALL_CODE_MBZ_MASK 0x3FFF0000 +#define VMMCALL_CODE_CPL_MASK 0x60000000 +#define VMMCALL_CODE_MBZ_MASK 0x1FFF0000 #define VMMCALL_CODE_COMMAND_MASK 0x0000FFFF -#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 30) | (func)) +#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 29) | (func) | 0x80000000) /* CPL=0 VMMCALL Requests */ #define VMMCALL_RESET_TO_REALMODE MAKE_VMMCALL_CODE(0,1) @@ -38,7 +38,7 @@ /* return the cpl required for the vmmcall cmd */ static inline int get_vmmcall_cpl(int cmd) { - return (cmd & VMMCALL_CODE_CPL_MASK) >> 30; + return (cmd & VMMCALL_CODE_CPL_MASK) >> 29; } #endif /* __ASM_X86_HVM_SVM_VMMCALL_H__ */ diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Aug 02 13:39:47 2006 -0600 @@ -33,58 +33,31 @@ static __inline__ int find_highest_bit(u #define VLAPIC(v) (v->arch.hvm_vcpu.vlapic) -#define VAPIC_ID_MASK 0xff -#define VAPIC_LDR_MASK (VAPIC_ID_MASK << 24) #define VLAPIC_VERSION 0x00050014 -#define VLAPIC_BASE_MSR_MASK 0x00000000fffff900ULL -#define VLAPIC_BASE_MSR_INIT_BASE_ADDR 0xfee00000U -#define VLAPIC_BASE_MSR_BASE_ADDR_MASK 0xfffff000U -#define VLAPIC_BASE_MSR_INIT_VALUE (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \ - MSR_IA32_APICBASE_ENABLE) #define VLOCAL_APIC_MEM_LENGTH (1 << 12) -#define VLAPIC_LVT_TIMER 0 -#define VLAPIC_LVT_THERMAL 1 -#define VLAPIC_LVT_PERFORM 2 -#define VLAPIC_LVT_LINT0 3 -#define VLAPIC_LVT_LINT1 4 -#define VLAPIC_LVT_ERROR 5 #define VLAPIC_LVT_NUM 6 -#define VLAPIC_LVT_BIT_MASK (1 << 16) -#define VLAPIC_LVT_BIT_VECTOR 0xff -#define VLAPIC_LVT_BIT_DELIMOD (0x7 << 8) -#define VLAPIC_LVT_BIT_DELISTATUS (1 << 12) -#define VLAPIC_LVT_BIT_POLARITY (1 << 13) -#define VLAPIC_LVT_BIT_IRR (1 << 14) -#define VLAPIC_LVT_BIT_TRIG (1 << 15) -#define VLAPIC_LVT_TIMERMODE (1 << 17) +#define VLAPIC_ID(vlapic) \ + (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID))) -#define VLAPIC_DELIV_MODE_FIXED 0x0 -#define VLAPIC_DELIV_MODE_LPRI 0x1 -#define VLAPIC_DELIV_MODE_SMI 0x2 -#define VLAPIC_DELIV_MODE_RESERVED 0x3 -#define VLAPIC_DELIV_MODE_NMI 0x4 -#define VLAPIC_DELIV_MODE_INIT 0x5 -#define VLAPIC_DELIV_MODE_STARTUP 0x6 -#define VLAPIC_DELIV_MODE_EXT 0x7 +/* followed define is not in apicdef.h */ +#define APIC_SHORT_MASK 0xc0000 +#define APIC_DEST_NOSHORT 0x0 +#define APIC_DEST_MASK 0x800 +#define vlapic_lvt_enabled(vlapic, lvt_type) \ + (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED)) -#define VLAPIC_NO_SHORTHAND 0x0 -#define VLAPIC_SHORTHAND_SELF 0x1 -#define VLAPIC_SHORTHAND_INCLUDE_SELF 0x2 -#define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3 +#define vlapic_lvt_vector(vlapic, lvt_type) \ + (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK) -#define vlapic_lvt_timer_enabled(vlapic) \ - (!((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK)) +#define vlapic_lvt_dm(vlapic, lvt_type) \ + (vlapic_get_reg(vlapic, lvt_type) & APIC_MODE_MASK) -#define vlapic_lvt_vector(vlapic, type) \ - ((vlapic)->lvt[(type)] & VLAPIC_LVT_BIT_VECTOR) - -#define vlapic_lvt_dm(value) (((value) >> 8) && 7) -#define vlapic_lvt_timer_period(vlapic) \ - ((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE) +#define vlapic_lvtt_period(vlapic) \ + (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC) #define _VLAPIC_GLOB_DISABLE 0x0 #define VLAPIC_GLOB_DISABLE_MASK 0x1 @@ -98,8 +71,12 @@ static __inline__ int find_highest_bit(u #define vlapic_global_enabled(vlapic) \ (!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status))) -#define VLAPIC_IRR(t) ((t)->irr[0]) -#define VLAPIC_ID(t) ((t)->id) +#define LVT_MASK \ + APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK + +#define LINT_MASK \ + LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY |\ + APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER typedef struct direct_intr_info { int deliver_mode; @@ -109,72 +86,52 @@ typedef struct direct_intr_info { #define MAX_VECTOR 256 struct vlapic { - uint32_t version; uint32_t status; - uint32_t id; uint32_t vcpu_id; + uint64_t apic_base_msr; unsigned long base_address; - unsigned long isr[BITS_TO_LONGS(MAX_VECTOR)]; - unsigned long irr[BITS_TO_LONGS(MAX_VECTOR)]; - unsigned long tmr[BITS_TO_LONGS(MAX_VECTOR)]; - uint32_t task_priority; - uint32_t processor_priority; - uint32_t logical_dest; - uint32_t dest_format; - uint32_t spurious_vec; - uint32_t lvt[6]; - uint32_t timer_initial_count; - uint32_t timer_current_count; - uint32_t timer_divconf; uint32_t timer_divide_count; struct timer vlapic_timer; int intr_pending_count[MAX_VECTOR]; - s_time_t timer_current_update; - uint32_t icr_high; - uint32_t icr_low; + s_time_t timer_last_update; direct_intr_info_t direct_intr; uint32_t err_status; - unsigned long init_ticks; uint32_t err_write_count; - uint64_t apic_base_msr; struct vcpu *vcpu; struct domain *domain; + struct page_info *regs_page; + void *regs; }; -static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig) +static inline int vlapic_set_irq(struct vlapic *vlapic, + uint8_t vec, uint8_t trig) { int ret; - ret = test_and_set_bit(vec, &t->irr[0]); + ret = test_and_set_bit(vec, vlapic->regs + APIC_IRR); if ( trig ) - set_bit(vec, &t->tmr[0]); + set_bit(vec, vlapic->regs + APIC_TMR); /* We may need to wake up target vcpu, besides set pending bit here */ return ret; } -static inline int vlapic_timer_active(struct vlapic *vlapic) +static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg) { - return active_timer(&vlapic->vlapic_timer); + return *( (uint32_t *)(vlapic->regs + reg)); } -int vlapic_find_highest_irr(struct vlapic *vlapic); +static inline void vlapic_set_reg(struct vlapic *vlapic, + uint32_t reg, uint32_t val) +{ + *((uint32_t *)(vlapic->regs + reg)) = val; +} -int vlapic_find_highest_isr(struct vlapic *vlapic); - -static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic) -{ - return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK); -} void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode); int cpu_has_apic_interrupt(struct vcpu* v); int cpu_get_apic_interrupt(struct vcpu* v, int *mode); - -extern uint32_t vlapic_update_ppr(struct vlapic *vlapic); - -int vlapic_update(struct vcpu *v); extern int vlapic_init(struct vcpu *vc); diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Wed Aug 02 13:39:47 2006 -0600 @@ -25,7 +25,6 @@ #include <public/hvm/vmx_assist.h> extern int start_vmx(void); -extern void stop_vmx(void); extern void vmcs_dump_vcpu(void); extern void vmx_init_vmcs_config(void); diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 13:39:47 2006 -0600 @@ -153,7 +153,7 @@ extern unsigned int cpu_rev; /* * Exit Qualifications for MOV for Control Register Access */ -#define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control register */ +#define CONTROL_REG_ACCESS_NUM 0xf /* 3:0, number of control register */ #define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */ #define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose register */ #define LMSW_SOURCE_DATA (0xFFFF << 16) /* 16:31 lmsw source */ diff -r 4acc6d51f389 -r b76e86966e7e xen/include/asm-x86/processor.h --- a/xen/include/asm-x86/processor.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/asm-x86/processor.h Wed Aug 02 13:39:47 2006 -0600 @@ -547,6 +547,10 @@ extern void mcheck_init(struct cpuinfo_x int cpuid_hypervisor_leaves( uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); +int rdmsr_hypervisor_regs( + uint32_t idx, uint32_t *eax, uint32_t *edx); +int wrmsr_hypervisor_regs( + uint32_t idx, uint32_t eax, uint32_t edx); #endif /* !__ASSEMBLY__ */ diff -r 4acc6d51f389 -r b76e86966e7e xen/include/public/io/netif.h --- a/xen/include/public/io/netif.h Tue Aug 01 14:58:20 2006 -0600 +++ b/xen/include/public/io/netif.h Wed Aug 02 13:39:47 2006 -0600 @@ -124,6 +124,14 @@ typedef struct netif_rx_request netif_rx #define _NETRXF_csum_blank (1) #define NETRXF_csum_blank (1U<<_NETRXF_csum_blank) +/* Packet continues in the next request descriptor. */ +#define _NETRXF_more_data (2) +#define NETRXF_more_data (1U<<_NETRXF_more_data) + +/* Packet to be followed by extra descriptor(s). */ +#define _NETRXF_extra_info (3) +#define NETRXF_extra_info (1U<<_NETRXF_extra_info) + struct netif_rx_response { uint16_t id; uint16_t offset; /* Offset in page of start of received packet */ diff -r 4acc6d51f389 -r b76e86966e7e docs/figs/acm_ezpolicy.eps --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figs/acm_ezpolicy.eps Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,657 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%BoundingBox: 0 0 610 400 +% +% created by bmeps 1.2.6a (SCCS=1.78) +% +/pstr + 610 string +def +/inputf + currentfile + /ASCII85Decode filter + /RunLengthDecode filter +def +gsave +0 400 translate +610 400 scale +610 400 8 [610 0 0 -400 0 0] +{ inputf pstr readstring pop } +image +r;Qmd6ps=,r^.#_8PW)W:fC4d:Jq*eJka?]JkgnmP"tsM!)EGd%7s,^8OZ0@77fs; +77'??705qG4Sf!e6pt0dBlJ$6H@:BtK8,-ULk:B'L4Y6'Lk:B'LAZi1L4b55LA6Du +I0Fb9BjEhVr;R-m;-@(3Bk_O*G'831IK"hMI=cm!I=cmrIK"NpI=6EfrcJ3er,r'_ +rHA*Xrb2IA?VWW\rrbGT86&[h<YAS@?"./K?t*JP@UEMP?XI8M@=hm=@$4oL>KU.P +?s?uGrEfn8='8U';G^7f;cEWm%T$&$92/,W:eEo6!<5/JrCmAj;cQlt>52>&>5_TU +=+XM*=+XN'<sVf+;c?Oj:/+I^9E%Np8P)EB770F.5smgo+94/a6N0LZ9heG_;cWft +rE0#!!*0"rJl'QcJkptoO\bjL#Ydra8P)EB77I&?"@5=;5!8g*%Q6't*ATB46qBjC +9i+berDies#ZXl';c-Cf:/6C8Jk^hkJkZ>A:QXo4rs"Q\9heEFlgauZO%i5;8rW'* +rt:&I2DR$=.30ck4@D_29hnM`;u9So;Z]fm;#X2j9hg44b"I=Ya\%.Vn4>s,jHtgV +I!BaVEH,o8Bk_3g>%QEJ8P+s'R#6KCG]\+KEGoc0BkLjXA_N/87uZW-R?<GaKSG,3 +J:N#pH?F+JhM2"b$RdA<+>PuC84ZHM;#O;n<E8ur!DuYl:B!t>8qKZt8qKY(8Qc"] +Xg"XjQ&q#bMM[(?IsQ-K=^(,_8cP6]YbdeROH,9WM2$Y4H?*\%>3e[Ks/*9:Ybn+b +S=,_1P`h&aK6h<Hl8CCN-mocQ1-.]l9jqaG@UWeYB4><7s+3no97fdX8qKY(8Q>_M +ZF-X&R$3VkN/NLGJ:)KU>snW`8cOgV[A][aPE:c_Mhm(;I!'726iTYEs-p[8Z`0do +SXZ%8QBRAfL44&>s#)bg-mocQ1-@oo8l\nn='Jo.<rc@fs+3mq97ffq92GS@W2lVY +Oc5*LJ:;fjG&hM8?:Orf9E0[DX.blBN/3.;IX6<`Ec5Yu7fPqGs-'dtXJDJWQBI>i +MMd.@J9u69s#)bg-n,oS1-@oo9%j!_lMlH/JkL\gN(Y,iJ=W=!O,8O?H?O=GChdZt +Ame7292#;8SY)8Bs!VPm?qUGg7/r=IX/+AIP)bETK7JFNaa8;R=oUB<0.87b,W7YM +8PB*YrqcWrn"3GU5QXKCkPG5V9+(@lPY78@PY78@p%(fWl1t3L!U9FI9*+;Qr(I%h +!r:o[fh2A7n*NdIrrW#WY4kQml1mtFn*f[;q>^"Y!U9E39BSs"8FT.Zs*U)uOc+pC +H?O:FC2!QX$"-C*84`c.Q'[X,rsNFN?qUGg7/r4?Un@Yd"H%teJ:.@r&UAV@=oUB< +0.81`,W7eQ8k]3Zrql]tLDXF&rkATFBGc!gr;QaLrC[OTs//K!s//K!s4/st9*5.n +0)S?Ds8O_>9*5.n0)\EIs8O0emJjZd9**Z;n4Nf6p&7Scn*W+%9*YFr++!>S\+iT# +s8O]En*W+%9*67Xs8W$>o1K/bs"8mrJkO]g)uk,DOc>0KI<]jPCM79h@Us%W9)hOW +s*'QeNV<A\A7]+?s$fEVLRk',QN$mcKn4[Ort9L!GB$ab3&WE<.2F0e4[Vb5s7lTl +rr^k4Gk_%6!f&JMrVlj\rC[O6s2@ISs2@ISs04`Z9*5.n+8eb5s8O2/9*5.n+8nh; +s8O06UAsdRo1K/bs"a+;!rr9Ur_!8M2XX3Cs8O06UAsdRq+CqlruXm,2E'np!rr9B +n4Ni_ruZhcJkO]g2#hcWMi!1>HZsLKCM.0e@:EbS8cMFVs*'?YM>r-RGB.V;B4PKO +@Urh;s$]?ULR=KsP`PhD!.b(K'6SA=G&UR`3&`K=.2F0e4\/:Bs7lTmrrT)Pa7fN7 +f/SQbrr>[i9+[?fj?`&1j?`&1H::K`s8UsT9,.F+hXsPAruXnjs1qA.ruXnjs8UsT +9*Fqfs66<X9*OS[p&G%6rC[k)ruXm,s7nECs8UsK92".As5$CArVm$o9A]^KhYp.O +d.RG3\4cf#!)*=k"\VMFs8UsT9*P@Vq>]]Sr(@IuruXm,s7nEChZ*W4r_!=mru_7? +%SKIAp&F]p9BlJO9;DOUqF^niru_55"5a(XhYp.MhZ*W4r_!=mruZhcJkO]g2?.WL +LkgY6I!BdQD/!Tm@U`hR8H2=Us)<[JL];mPG]dtBBkCoU@Ui_8s$fKXJWlCbP)kS" +rtK^$FEMbF=8t6=2D6Ts-oaOa925H]rWN9$k:#fjrrYO$s8Vsj./!U$s6'DCs7@C, +fDiO^s4'h<s8T@11]RIshZ(827fWK1fDiO^s4.*C$o<hAmRp:2s26#Zru_265QCa* +9pPb0/kuBGZ*Q7<s1P?1eP/d<ruW?>s2Co9gJ-)qehc1*859-a+!45Wru]km]r1n\ +9hkZfS"frG9DqR2s8O08Q2fDffDiO^s4'h<s8O08s8O1gs40!_b"0)CbtH[g]JfX[ +(B=CV92!n:]VkeZ9@s3VVuP7>9E5#6JkL\gf1S%%Ck%(jK7A8nF`MA8B4YR^@pMS( +92#;$ItNFSIscK`Ec,Z*AcH4L>t4ic8H4.!P*;#gN/@Q6!do9;rcJ`h<rY9C2_QTu +-oaOa9i1lbrWE3#8@S0i"5bO$s8,PBhZ'k\S,]bneh^(truX`1q*@dUruX^$s8VEb +bo]DMs8O2;ruX`1q*@d4qYpL#2bs5L+%?50+8nr!s8O1,nG.Ap:B1>97S*CU+%H;+ +5u.I[+&;\4+%?5*5P>$u5u'R1:B1>9:/:ih+8Z!Z7fW9M:B1>99E5#QrD"[=ru[Qr +q0G:%ruX`1q*@dUruY#9ru^q6+$iXb6Vd:E61t8(7Jfgqs8O09:AXu47fW9MqYqX, +s7nrUs8O0m:4c6m:,W&bH\$d"J:2`gF`D;6B4PL\>"&Bc:B,!SJV*oPI<p-\EGfN( +s'oJ@7/ohMs*BQaOcb]ar;RIXH$4=PCfLEr4#\]A)C[d892/7_q#1?pT4%0g!f)%# +qbT8is5`eop#Q.X5Z%L\+&N";02V]K+&Gf6s7u]U78Qh\ru_:@+&N";0C&SN0E;%o +;#gP;;#gP;rD<Im($(c9:/Luj+&Gf6ruY);s"@4KruY)7rrXqSru_/8(B=CV:f.2l ++92?_;#gPK;#gP;;#gP;rD<Im($(c9:B1>9;#gPK;#gP;;#gP;s8O2=:^4i;\c:h7 +:A[j's8O0;;#gP;;#gPKs8O0;s8O`Ks8O0m;!:`-:@M"8s'p5#J:W6"H[9mXE,96" +@piD+s%Z>h@s39Ns+#QFH?XIMCh`oZ?s#er9M5>.L5_1SNrK%pL]@DJH?XLPBiG$r +5!(PO*%<s992JOdq#1?p)!Chs!P_M2,lhHOrrF8"qboJBs8Uh2huE_&92k]e+&i48 ++&i4>+&c,<s,5h8`D]_8ru_+;+&i48+92?_9E5#6;u6M9;uck>rDNass8F)U5YtBX +s8O0>;u6M9;ucY8;uck>;u6Ol*s2<=+8f%Qs8O0>;uck>qYqX9s7ma8s8O0>s8O2> +;ZZpurZ;h>:fI5j+&i48+&i4>+&i4>+8Z!ZqbmXjs8T>dqG7t-ruY'6qYqX6s7mc5 +ruY);q&`H5ruZhhJl(&q"TMhJH%#Ph-ZO$=An,.I5lXYWs'K_jIK+bEH[0gYEGfOk +@pW/#s%H,dF+T7.NrK%[M2-fart0HsE+`#I5<h4c/0$3&6V10Rrr3#urqucs^Hh_s +#JU6=,p`Nk;>^@oG_c,p2td3U6c8rp+&Z(ks09fJbqN,sruY3>s8O0;q>$4RqYqYj +s09fJbqS&TMp25$McAU6]N"q2+8o.?s8O2<<&XdV+&l4ms09fJbqN,nruY4gs2E4Y +fi6E"`DksP<)i_o+&l5>ru]qoZ-<6m0NA)P+&r:?+8o.?s8O2=<#"$cZ-<6m0N@oK ++&r:?+4C2.<9;g4<!:YLruXr2<#5N6+&l4ms09fJbqRiNZ-<6m0N@oK++dID<7b(P +s&s2[H2@OfEc,W(?s6Djs&;tt>&/5*s*K*=H?XOQDJK2Z>#@H_:/(\*I>*OWrre18 +L4t6YrtBHkA5E4n6U*Xf*%X0?9i=nP2`CLk!IoUsrs1^e4S/T;!%#DXrrKT"qGmjZ +s*@D/s40..<\3),s48>_<r`1A<`]8#+'-)Ti)IDc]N3kgs48>_<o*f/h>aBO<pBYW +s8O2><W`=$+8](?s8O2?<\WA0s48>_<lP+=<`[TCs7MXI<m^F;p7=cT`W,s=<r`1A +<o*fUf,mL`s8O0As8O2><W`=$+8](Wh>dN,+%KAFq7Kc.ruY:go)JET7oiZ[s4/:f +<W`=$+9#:Ph>dN,+%KAfs8U[m7om>!]Rj2J<e=<?<!<5%Ao;_erss*eC1UaR9fi;R +<<$!2DKPUP1LF3X3r`&Qs(ck0L!K^RLPCM8J:@O>EGJrUs$T7>3\MI%4%;tC;c?Rn +<*!+(=]\a6TDecljs:#&rr2uBqYpW;3$8!$#"Th<>?Dt<rEB@p+!4,S>6,ffr`]mT ++'VrJ+%9C41/D+F+!4,S>7=%E8k:%&>?aB83?K@@>6,ffqHEtB+8oCG808pGr`^IA ++!4]k9JR\M<a/d%3?L7^>?arH+'Vqk+'Vr?+!4,S>6Q)j>?`0kr*'1D+8T1D808pG +r`^"61/D*r+'VrC3?L7^>?eN8Vb$Se!?WE^>6@D<+%lN:"%XLU9)`#r;_h.#>No@D +=7B8os&39<DZ"JdE,TQ-ARSeB8icoQ=8u3+BQ!`f'6%l+C1UgX<(]1N<)N[.F*`@g +KDpHHJU`)oGB7Y8?;(;g6pj!j*%!a::/b.o=^,3>?smDP@T]Q,rr^IF!6k0:!T,#O +>M<9as8Va6;hA5*>I[l@s%QU'ASD!U&SGZa?WpH+7Q19N>Q7E"?tF$LBfKa:@UE;= +:e!AC<)im,CiaiII!U-dH?j^VEG]E#>"AT_7moBn*%!a::/b(k=]o$;?X[AP@VD,, +rr^IF!5J7-!P^mO?.rQes5&Yo?%Q:4>I[lqls!.]='Ad1>$>'3=&i0p9Lh<?s'&^o +>>.pr>$>'4>$5!0<Du[e7mBZH=&eO&?t<tfChmkdCER>)AR]"N;Hj)m7moBn)C@O8 +:/Fkh='&O/?!grI@>B+*rrOJHFT2:A,s7t#rrK<"Jm6o4!Zsj3Jm3h2[p)gtfi1+$ +6:4%+6UF((5<V(h2bVbg>?dEH<'<Q76U=(,6:!k$4Zb\`9@oD0<0Q*H9Mn\c;,^Ck +;Gg:d9he2_g5eir6om(A-9F[l:ejhd<)m((r`]G0a#O"s#\*i7L!4$,-0G.*!FVOO +=k-Z,=+XM`<rlHgnc&g[PZ_'h=d8IV#4.OR<)HSVnc''aO%Mo16TQt@-9F[d9)_Nd +:f:3j<s2Z/s!ZLsrr>1Z!!&elrrVp3mt+Mj<.\)$<97'h;,gCg:ejb]:JOSU9M.qU +9En*Z8k_iI8,G[^3\hU#4$,hk5!M:tr^6ZR"%WC+5l:QaPYjPb^\e$4BUAaN7Y4+# +7Y3qK5ljABqEY0I4[&a+!BiRE4V9e>4?>M_3]B#W4$#,8-9F:Wr]U?I5PdVIs8Qc! +o)Ag43<0#15LhuM5(YtM54UlB4#8W3,rf7*p#lPYs7[r!o`#'_0\?@)K'7gMK'7gM +`omXq3[Pak3+#APkl1S`cR>.RrrTYX\,QDZk^r#Mk^r$<kQaL:-5n0i?VL.VrVlug +BK4W?rr_Fl8E]sOK'7gMK'7gM`omXq3[Pak3+#APkkkAea!`WkLVJn"5T$-js+9Hd +k^r#Mkf2fk6olY5,rf7*p#u5O#1%dD5]D4fq>^6R!!'dt!!%W7K'7gMPir??3[Pak +3+#AVkkkD_kQ'fHmcaQKr9+7`kQ'fHo&p&RroaC`kQ'c/!!)u]!!)lZ!!%W7K'7gM +Pir??3[Pak3+#AVkPtVZkPtVNkPtVXkPtV^kPtVRkPtV^kPtVDkPtV]kPtVZkPtU7 +k^r#Mk`k996olY5,rf7*qre"[r9+7`kQ'i1rW)QR!!)o[r;Zo_!9jC^o]Q8TroaIb +kQ'i1rW!5fkQ'i1!9iVHo]Q8TrTF:_kii!G"6eqKkktL5k^r#MkaCW>6olY5,rf7* +qrmqX"m>sM!9aF^kPtVTkktJ_ki`$GkQCnL!9aFQkQ_+O!9iVHkQ(VG#QX&gki`$1 +kQ(8=qZ$Z\!<20b!9aFH!<20^!.sEdk^r#ekQaL:-5n0i?VL@\!!)r\!s%NbkkkGQ +kPtV\kPtV^kQCnL!9aFQkQV%N!9iVHkkkDckQ'fHkQ'fHo]Q8TrTF7^kkkD_kQ'fH +roa=^K'7gMK'8Ze#=LU")C7@M9`+#R!;u$`!9aFH!:]1P!;u$\!<20b!9aFH!:f7X +!9aFHkQ'fHr9+=bkQ'fHkQ(8=!!)u]!W_Ear9+1^kQ(VG!!%W7K'7gMRcjuE3[Pak +3+#AVkPtV\kQCnL!9aF^kPtVTkPtV\kPtV^kQCnL!9aFPkPtV^kQ1bJ!<20a!9iVH +roa=^oB6/SrTF:_kQ(VG"9@WckQ(VG!!%W7K'7gMRcjuE3[Pak3F>JWkPtV\kQCnL +!9iYG!;#FP!!2<Ir;[#b!9iVH!:o=R!<20`!9iYG!<20^!<20^!;#CS!<)*_!9iYG +!!DHK!9j@]K'7gMK'8Wd#=LZu)C7CN9T\H<!.sEdk^r#akQaL<+rVaf?VL@\qZ,sG +qZ,mEqZ,aAq>g?T!!%W7K'7gMQKSQA4<b[i3F>I3k^r#Mk^r#nkQaL<+rVaf?VH(8 +K'7gMK'8un#=LZu)C7CN9S2J[k^r#MkbI>H6p)Y3,ro=+K'7gMK'7gMUZ_qN4<b[i +3F>I3s+:9&s+:9Grs(qS+rVaf?VH(8K'7gMK'8un#=LZu)C7CN9S2J[kecQKs+9Hd +kkXEI6p)Y3,ro=+K'7gM_W^:bK'7gMq</&O4<b[i3F>I3k^r$8kj&2"k^r$okQaL< ++rVad?VH(8K':)8qYpWcT2>MP!_A[@qYu02K'<$o#=LZu)C7=L9S2J[kecQ\rr\#n +@'BRE"Li%]Gk_.9K'7gMq</&O4<b[i2d]71k^r$8kl(M`f/S$Lq>UMO0ZX.lK'7gM +q</&O4<b[i2d]71k^r$8kl1S`V_H0brrUe3L]7=*k^r$okQaL<+rVad?VH(8K':)8 +"TSMb..?d-"$jX$s+9HdkkXEI6p)Y3,r]1)K'7gM_WV+%s%'Wirr_.,p]#j/K'<$o +#=LZu)C7=L9S2J[kecNbs.<]grrRt#s+9HdkkXEI6p)Y3,r]1)qWNOVK$MK`!rj,# +r;Qb=r?VGRqYpR=htcJfcAKmIchci16p)Y3,r]1)qre(+d":J5kfW)i^Hh_s#BTqG +4='t-A,H9,G_c.Z!RB&Dk_nX*dE_XQ#=LZu)C7=L9`4)Tcd7:-K':>?!IoUsrs)CI +PlLb\!'L/Y!OkVskQ0#VK'8'T!R]6kkQaL<+rVad?VLC]!7$2[K'3=#jPJYOg?R2h +@%[5o"2@\54T#-Za#Nt[!7$2[TBH@;hV7n\rmh#%"5DVfjSe9Bchuu36p)Y3,rT+( +r9+.+K'7gM"R+_#N_@VN!Ec8trs.\.,p`O;!'L/Y!T,$skQ&n[kb%&@hVaDeoe6J5 +J)fPekQ&p+kQaL<,8qjd?VLC]!7$2[K'3@$gl?O$c2RfXQi-jg,lg&]b_6$Zqu6]3 +5l9aFc@Y8PkQ9P"8+Y^A7ul[/kQ&p+kQaL<,8qjd?VLC]!7$2[K'3=#ge5i7rW.e! +rVm/I!%$e-s'l$kqu6]#;#BGVc@Y8PkRuZDd*P)*6-qpE6-qpE6-qpE9DmuRcMZl2 +6p)\4,rT+(r9+.+K'7gM!pJAmrqt(=!QR1urs6gK!0mMY,lf7grrHN"qre%*K'8ij +"PYWV62^HR"4#4Hli$#IcMZl26p)\4,rT+(r9+.+K'7gM"6eMoqTSa:s!ZLtrs(Xd +!$qV-!%%RC!r!Q#qre%*K'8ij"5GTSc1Ul75KkhJrTF7,r9+AR4<kaj2IB/UkQ&n[ +k^r""khIl8pB(B05lCWeF?F'Js+Q0urVlq4QiHsH!7$2[TBHC40Zc6HpB:34atW2\ +kQ&p+kQaL<,8qjd?VLC]!7$2[K'3:"gb?qE"98C7Qh(.Ya#O,!qre%*K'8ij"5GTN +a7f0/oJFWCm/?,JcMZl26p)\4,rT+(r9+.+dHCT2!:/hL!!)3G!!&>KquHNU!<<,r +kQ(Y`lf\B)0['+ls8VgAht6pOmkEAns82![cFW3?!!(O4!<<,ikQ(Y`gZSY<!7L'5 +gb?Z&rUp*hrq-Ed_o"1prTF7,r9+AR4<kaj2IB/UkQ&p&kkbA=kQ(Y`nE9lQ!<20_ +!!)3G!!)o[qZ,O;!<<,ZkQ(Y`qWReVp#lPZ!9iVH!;Pa]!!)6H!!*#^!<<,ckQ9Nn +p%n:]!!*#j!!)BXquH?\rr3&G.$sZ-!k0Serr;lZ!7'KcqZ,gC!<<-!kQ(Y`l0/!E +o&p)S!:f7R!!)BLqZ-?R!<<,JkQBTo_86-C$ig;"oDem`o^aoU0^Sc%!7(N+#=L[! +)C7:K9`4)ScM6T(!!)u]!<<,GkQ(Y`j6-ICqWIq[!<20_!!(s@!<<,ZkQ(Y`qWIq[ +!<20_!!)`V!<<,hkQ(Y`k3)m%0_P;7rW!#loDn:N!<<-!oDnplo^r+^"7Kn_fD>LL +k?pjDrVucY!7'Kc!<<-!kQ(Y`ki`$I!9E>E!!)HN!<<,RkQ(Y`roa@_!;G[X!!(I2 +"5GTH2#d+U!!)Z`!!)Z`o>/6sm/?,JcMZl26p)\4,rT+(r9+.+puh_Y!<)*f!!)3_ +!9aC_kihmDroj:\"R,%L!9jC^"R,%L!9j:[roj:\!U/bF!!MKc!9iYE!!MNL!!)6^ +!;G[W!;bm[!!)u]!rr>bkkkD`ki`!Hkl(S\kktJdki`!HkPtVHqu?`\qu?`\rW)r] +qu?l`kPtVHrVuu_kkkGYkQ(Y`rTF=`!9iYE!!2<Ir;[&c!!)3_!9jC^"R,%L!9j=\ +"R#gckihpE"R,%L!9jC^qWJ%:0_G#7oDJXko)SCRr;[/qo)Jd^!!)Tj!<)Ki!!*#i +#QOkr!!)TjoCMk[!;$*f$HFPKItte"Im=jCqu?QW!7'Kc!<<-!kQLqdki`!HroaLc +!9aC_kl(SXkkkD_kPtVHqu?`\rW)r]quHWX!<<,tkQ_(fki`!HkihsF#3b7N!9aC_ +roaFa!9iYF!!VTM!!)6Hqu?l`kPtVHrW)iZ!<<-!kQLqdki`!HroaOd!9aC_kihpE +roj:\i919u0YP0so)Sgkrpp9`1qk[1rTF7,r9+AR4<kaj2IB/UkQ&p'kQ(Y`rTF:_ +!9j=\!pBUaroaIb!9iVHroaC`!9jC^#3b7N!9aC_r9+7`!9iVHroaLc!9iVH!<20b +!!)3_!<20`!!)6^!!DHK!!)iY!!)iY!<<,ukQCkckPtV^kQ1_akl(Pdki`!Hki`$G +kQ1_akkkD_ki`!Hroaaj!9iVH!9iVH!9aC_roaC`!9jC^#O(@O!9iVH!;bm[!!)u] +"98Gc!!*#^$31(ikPtVHkPtVHrW!;hkPtVH!!)6H!!*#^"98Gc!!*#^!WW5arW!&a +kPtV[kQBTooCMkM!<D]h!"\W#!:o[\!:g*inc/[\!!)ug!<<-!ncAdko)/Onnc/[\ +nc/[\q>UZFIs=4tJ%tgZqre%*hrk(@!<20c!!)6H!!*#^!WW5arW!&akPtVYkQ(Y` +roajm!9aC_ki`!Hki`!HkPtV^kQ(Y`r9+.]!;u$d!!)6H!!)3_!<20d!9aC_kPtV^ +kQCkckPtV^kQV%N!!)3_!<20`!!)6^!!DHK!!)r\!<<-!kQLqdki`!HroaRe!9aC_ +kPtV^kQCkckPtV^kPtVAkQBTo\ki7p!<<,unc\Ko\hNLLkQ&p+kQaL<,8qjd?VLC] +!7(B'!<<,ukQCkckPtV]kQ(Y`roa@_!;ks_!!)3_!<20b!!)3_!<)*^!!)lZ"TSPd +kPtV^kQCkckPtV^kQCkckPtV^kQ(Y`q<.eYq<.hZ!<)*a!!)3_!<20b!!)3_!<20_ +!!)o["98Gc!!)r\!<<-!kR7Fkki`!Hki`!HkPtV^kQCkckPtV^kQLqdki`!HqWIq[ +!<)*a!!)3_!<20j!!)6H!!)6H!!)3_!<20f!!)3_!9iVH!<20b!!)3_!<20b!!)3_ +!<20_!!)o["5GU%oDA([!:o^[!!)Te!!r,q!:g*inc/[gnc8^jrpg0l!:g*irpg3m +!:o[\!;c6hna,?km/?,JcLg<#cJRj_!<20_!!*#^"98Gc!!*#^!WW5aqu?i_kPtV^ +kRRXnkPtVHkPtVHkPtVH!!*#^!<<,tkkkG[kktJ`ki`!Hr9+7`!9aC_roaC`!9jC^ +rTF@a!9aC_roaIb!9aC_roa@_!;u'X!<20_!!*#^#64bf!!)3_!<20`!!)6^!8coA +gb?=Nr:0jg!<)HknPHeNm/?,JcMZl26p)\4,rT+(r9+.+puh_Y!<)*a!!)3_!<)*^ +!!*#^!rr>bkkb>]kPtV^kQCkckPtV^kQ(Y`rTO+Y"6eqK!<20b!!)3_!<20b!!)3_ +!<20_!!)lZ!!)fX!<<,ukQ1_akkY8\kPtV^kQ:ebkihmD!pBUar9+.]!<20h!!)6H +!!)6H!!)6Z!!;?a!<20c!!)6H!!)lZ!<<,ukQ1_akkY8dki`!Hki`!HkPtV^kQh.g +kPtVHkPtV^kQCkckPtV^kQCkckPtV^kQ(Y`qre.;0_=o5nc/[hncSpmnc/[fo(`:a +nc8^jrpg0l!:g*irpg3m!:o[\!;c6hna,?km/?,JcLg<#cJRgg!!)3_!<)*^!!*#^ +"98Gc!!*#^!<<,qkQ(Y`roadk!9aC_ki`!Hki`!HkkY;WkQ(Y`qWIq[!<20_!!)r\ +"98Gc!!*#^!rr>bkktJcki`!HkPtV^kQCkckPtV^kQ(Y`r9+7`!9aC_rTF7^!<20c +!!)3_!9j7Z!U/bG!9!&Cgb?0>p@8@V\$e!WrTF7,r9+AR4<kaj2IB/UkQ&p'kQ(Y` +rTF@a!9aC_rTF7^!<20b!!)3_!<20b!!)3_!<20f!!)3_!9iVH!<)*^!!*#^"TSPd +kPtV^kQCkckPtV^kQCkckPtV^kQ(Y`qWInZpuh_Y!<)*a!!)3_!;ks\!!*#^"98Gc +!!*#^"98Gc!!)r\!<<-!kR7Fkki`!Hki`!HkPtV[kQ(Y`roaLc!9iVH!;bm[!!)u] +"98Gc!!)lZ#QOkgkPtVH!!*#^#QOkg!!)6H!!*#^"98Gc!!*#^"98Gc!!*#^!<<,s +kQBToo()\J!!)uf!s%ik!;l9i!!)QZ!!)re!<<-!nH8glnGiRgnHAmmnaQSZqXF^X +lf9bdrTF7,o]Q;#hrk4D!9iVH!<20_!!*#^"98Gc!!*#^!<<,qkQ(Y`roajm!9aC_ +ki`!Hki`!HkPtVWkQ(Y`qrmtY"6eqK!;u$`!!)3_!<20_!!)u]rW!,c!!)3_!<20b +!!)3_!<20_!!)r\"TSPdkPtV^kQ(Y`roaRe!9aC_kPtVXkl(S@kQBToZa9T"!<<,u +nHA>`ZS:bEkQ&p+kQaL<,8qjd?VLC]!7(B'!<<,ukQCkckPtV]kQ:ebkii!G!pBUa +roaIb!9aC_roaRe!9aC_kPtV\kQ(Y`roaLc!9iVH!<20b!!)3_!<20b!!)3_!<20_ +!!)o[!!)cW!<<-!kQLqdki`!HrTF=`kPtV^kQCkckPtV^kQCkckPtV\kQ(Y`roaaj +!9iVH!9iVH!9aC_rTF=`kPtV^kQLqdki`!HqWIq[!<20c!!)6H!!)u]$NTDS!!)6H +!!)3_!<20f!!)3_!9iVH!<20b!!)3_!<20b!!)3_!<20_!!)o["5GU$o)%qW!<)Eh +!:fUW!!i&a!!)QZ!!)odqu?ihnGiRfnb`C`nHA@Ij=os!kQ&p#kQ&ockQ(Y`roaRe +!9iVH!9iYG!!;?a!<20_!!)iY!<<-!kRRXnkPtVHkPtVHkPtVH!!)u]!!)r\!<<,t +kQh.gki`!HkPtV^kQh1P!!)3_!9iYG!!29`roaRe!9aC_kPtV^kQCkckPtV^kQ(Y` +r9+.]!<20e!!)6H!!)6HrW!,c!!)3_!<)*_!9aF^kQ(Y`iTLC!0XFjYnGrUirUC$[ +['MIQrTF7,r9+AR4<kaj2IB/UkQ&p&kkb>^ki`!Hr94+["R#gckihmD!pBUaroaLc +!9aC_kkb>\kihmDroj=]"R#gckihpE"6eqK!<20_!!)o[!!)cWqZ-TYqu?c]kkbAZ +kkb>]kPtV[kl(PjkPtVHkPtVHkPtVHkkkD_ki`!Hroa@_!<23]!;u'X!<)-Z!<20f +!!)6H!!)3_!<20b!!)3_!<23]!!MKc!9iYE!!DHK!!*#^!<<,skQBTonaXuq!<<,r +n-&4Fj"TiukQ&p#kQ&ockQ(Y`rTF=`!9iYG!!VQd!9aC_roa@_!;PdW!"\8n!9aC_ +ki`!Hki`!HkihpEqrmnW#j;6gki`!HkihsF"mG.M!9iYG!!MKc!9iYF!!VTM!!)6H +qu?i_kPtV^kQ(Y`r9+.]!<)*`!!)6HrW!2e!!)3_!9iYE!<23\!9!&Cgb>t9p@&4R +@'D?OrTF7,r9+AR4<kaj2IB/UkQ&ohkQ(Y`_<:k!jlc^F!.sD<kigeUnaY)tr;cZ_ +"RkX90^Sc%!7(6#!7$2[TBHC40WeaVn-&3^XYB,?kQ&p+kQaL<,8qjd?VLC]!7'im +!!)u]!<<,9kPtVEkQ(Y`K'3C%khIl]nAju#mci^bm/?,JcLg<#c@Y8PkQBToX/bm^ +"R]!a0^Sc%!7(N+#=L[!)C7:K9`4)ScKOKi!2J`Y!!%W7"6et(0ZEJ`mH<F^mJZ5K +cLg<#c@Y8PkQBToW(m!S"RW.f0^\i&!7(N+#=L[!)C7:K9`4)Sc@Y83kQ9u'0ZE;[ +kMb2MmJZ5KcLg<#c@Y8PkQBToW2TFT"QrLX0^\i&!7(N+#=L[!)C7:K9`4)Sc@Y83 +kQ^8,5fDO8h9+RXh:pPm5k"[8!7(6#!7$2[TBHsE5c@DU9rLdb9rLdb9rLdbW'KhM +kQ&p+kQaL<,8qjd?VLC]!7$2[K'3@$hgT:?a3Xt8[:Y'_rTF7,o]Q;#K'8ij"5ePt +G4^Lj7t^F3kQ&p+kQaL<,8qjd?VLC]!7$2[K'3@$jQM_!`\7K[K_"d6kQ&p#kQ&n[ +kb%&@jQM_!oe6J5K_"d6kQ&p+kQaL<,8qje?VLC]!7$2[K'3C%kj7g1o]>c.q#9pg +p@e1FrTF7,o]Q;#K'8fi"75OKo_eC]q#9pgp@e1FrTF7,r9+AR4<b[i2d]8VkQ&n[ +k^r$/kQ&p#kQ&n[k_J@%cMZl26p)Y3,r]1)r9+.+K'7gM\`a%>o]Q;#K'8!R!71T, +#=LZu)C7=L9`4)Tcd7:-K'9i1!R]6ckQ0#VK'8'T!R]6kkQaL<+rVad?VL@\!RB&D +k^r$3kQ0)Vo&p,"d":J>kQ0)Vqre8Q4<b[i2d]8Tk^q*3cFhF&cg^.McAKmIchci1 +6p)Y3,r]1)K'7gMK'7gMUZ_qN4<b[i2d]71k^r#Mk^r#nkQaL<+rVad?VH(8K'7gM +K'8un#=LZu)C7=L9S2J[k^r#MkbI>H6p)Y3,r]1)K'7gMK'7gMUZ_qN4<b[i2d]71 +k^r#Mk^r#nkQaL<+rVac?VH(8K'7gMK'8un#=L[!)C7:K9S2J[k^r#MkbI>H6p)\4 +,rT+(K'7gMK'7gMUZ_qN4<kaj2IB.0k^r#Mk^r#nkQaL<,8qjd?VLC]JsV(U\!M^1 +K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-IqYpd!q!ctH +aRk)aK)`mk!1/<$K';dh#=L[!)C7:K9`4)SQi$dhrpAIln&MTRnc".?K)`sm!1/<$ +K';dh#=L[!)C7:K9`4)SQi$diq;BrLnB%i@b3o7\s+:9nrrAC;k^r$hkQaL<,8qjd +?VLC]!13T_$N8oDeaLP]Zan``K)^H&b5VI.K'7gMo&p<H4<kaj2IB/UkQ$tGrsI]G +g[N._ZEqEgon*3qs3(EBQ\+FQkjmpB6p)\4,rT+(r9+-IqYpu_oC)=l\&-G3ZHhq; +qZ$Npp\t6o!.t6&s5X+ZQ\+FQkjmpB6p)\4,r]1)r9+-Iqu7-!iVNEEd`KAF`Nutt +meZt_!.t6&s4@8NQ\+FQkjmpB6p)Y3,r]1)r9+-IrVmE%mHEL)qXi"OZEq3NZa\'R +rt,52rr<'!rr<'!rr<'!!!*'!r;_HLK)b*8!1/<$K';dh#=LZu)C7=L9`4)SQi6pp +gX4<rqYK`q\uiHR[Bm3Cqu79/!<3$!s8N'!s8N'!rr<'!!!%WNK)b!5!1/<$K';dh +#=LZu)C7=L9`4)SQi6pp^q7(lqYK]l[^3NS['R*Lqu6d!!<3$!rr;os"TSK%!<;ut +K)^H&kl1XLmHB/IPg09Tp#lWK4<b[i2d]8VkQ$tJrt!#Q[Cc%umC0F2]!o#PZ-<.G +q>^Qrs8;p$s8N'!s8W#tK)^H&l2LaMmcX\sd":JHkQ0)Vp?2`L4<b[i2d]8VkQ$tJ +rt!J_ZF/9"k-qY#Wi3),ZJGHY!<<-!rrE*"rr3!!!<3!!!!)ut!<<+Os+::8rrADS +kQ0#VK'8E^!R]6fkQaL<+rVad?VLC]!13Za&)=Cp['5AA^:^:pI$U\@kPY>\!!*#u +!<<-!rrE*"rr3$"!<;utK)^H&kl1XLn)sbsrTF=DhV7,FkLKRc"5DVfjS\4pQi-(- +VZ?bqkQ&s'kQaL<+rVad?VLC]!13Za&(I\m^nl51guG2R?YG(pl%8qes3:QDQga,< +cMcr/hVaDea=m]]J)fPdkQ$s(rrAD`kQ%OBD?92*rTF7,pZMiM4<b[i2d]8VkQ$tJ +rstZuh;PV\htlr+F]`<fG0Y^>K)a*q!130<!7(Q,"5JoZbfKedgi\Y<r9+-ILAq7? +r9+0ZDWh$$aR9*,kQ&p&kQaL<+rVad?VLC]!13Za%t:M;m^%,eoA,I;:L.7+Y(H\* +s3:QDQga,<cMcr.ge5i2rW<&@9DdoQQ\PM?Qi-%JVf(_u"3AROs8D-]cM-N-6p)Y3 +,r]1)r9+-IrVmD#HZYIGDm$9m?"&/%M2fu9s+:9qrrADSkQ&p,kQ0Elrqsn8"8_XD +lhorHQeDB=!3cD&Qi-%LVf)P7lKA>kaR9*,kQ&p&kQaL<+rVad?VLC]!1/<;K)`C] +!130<!7(Q,!o,L+a8#i0mP+#*kQ$tIs8;rbs8;rorr<&&rrAD`kQ@`#s8VBJ"3ARO +s8D-]cM-N-6p)\4,r]1)r9+-IqYpd!q!ctHaRk)aK)`mk!130<!7(Q,!SfBLpB:3[ +l7hT&kQ$tJrr<&arr<&mrr<&&rrAD`kQ@`#s8VBJ"3AROs8D-]cM-N-6p)\4,r]1) +r9+-Iqu7!%mG$7]a0*STrdt0%s2k9@Qga,<cMcr-gb@@Q!<<,to`5$mqXk!`n)uIl +r9+-Irr2ruqZ$Nprr;rt!WW3!!!<3#!;c`p!!N?%!<<)u!4;b+Qi-%LVf)P7roj=\ +#NUn=/MTtVhu3TRkQAoImf37L!7(?&#=L[!)C7=L9`4)SQi$diq;BrLnB%i@b3o7\ +s+:9nrrADSkQ&p,kQ0HmiV!0MqXjjh!;uKj!!)lg"SD0H0^S`$!13]b!!)or!!*#u +!W`6#q>UKrrrDrr!!*#u!W`6#r;Q`s[Jp5nr9+6\DZBb9kR[^nqN!6aDO6T53%9UX +s8W&]"3AROs8D-]cM-N-6p)\4,r]1)r9+-Iqu7$%i8iGWa0)bZf_C'uK)a!n!130< +!7(Q,!o,L&n+6V\!;?'a!;c<g!!)rh!<<,roE=dRk:l9#kQ$tKrr<&rrr<&urrN3# +!;ulq!!3*"qu6Wrrr3*$rrE*!r;a8*!13WI"/g&:s8M3cs8?a^K(Am?"o4W@?Ma^# +kQAoImf37L!7(?&#=L[!)C7=L9`4)SQhp^hi8r__`2p8N_T2>$s+:9orrADSkQ&p, +kQBToo^qSC!<<,qo)o$no)JdioDARhoCMk[qXXj\mH-+hr9+-Irr2ruqu6Wrrr3$" +rrE#t!!*#u!W`6#qu6Wrrr3*$rrE'!rr2ru[Jp5nr9+6\DZBb9kQLpF-S)_'rr^4p +JcG]4"3AROs8D-]cM-N-6p)\4,r]1)r9+-IqYpu_oC)=l\&-G3ZHhq;r;Qct!<3!! +!!)Zk!<<+Os+::7rrADSkQ&p,kQBTooCM>>!<<,sne2!'nc/[\nc/[\nc/[\!!)T\ +!!)ld"S(j?0^S`$!13Za!!)rs!!*#u!W`6#rVlitrr3'#s8N)srr<&urr`?%!<3&u +rr<&,rrAD`kQ@`#s8W)^"l_(c9e<aLrrT,Je,AJ4aN3fLrTF7,pZMiM4<kaj2d]8V +kQ$tHrse\\qYKp6ahl$9ZaJ*Hr;Qct!<3!!!!)Zk!<<+Os+::7rrADSkQ&p,kQBTo +oCMkMr;Zigr;cZa!!)rf'*&%'!!)T\!!)T\!!)Qi!:o[\!;c6hna,?km/6&IQi-m^ +!!3-"rW)rtrW!!!s8;rss8;ous8W&u"TSK%s8W#t[Jp5nr9+6\DZBb9kQZl!o^5L* +[/9k)rC225kQAoImf37L!7(?&#=L[!)C7=L9`4)SQi6ppp?h)%qYKj.`j2q`['R6` +r;Qct!<3!#!!*'!r;['%rr<'!!<;ut!<;rsK)^H&nG`KTn)sbsrTF@=0_4f$nGrUi +r:0U`%IjDunaQSZnGiRZnGiRcnHA@Ij=orukQ$s(rrAD`kQ@`#s8W)^#?>F:s6ic7 +Zhsb'K0]D!"3AROs8D-]cM-N-6p)\4,r]1)r9+-IrVmD_dE^8<qXM81XgbpMZa6k5 +s7u^#rr<'!rr<'!r;Zp!!!)or!<<+Os+::?rrADSkQ&p,kQBTonaZ&:!<<,rn,WLh +rpUEu!:TsgnF-DXn,NIXn,NIbn-&4Fj"TitkQ$s(rrAD`kQ@`#s8W)^!A]E/rr_^e +/$]$P!Mq=FkQAoImf37L!7(?&#=L[!)C7=L9`4)SQi6pp^q7(lqYK]l[^3NS['R*L +r;Qct!<3!"!!*&r!!<0#!<3!!!!)rs!<<+Os+::>rrADSkQ&p,kQBTonaZ,<!<<,p +n,WLhrpU!i!:]LU!!2TYquHT_"RkX90^S`$!1/H?!13WI"/g&:s8M3_0S03&"7T2< +YPnJ%UFQ6+"3AROs8D-]cM-N-6p)\4,r]1)r9+-IrVmDGZF.=9md7Ki\%9&TZa%aP +rrE*"rr3*$!<3$!r;Qct!<3!!!!)ut!<<+Os+::=rrADSkQ&p,kQBTonF4Qg"RbO6 +0^S`$!1/H?!13WI"/g&:s8M3_94e&$"7T8>Y5\G%LHb\#"3AROs8D-]cM-N-6p)\4 +,r]1)r9+-IrVmDTZa.!i_</54Yc=Y)Za/EbrrE*"rr3*$!<3$!r;Qct!<3!!!!*#u +!<<+Os+::<rrADSkQ&p,kQ0Hma6s/ukM\,^r9+-ILAq7?r9+6\DZBb9kQ6Mon,31j +nPq'?s8>K3rTF@)aR9*,kQ&p&kQaL<,8qje?VLC]!13Za&)=Cp['5AA^:^:pI$U\@ +kPY>\!!*#u!rr?$s82iurr<&ts8Duus82kKs+::?rrADSkQ&p,kQ0Hma6EfjiS6-S +r9+-Irr;osmf*7err;osW;cjar9+6\DZBb9kQ9KgLAUuTnl@3>V^TaekQAoImf37L +!7(?&#=L[!)C7=L9`4)SQi6ppe?$9tV0:\Mj.pj*BS3JPK)^H&c2Rd1n)sbsrTFF@ +5fDO8h9=^Zh:pPm5k"X7!13]b!!*#u!!)Bc!!&hp!13WI"/g&:s8M3as+)].qu6ik +=",kGs8D-`aN3fLrTF7,pZMiM4<kaj2d]8VkQ$tJrstZuh;PV\htlr+F]`<fG0Y^> +K)a*q!130<!7(Q,"5eQAX3&]kca@A;oDIePQi@!b!<3!"!<<)u!!3-"r;cisrW!'# +!<3&qs8E##rrAD`kQ@`#s8W)^"onF).ZjK)rrr7\-WBd>rTF@)aR9*,kQ&p&kQaL< +,8qje?VLC]!13Za%t:M;m^%,eoA,I;:L.7+Y(H\*s3:QDQga,<cMcr/jQM_!a=m]] +K_"d5kQ$tKrr<&urrN3#!<3!"!<3&urrN3#!<)p!!<3&rrr<&urr<&%rrAD`kQ@`# +s8W)^&-)\'I474"PEU5R.!G7_s8D-`aN3fLrTF7,pZMiM4<kaj2d]8VkQ$tJrst`K +FH`G;Y-3:[@=<0QNRNLZK)a*q!130<!7(N+"75OKo]Gi0q#9pgp@e1Fr9+-Irr;os +!WW2t!!3*"rr3'#rr<&urrN3#!;lcr!<2uu!3Z>%Qi-%LVf)P7roj=\#Ln2d.k3`* +d/F"CkQAoImf37L!7(?&#=L[!)C7=L9`4)SQ\,6hs1/.0Qga,<cF<!;Qi@!b!;uis +!;uis!<2uu!<3!%!!*$!rrDrr!!*#u!!'2%!13WI"/g&:s6AeMaN3fLrTF7,pZMiM +4<kaj2d]8VkQ$tGrs&JtnCb=moRd*ps2Y->Qga,<cF<!;Qi@!b!;uis!<3!"!<3&u +rr<&trriE&!<<'!r;Q`srr2ruY5\Kgr9+6\DZBb%kQAoImf37L!7(?&#=L[!)C7=L +9`4)SQi$dhrpAIln&MTRnc".?K)`sm!130<!7&(;!13]b!!)orrW!!!s8;ous8W&u +!rr9#rr;os!WW3!!3Q8$Qi-%LVf)P7lKA>kaR9*,kQ&p&kQaL<,8qje?VLC]!13T_ +$MiW5bOEWV[E@q:K)^H&b5VI.n)sbs\**gYo)A[iQN$rOr9+3[DZAn@!Ug!dkQ&p& +kQaL<,8qje?VLC]!13T_$N8oDeaLP]Zan``K)^H&b5VI.n)sbs\**gYo)A[iQN$rO +r9+0ZDW]"@mf37L!7(?&#=L[!)C7=L9`4)SQhp^hi8r__`2p8N_T2>srrE*"K)^H& +rVlkan)sbsrTF=DhV7,FkLKRc"5DVfjS\3AQ\PM?Qi-%IVr[7Gs8D-]cM-N-6p)\4 +,r]1)r9+-IqYpu_oC)=l\&-G3ZHhq;qu?Qoli6k_q>UHq!.t6&s8DrtQga,<cMcr/ +hVaDea=m]]J)fPdkQ$s(rrAD`ki2X@kQ&p&kQaL<,8qje?VLC]!13T_%JJcWqY&@Z +_SsL#[Ee4<rrE*"kl1Y`!;6?m!!%WNK)bfL!130<!7(Q,"5JoZbfKedgi\Y<r9+-I +LAq7?g#rF]pZMiM4<kaj2d]8VkQ$tJrt"hjkhu=6oZY=\Zb3ZO\&nRJ!<<,ss8;rs +s8;ous8W#t"98B$!;lfp!!WE&!!*'!r;_HLK`;%=n)sbsrTF=<9?YBT!r^87qre$H +LAq7?g#rF]pZMiM4<kaj2d]8VkQ$tJrt!l3cID^en\)N9\%B&SZ`j<,!<<,trs/T) +s8N'!rr<&prr`<%rr<&srs/T)s8N'!rr<&srrE*"K)^Q)!130<!7(Q,!S]=-r5ng< +qXcK-r9+-ILAq7?g#rF]pZMiM4<kaj2d]8VkQ$tJrsuoW\&%q;n@?!6\[]#QZap#6 +!<<,trs/T)s8N'!rr<&ss82iurr<&srsA`+s8N'!rr<'!s82kKs+UIQQga,<cMcr. +gbATFq#g9W0^S`$!1/H?!12C&!7(?&#=L[!)C7=L9`4)SQi6pp_m6\^oBu"TZa[NT +Za6p\r;Qct!;uj&!!*'!!!*$!!<)p'!!*'!!!*$!!;uj-!!*'!!!*$!!<3$!s8N'! +K)^Q)!130<!7(Q,!SfBLpB:3[l7hT&kQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13Za +&(%Yg[FW1V\$E6<W33J4h>I9R!!)rs#QOl)rr<'!!!)ut#QOl)rr<'!!!)rs%fcV0 +rr<'!!!*$!!<<'!!.t6)rrADSkQ&p,kQ0Hmde*V@!;Q3io^Cutm/6&IQ\PM?QeCR& +cM-N-6p)\4,r]1)r9+-IrVmD`Yd1X?Lto_WV1X/]Vn)!fs82its8W#trr;os!WW2t +!!3-"qu?cts8;p$s8N'!s8VusK)^Q)!130<!7(Q,!SfBfp&"gao`5$mq"4d^n)uIl +r9+-ILAq7?g#rF]pZMiM4<kaj2d]8VkQ$tJrt!V\]>17dh;%%dG$ep8Y3CQ<K)a*q +!130<!7(Q,!o,L&o(2q_!;#gd!!)Z`!!)fd!<<,poE=dRk:l9#kQ$s(rrAD=kQ&p& +kQaL<,8qje?VLC]!13Za&"TWSiN[L^qX]ek=D25gc@Z(Js3:QDQga,<cMcr/gbABm +p%&1a!:fX]!!*#i!rr>moDJXkoCDq^q""XZmH-+hr9+-ILAq7?g#rF]pZMiM4<kaj +2d]8VkQ$tJrssRXipO-seFVLW@o$B9<N^rRK)a*q!130<!7(Q,"5GU%oCqeV!!)KY +!<<-!nd>Etnc/[\nc/[\!!)fb"S(j?0^S`$!1/H?!12C&!7(?&#=L[!)C7=L9`4)S +Qi6ppT6k[DU2R3<IU-B1Ef#e)K)^H&c2Rd1n)sbsrTF@=0_=o2nc/[do)/Ogo)/Re +nc8^jrpg*j!:p!e!qH<kq!nRXm,]qfr9+-ILAq7?g#rF]pZMiM4<kaj2d]8VkQ$s$ +s+:9]rrADSkQ&p,kQBToo()PF!<<,gnGrUirp^*k!:^$hr:'df!;Q'enE]-hm/6&I +Q\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMh!p:/=PBK)^H&ec,W9n)sbsrTF@=0_+]+ +n,WLhnaHhb!:]IX!:]IX!;u<e!!)f`"RkX90^S`$!1/H?!12C&!7(?&#=L[!)C7=L +9`4)SQg4SR/2K(23.h0^s4.,LQga,<cMcr/gbA9goC)b\!;#^X!<)Eb!!;Wi!;Q$d +n*8pem/6&IQ\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMh,A2)Qj=Mi*CJK)^H&g&D&= +n)sbsrTF@=0_"SRmf`(Ci\9`skQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13!N%kTXr +.:.^^F)(aTpo('eUk8Vus5<nWQga,<cMcr-gb?e;"RYC20^\f%!1/H?!12C&!7(?& +#=L[!)C7=L9`4)SQg4S]/N#C5Kp%U<C]FBg^qd:0K)^H&i;WeDn)sbsrTF:;0ZWG] +kMb2MmJQ/JQ\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0d"s7a@ij0=XB +s8E#prr<&_rr<%Ns,6mWQga,<cMcr1h*Ap8h;-<3"l7qb\j5`^kQ$s(rrAD=kQ&p& +kQaL<,8qje?VLC]!13!N%kTXr-\[_HE,5LJ_;jR\Nr/hV!;ZWp!9jF_!.t6/rrADS +kQ&p,kQB^kBrfA&"OFJfKCf$)!1/H?!12C&!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5 +Kp%U<C]F.Fj5[D)qu6]ts8W#t!WW3!!!WB&rrE*!rW!!!s8;rss8E!!s8W&uK)^i1 +!130<!7(Q,"6A[.9?8dh5_S_#r9+-ILAq7?g#rF]pZMiM4<kaj2d]8VkQ$t7rsp\= +2(+*@P&OiVGJW>"Z&\_]!s&B$!<3!"!<3&urrE*"qu6]trrE&u!W`6#rr3$"rr@ZN +MuNdDn)sbsr9+7LnFQ;7p#l,Lo`Op]p$;P>!1/H?!12C&!7(?&#=L[!)C7=L9`4)S +Qg4S]/N#C5Kp%U*A7oGjj5[D)qu6`us8N)urrN3#!<2uu!<)rr!!3*"rr3!!s82it +rr@ZNMuNdDn)sbs\**gYLAq7?g#rF]pZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJ +B>W]hZ&\_]!s&B$!<3!"!<3&urr<&urr<&urrN3#!<3!"!<3&srr<%Ns,6mWQga,< +cF<!;Q\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=XArrW9$ +rrE&u!W`6#rr2rurr2rurr3$"rrE&u!W`6#rr3$"rr@ZNMuNdDn)sbs\**gYLAq7? +g#rF]pZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJB>W]hZ&\b^rW!!!!<3!&!<<'! +!<3&ts8;ourrE&u!W`9#rW)rt!<<+Os,I$YQga,<cF<!;Q\PM?QeCR&cM-N-6p)\4 +,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=Vrs+::/rrADSkQ&o;kQ$s(rrAD=kQ&p& +kQaL<,8qje?VLC]!13!N%kTXr-\[_HC27Tt_W0[]Ne7:_s5<nWQga,<cF<!;Q\PM? +QeCR&cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=Jns+::/rrADSkQ&o; +kQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13!N%nfYm:ipu.AnPafOe88&m"57hs5<nW +Qga,<cF<!;Q\PM?QeCR&cM-N-6p)\4,r]1)r9+-IK)^H&\c2Yrn)sbs\**gYLAq7? +g#rF]pZMiM4<kaj2d]8VkQ$t7rrf`):J<_=s3Tt]s-<TaQga,<cF<!;Q\PM?QeCR& +cM-N-6p)\4,r]1)r9+-IlMgu<1G^I>oDd2$K)_,9!130<!7&(;!1/H?!12C&!7(?& +#=L[!)C7=L9`4)SQg4SV/N#C815h$IM"gqrk^ri"rrADSkQ&o;k_,;UkQ&p&kQaL< +,8qje?VLC]!13!N%kTXr.:.^^F)(aTpo('eV#LD@k^ri"rrADSkQ&n[k`P'/cM-N- +6p)\4,r]1)r9+-IlMhAH2)Qb8P*0d"s8Ibg^pA^ns3Tt]s-<TaQga,<c@Y8BkQ&s' +kQaL<,8qje?VLC]!13!N%kTXr-\[_HE,5LJ_;jR\NrK%ZkihpEqWInZki`!Hq<3G1 +Q2^iNn)seud":JFkQ0)WpZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P&P4:pVGnMZ&\h` +!pJhJp?2JVki`!Hq<3G1Q2^iNmcX\sd":JHkQ0)Vp?2`L4<kaj2d]8VkQ$t7rsp\= +2(+*@P&P4:pVGnMZ&\h`!pJhJr9++\roa@_kl(PckQ'fHkii!G!U/bG!<23]!!2<I +rW)iZK)_,9!13*:K$KV+!71?%#=L[!)C7=L9`4)SQg4S]/N#C5Kp%U<@=*47j5[D) +rr3#_kktM\kQLtM!9iVHroa@_!;ks]!9aF^kQ1bJ!<20`!9aFYk^ri"rrAC;k^r$h +kQaL<,8qje?VLC]!13!N%kTXr-\[_H?=[\Z_rKd^NrK%[ki`$CkPtV^kPtV^kPtV] +kktJ^kQ(VG!<D?]!!29`q<3G1Q2^iNK'7gMo&p<H4<kaj2d]8VkQ$t7rsp\=2(+*@ +P%ncJB>W]hZ&\h`!pJhJqWInZroa=^roa=^roa=^roaC`kQ(VG!W_Ear9++\q<3G1 +Q2^iNK'7gMo&p<H4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJB>W]hZ&\h`!pJhJqre1` +kQ'i1!<20^!<20^!<20`!9aF^kQ1bJ!<20`!9aFYk^ri"rrAC;k^r$hkQaL<,8qje +?VLC]!13!N%kTXr-\[_HC27Tt_W0[]NrK%ZkihpE!U'O_kQV%NkPtVH!<)-[!!29` +roaC`kii!Groa@_!;ku3s-<TaQ\+FQkjmpB6p)\4,r]1)r9+-IlMhAH2)Qb8P*0Qq +CM1NEj0=XDs3Tt]s-<TaQ\+FQkjmpB6p)\4,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NE +j0=XDs3Tt]s-<TaQ\+FQkjmpB6p)\4,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=L@ +s3Tt]s-<TaQ\+FQkjmpB6p)\4,r]1)r9+-IlMhAf:/4W-H$O"7B4[3tT8Dq6s3Tt] +s-<TaQ\+FQkjmpB6p)\4,r]1)r9+-IfDj4]K)_,9!1/<$K';dh#=L[!)C7=L9`4)S +Qg4SR[8'Lk2hM']s4.,LQ\+FQkjmpB6p)\4,r]1)r9+-IlMgu<1G^I>K)^H&ec,W9 +K'7gMo&p<H4<kaj2d]8VkQ$t7rs1262(CA>MMd4As+::(rrAC;k^r$hkQaL<,8qje +?VLC]!13!N%kTXr.:.^^F)(aTpo('eUk8Vus5<nWQ\+FQkjmpB6p)\4,r]1)r9+-I +lMhAH2)Qb8P*0d"s8Ibg^pA]Gs+::/rrAC;k^r$hkQaL<,8qje?VLC]!13!N%kTXr +-\[_HE,5LJ_;jR\Nr8nW!<)ot!9X=[!.t6/rrAC;k^r$hkQaL<,8qje?VLC]!13!N +%kTXr-\[_HE,5LJ_;jR\Nr8nW!<)ot!9X:]!<2uu!.t60rrADQk^q*Ec2c2`kQaL< +,8qje?VLC]!13!N%kTXr-\[_HE,5LJ_;jR\Nr8nW!<)p!!<3&urrE-"rW!$"!!*#u +rW!!!s8;p!s8N)urr<&us8E#ts8E!!s8W&u!rr9#rr30&rrE'!s8W&u!WW3!!<3#t +!.t6\rrADRkQ/uUK'8K`!R]3dkQaL<,8qje?VLC]!13!N%kTXr-\[_HE++*;_;jR\ +Nr8qS!!3*"rr36(rrE*!!<<'!r;QfurrE&u!W`6#rr3'#s8N)urrN3#!<)ot!<3!" +!<3&urrrK'!!*'!!<)ot!<3!"!<3%Ns0_k,Qga,=cd7:-PNW%pchHW.6p)\4,r]1) +r9+-IlMhAH2)Qb8P*0-^B4Sp?j0=XBrr<&trrN3#!<3!*!<3'!rrE*!!<<)t!!3*" +rr3!!s8;rss82iurr<&urr<&urrN3#!<3!"!<3&urr<&ts82iurr<%Ns0hq-Qga,< +cMcr.jPJYPg?7#cg&p*bhW4UuKU;W#j/2nWrTF7-pZMiM4<kaj2d]8VkQ$t7rsp\= +2(+*@P%ncJB>W]hZ&\b^!!)ut!W`6#rr3<*rrE*!!<<'!rrE&u!W`6#rr3-%rrE*! +!<2uu!;c]t!!*$!rr3$"rrE&u!W`6#rr2rurVlitqYpQr!.t6\rrADSkQ&p,kQB]" +N_@GI"$h@rir&!?Q\PM?Qi-%IVr_dsmf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5 +Kp%U6CMRS"j5[D)r;Q`srVlp!rrE&u$3:)+s8N*!rrE'!rr3$"rrE&u!W`6#rr3'# +s8N)urr<&trrN3#!<3!"!<3&urrN3#!<2uu!<)ot!<2uu!<)ot!.t6\rrADSkQ&p, +kQBV#Fj.r,"5J$ZjS\3AQ\PM?Qi-%JVf(\t!m'g0rTF7,pZMiM4<kaj2d]8VkQ$t7 +rsp\=2(+*@P%ncJB>W]hZ&\b^!!)ut!W`9#r;[0(!<<'!s8N*!s8;ourrE&u!W`6# +rVlp!s8W&u!WW3!!<3#t!<3#s!!3*"rVuis!WW3!!!3-"rW%QM\,QGpn)sbsrTF=< +9?YBT!r^87qre$HLAq7?r9+0ZDWq*&aN3fLrTF7,pZMiM4<kaj2d]8VkQ$t7rsp\= +2(+*@P%ncJB>W]hZ&XG9K)ad/!130<!7(Q,!S]=-r5ng<qXcK-r9+-Ig&D$PYQ"Th +r9+6\DZBb%kQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5Kp%U6CMRS"j5[D) +K)^H&i;WeDn)sbsrTF=<0`&ic"8)"8m/6&IQi-m^!:Bgb!;c]q!;?Hj!;c]q!9jF_ +!9*qXQi-%LVf)P7lKA>kaR9*,kQ&p&kQaL<,8qje?VLC]!13!N%kTXr-\[_HC27Tt +_W0[]MLtk[s5<nWQga,<cMcr-gb?eC"SVBN0^S`$!13Za!!)<a!!)`m!!)`m!!)`m +!!)6_!!)!X!13WI"/g&:s6AeMaN3fLrTF7,pZMiM4<kaj2d]8VkQ$t7rsqat:/H%X +H"L]%AW`UWM<oioK)ad/!130<!7(Q,!SfB\o`5$mr:L'j!;c?ko^Cutm/6&IQi@!b +!;c`p!<3#t!!3-"rW!$"rrDoqrW!*$rrE*!rW)iq!!)rs!!*#u!<E0!!!WB&rrE*! +rW!!!s8;rss8E!!s8W&uj8T+Gr9+6\DZBb9kl(MdjGlnc0hmM^rVui["3AROs8D-] +cM-N-6p)\4,r]1)r9+-IK)^H&\c2Yrn)sbsrTF:;0]D^(!;c?h!!)ri!<<,ro`XpU +kV2B$kQ$tKrr<&rrr<&urrN3#!;ZWr!<3&rrr<&urrN3#!;uis!;ulq!<3!%!<3'! +rrE&u!<<,srrN3#!<3!"!<3&urrN3#!9*qXQi-%LVf)P7roamms8%d/12`GCGrR7- +q>^KnkQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4SR[8'Lk2tR('k^rhmrrADSkQ&p, +kQ9Nnp$_MR!!)`brW)fe!<<,toDnplqXap^mcQ:jr9+-Irr2ruqu6Wrrr3$"rrDus +r;Zlu!;lcr!<3!$!<3'!s8;rqrr<&qrr<&urr<&urr<&ts8;ourrE&u!<E/t!!3*" +iVrnEr9+6\DZBb9kQV"bCaao+rVm&sRkJ+Es8D-`aN3fLrTF7,pZMiM4<kaj2d]8V +kQ$t7rral/1FY<Ts4Z[gs,6mWQga,<cMcr/gbABmmdgGZ!;Z3h!!)Tj!<2Tf!!2]_ +quHTb"S1sB0^S`$!13]b!!)or!!*#u!W`6#rVlitrr3$"rrDrr!!*#u"9AH%rrE&u +!!)rs!!)lq!!*#u!!*#u!!*#u!!*#u!W`6#rr3$"rrDus!!)!X!13WI"/g&:s8M3b +s,ABV\GH4-`A)rDrTF@)aR9*,kQ&p&kQaL<,8qje?VLC]!13!N#V@xxxxxx>MMV$, +g?=.gMuNdDn)sbsrTF@=0_=o&nc8^jqskC#!:g*io'ub\o'ub\nc/[\nc/[dnc\LL +jY6'!kQ$tJrr<&srr<&urrN3#!<)ot!<3!#!<<'!r;Q`srr3*$rrE'!rr30&s8N*! +rrDrr"T\Q&s8N)urr<&urr<&urrN3#!<3!"!<3&urrN3#!9*qXQi-%LVf)P7roaOF +/;$YJ[eg"*W%$3okQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C7?A4)SCB+>/ +W2?Gfrr:^9K)^c/!130<!7(Q,"5GU%oDA+W!!)Tg!;Z0c!;uC$!!)Qi!:o[\!:o[\ +!:g*io'ub\qXOdZm,]qfr9+-Ir;Z]q!WW3!!<3#t!!3-"r;cisr;Zlus8E!$s8N*! +s8;p#s8N*!s82itrrE&u"p"]'!!*$!rVufr!WN0!rrN3#s8E#trrE*"j8T+Gr9+6\ +DZBb9kQZl!o^5L*[/9k)rC225kQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5 +Kp%U<C]FBg^qd:0rr;$B!W_EaqriY3MuNdDn)sbsrTF@=0_4f$nGrUir:0U`%IjDu +naQSZnGiRZnGiRcnHA@Ij=orukQ$s(rrAD`kQ@`#s8W)^#?>F:s6ic7Zhsb'K0]D! +"3AROs8D-]cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0d"s7a@ij0=XDrrM?Ir;c*G +!W_EaqriY3MuNdDn)sbsrTF@=0_+]$n,WLhqX=Lc!<2Hu!!)Kg!:]IX!:TsgnF-DX +qX=XVlJjSbr9+-ILAq7?r9+6\DZBb9kQ*Gnrr3)h;(JpLrrJrHrTF@)aR9*,kQ&p& +kQaL<,8qje?VLC]!13!N%kTXr-\[_HE,5LJ_;jR\NrK%[ki`$GkPtVJkQ1bJ!;ku3 +s,6mWQga,<cMcr/gbA9gnF-GY!;Q$a!!*#f!rr>jnGE7enF6>UqX=XVlJjSbr9+-I +LAq7?r9+6\DZBb9kQ*AgrVluh;C\mKrrJlErTF@)aR9*,kQ&p&kQaL<,8qje?VLC] +!13!N%kTXr-\[_HE,5LJ_;jR\NrK%[ki`$GkQ1bJkl(P`ki`$GkQV%N!9aFHkl(Pb +ki`$1!;ku3s,6mWQga,<cMcr/gbA6eamTB#l/FD`r9+-ILAq7?r9+6\DZBb9kQ+=f +r;Qlg<%>'MrrIm=rTF@)aR9*,kQ&p&kQaL<,8qje?VLC]!13!N%kTXr-\[_HE++*; +_;jR\NrK%[ki`$GkPtV\kQ1bJ!<20d!9aC_ki`$GkQCnL!9aF[k^rhmrrADSkQ&p, +kQ0Hma6s/ukM\,^r9+-Ig&D$PgA_3SrrCaP!13WI"/g&:s8M3`LGA8qrs/'o.]i[K +89Xsq"3AROs8D-]cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0-^B4Sp?j0=XDrrM?I +r;ci\r;[)dkQ'fHki`$GkPtV^kQCnL!9aF[k^rhmrrADSkQ&p,kQ0Hma6EfjiS6-S +r9+-Ir;Z]qmJm+bqYpNqpAb'kl2LebrrCaP!13WI"/g&:s8M3`gF@sTrs&$p.B99o +bPgW,aN3fLrTF7,pZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJB>W]hZ&\h`!pJhJ +r9++\roaUfki`$1!9iVHroa=^roaIbkQ'fHqriY3MuNdDn)sbsrTFF@5fDO8h9=^Z +h:pPm5k"X7!13Za!!)<a!!)`m!!)`m!!*#u!!)<a!W`6#g&D&=r9+6\DZBb9kQCj9 +/%,9S"nPeE0m*HokQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5Kp%U6CMRS" +j5[D)rr3&`kQ(PE!!*#^!!*#^!!*#^!!*#^!!*#^"9@WckQ(MDK)^c/!130<!7(Q, +"5eQAX3&]kca@A;oDIePQi@!b!;c`p!<3#t!!3-"rW!$"rrDoqrW!*$rrE*!rW)iq +!!*#u!W`9#rW!$"rrE&u"p"Z'rrE*!rW!*$rrE'!g&D&=r9+6\DZBb9kQV"_>q1s3 +rVm&tO=+!$s8D-`aN3fLrTF7,pZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJB>W]h +Z&\h`!pJhJqrmtYroa=^roa=^rTO4\"R,%LkQ(MDK)^c/!130<!7(Q,"6A[.9?8dh +5_S_#r9+-Irr2ruqu6Wrrr3$"rrDlp!W`6#qu6Wrrr3$"rrDus!!)rs!!*#u!!)rs +!W`6#rr30&rr<'!rrE&u"9AH%rrCaP!13WI"/g&:s8M3ms8Ve@.6;U8PB]2<G4bh7 +rTF@)aR9*,kQ&p&kQaL<,8qje?VLC]!13!N%kTXr-\[_HC27Tt_W0[]NrK(LkPtVJ +k^rhmrrADSkQ&p+kQC2@oCV2<kP5&L"8;H]lhorHQi@!b!;lcr!<3!"!<3&ss8;ou +rrDrr!!*#u"9AH%s8W#tr;Z]qrr;os#QOf(rrE*!!<2uu!<3!$!<3'!!87APQi-%L +Vf)P7roj=\#Ln2d.k3`*d/F"CkQAoImf37L!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5 +Kp%U6CMRS"j5[D)rr;QQ!!)<JK)^c/!130<!7&(;!13]b!!)or!!*#u!W`6#rVlit +rr3$"rrDrr!!*#u"9AH%rrE&u!!)rs!!)rs!!*#u#QXo)!<3'!rrE&u!!*#u"9AH% +rrCaP!13WI"/g&:s6AeMaN3fLrTF7,pZMiM4<kaj2d]8VkQ$t7rsp\=2(+*@P%ncJ +B>W]hZ&8P\g?=.gMuNdDn)sbs\**gYrVlitr;Q`srr3$"rrE#t!!*#u!s&B$!;uis +!<3!$!<3'!!<3!&!<<'!s8N)srr<&urr<&urr<&urr<&urr<&urr`?%!<3&PrrAD` +kQ@`#s8VBJ"3AROs8D-]cM-N-6p)\4,r]1)r9+-IlMhAf:/4W-H$O"7B4[3tT8Dq6 +s4Z[gs,6mWQga,<cF<!;Qi-m^!!3-"rW)rtrW!!!s8;rss8;ous8W&u"TSK%s8W#t +"onT&s8N)rs8;rsrr<&urr<&ts8E!$s8N*!!87APQi-%LVf)P7lKA>kaR9*,kQ&p& +kQaL<,8qje?VLC]!12=;g?=.gMuNdDn)sbs\**gY_#FB7aSu7,r9+3[DZAn@!Ug!d +kQ&p&kQaL<,8qje?VLC]!13Q^#6+Defso,qK)^H&a8Z.+n)sbs\**gY_#FB7aSu7, +r9+0ZDW]"@mf37L!7(?&#=L[!)C7=L9`4)SQi$dhrpAIln&MTRnc".?K)`sm!130< +!7(Q,!p&4mjP&eIrn7J/gtq,ikQ$s(rrAD`kQ%OAmK!:ckQ&p&kQaL<,8qje?VLC] +!13T_$MiW5bOEWV[E@q:K)^H&b5VI.n)sbsrTF@?i/UIO0EXRij5U"#!1/H?!13WI +irAu@!7(?&#=L[!)C7=L9`4)SQi$dirSZben&MT;\_-\/s+:9nrrADSkQ&p,kQBV# +Fj.r,"5J$ZjS\3AQ\PM?QeCR&cM-N-6p)\4,r]1)r9+-IqYpo\jkK:CXKo1La7Y&a +K)a$o!130<!7(Q,!o-Gla8Q/=b"MWq!1/H?!12C&!7(?&#=L[!)C7=L9`4)SQhp^j +iUcO1a1&q2aKj+[rVZ]n!:0Xe!!*'!quD?KK)bQE!130<!7(Q,!S]=-r5ng<qXcK- +r9+-ILAq7?g#rF]pZMiM4<kaj2d]8VkQ$tHrse\\qYKp6ahl$9ZaJ*Hr;Qp#!<<'! +!9sLa!!%WNK)bEA!130<!7(Q,!o,L+a8#i0mP+#*kQ$s(rrAD=kQ&p&kQaL<,8qje +?VLC]!13Za&,,DSi;3<Bbf6rp]X5#Sao)/D!!*'!!!*'!r;Zlus82lrs8;p$rr<'! +!!)orr;_HLK)bcK!130<!7(Q,!SfBLpB:3[l7hT&kQ$s(rrAD=kQ&p&kQaL<,8qje +?VLC]!13Za&)5LWeGB%3]t1>T]="uOYPeD9!!*'!!!*$!!<<'!!<3$!s8N'!rr<&t +rr`<%rr<&srriB&s8N'!K)^H&rVlkan)sbsrTF:;0[fUp!!)fe"SD0H0^S`$!1/H? +!12C&!7(?&#=L[!)C7=L9`4)SQi6pp^q7(lqYK]l[^3NS['R*Lr;ZZp!WW2s!!iN( +!<<'!!<;ut#64]'!<3$!r;Qp#!<<'!!.t6&s8DrtQga,<cMcr-gb@^[quHKa!<<,p +o`XpUkV2B$kQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13Za&&Y]\]CYIX\$NQT\$NEG +bl%JA!!)rs!<<,trs&N(s8N'!s8W#t"oeQ&rr<&srriB&s8N'!K)^H&rVlkan)sbs +rTF=<0_P#/!<<,koE>3po^i+`q"+Re!;Q0hoBtcqm/6&IQ\PM?QeCR&cM-N-6p)Y3 +,r]1)r9+-IrVmDTZa.!i_</54Yc=Y)Za/EbrrE*"r;Qct!;uj#!!*'!!!)ut#64c( +!!*$!!;uj#!!*'!!!%WNK)bfL!130<!7(Q,"5GU&o_%eV!!)Q\!<<-!o)esmoCMn\ +"7u*a!;Q-go'PQnm/6&IQ\PM?QeCR&cM-N-6p)Y3,r]1)r9+-IrVmD`Yd1X?Lto_W +V1X/]Vn)!grrE*"qu?Qo!<;rs!WW2u!!WE&!!*'!qu?cts8;qLs+::KrrADSkQ&p, +kQBTooCM_I!<<,gnc8^jrpgEs!:g*io'ub\nc/[bnc\LLjY6'!kQ$s(rrAD=kQ&p& +kQaL<+rVad?VLC]!13Za&(I\m^nl51guG2R?YG(pl0eQP!!%WNK)aj1!130<!7(Q, +"5GU%oD%kV!;c9b!!)Tg!<)Hh!!*#h!WW5kqZ$]g!!)fb"S(j?0^S`$!1/H?!12C& +!7(?&#=LZu)C7=L9`4)SQi6ppSYt<&Z#nn"o8n)sBOl;3mf*:f!.t6&s5O%YQga,< +cMcr/gbA<ip[J7a!:TFY!!*#g"98Gl!!)re!<<,pnHA@Ij=orukQ$s(rrAD=kQ&p& +kQaL<+rVad?VLC]!13Za%t:M;m^%,eoA,I;:L.7+Y(H\*s3:QDQga,<cMcr/gbA9g +p$_t^!:fOb!!)NX!!)NX!!)rd!<<,pn-&4Fj"TitkQ$s(rrAD=kQ&p&kQaL<+rVad +?VLC]!13Za&"e2jPG2uuYC9bcI<(1(dt7UOs3:QDQga,<cMcr/gbA9goC)b\!;#^X +!<)Eb!!;Wi!;Q$dn*8pem/6&IQ\PM?QeCR&cM-N-6p)Y3,r]1)r9+-IK)^H&\c2Yr +n)sbsrTF@=0_"SRmf`(Ci\9`skQ$s(rrAD=kQ&p&kQaL<+rVad?VLC]!13!N"LV!# +9K.S'K)aC$!130<!7(Q,!SfBLmf`%@i@sZskQ$s(rrAD=kQ&p&kQaL<+rVad?VLC] +!13!N"=u>b.6)qZK)aC$!130<!7(Q,!SfBLl3-;/gbA-nkQ$s(rrAD=kQ&p&kQaL< ++rVad?VLC]!13!N#V@xxxxxx>MMQlaK)aO(!130<!7(Q,"l2G^hVI#3h?D`if=F69 +r9+-ILAq7?g#rF]pZMiM4<b[i2d]8VkQ$t7rsp\=2(;jcKl_#/s7iOiVPJhDK)ad/ +!130<!7(Q,"5eQAX3&]kca@A;oDIePQ\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMhAH +2)Qb8P*0d"s8Ibg^pA]Gs+::/rrADSkQ&p,kQBo0O\<bL"$hP1o_dnQQ\PM?QeCR& +cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0d"s7a@ij0=XBs8E#prr<&_rr<%Ns,6mW +Qga,<cMZl.m-sW=k4Rp4rq-Bep@[bLkQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13!N +%kTXr-\[_HE,5LJ_;jR\Nr/hV!;ZWp!9jF_!.t6/rrADSkQ&o;kQ$s(rrAD=kQ&p& +kQaL<,8qje?VLC]!13!N%kTXr-\[_HE,5LJ_;jR\Nr/hX!<<)t!!3-"rW!-%!<3'! +s8E!!s8W#trr;rt!WW3!!.t61rrADSkQ&o;kQ$s(rrAD=kQ&p&kQaL<,8qje?VLC] +!13!N%kTXr-\[_HE++*;_;jR\Nr/hY!<<'!rr3$"rrE&u!<<,srrN3#!<3!"!<3&u +rrN3#!.t6/rrADSkQ&o;kQ$s(rrAD=kQ&p&kQaL<,8qje?VLC]!13!N%kTXr-\[_H +?=[\Z_rKd^Nr/hY!<<'!rr3$"rrE&u!!)utr;Zlu!<3!!!<;rs!WN.Os,6mWQga,< +cF<!;Q\PM?QeCR&cM-N-6p)\4,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=XArrW9$ +rrE&u!W`6#rr2rurr2rurr3$"rrE&u!W`6#r;Q`sK)^c/!130<!7&(;!1/H?!12C& +!7(?&#=L[!)C7=L9`4)SQg4S]/N#C5Kp%U6CMRS"j5[D)qu6`us8N)urrN3#!<2uu +!<2uu!<3!"!<3&urrN3#!<3!"!<3%Ns,6mWQga,<cF<!;Q\PM?QeCR&cM-N-6p)\4 +,r]1)r9+-IlMhAH2)Qb8P*0QqCM1NEj0=XBs8E!!rrE&u"p"]'!!*$!rVufr!WN0! +rrN3#s8E#trrE*"K)^i1!130<!7&(;!1/H?!12C&!7(?&#=L[!)C7=L9`4)SQg4S] +/N#C5Kp%U6CMRS"j5[D)K)^H&i;WeDn)sbs\**gYLAq7?g#rF]pZMiM4<kaj2d]8V +kQ$t7rsp\=2(+*@P%ncJB>W]hZ&XG9K)ad/!130<!7&(;!1/H?!12C&!7(?&#=L[! +)C7:K9`4)SQg4S]/N#C5Kp%U6CMRS"j5[D%K)^H&i;WeDn)sbs\**gYLAq7?g#rF] +pZMiM4<kaj2IB/UkQ$t7rsqat:/H%XH"L]%AW`UWM<oioK)ad/!130<!7&(;!1/H? +!12C&!7(?&#=L[!)C7:K9`4)SQ\,6hs1/.0Qga,<cF<"jQeCR&cM-N-6p)\4,rT+( +r9+-IlMh!p:/=PBK)^H&ec,W9n)sbsK'8?\!7(?&#=L[!)C7:K9`4)SQg4SR/2K(2 +3.h0^s4.,LQga,<c@Y8BkQ&s'kQaL<,8qjd?VLC]!13!N#V@xxxxxx>MMQlaK)aO( +!130<!RK,Ek`b32dEhRN#=L[!)C7:K9`4)SQg4S]/N#C7?A4)SCB+>/W2?GfK)^H& +i;WeDmcX\sd":JHkQ0)Vp?2`L4<kaj2IB/UkQ$t7rsp\=2(+*@P&P4:reA5(Z\3r1 +K)ad/!13*:K$KV+!71?%#=L[!)C7:K9`4)SQg4S]/N#C5Kp%U<C]F.Fj5[D)r;ZZp +qYpNqkl1V_K)^i1!1/<$K';dh#=L[!)C7:K9`4)SQg4S]/N#C5Kp%U<C]F.Fj5[D) +r;Q`spAY*mkl1V_K)^i1!1/<$K';dh#=L[!)C7:K9`4)SQg4S]/N#C5Kp%U<C]F.F +j5[D)r;Q`sr;Q`srr3!!s8E!%rrE'!s8W&u!WW2u!<3#t!!3-"rW%QMO8f3HK'7gM +o&p<H4<kaj2IB/UkQ$t7rsp\=2(+*@P&OiVGJW>"Z&\b^r;cis"T\Q&s8N)urrE*" +qu6]trrE&u!W`6#rr3$"rr@ZNNW0!FK'7gMo&p<H4<kaj2IB/UkQ$t7rsp\=2(+*@ +P$V[3AAdHfZ&\b^!!)lq!!*#u!!*#u!!)utr;Zlu!<3!!!<;rs!WN.Os,I$YQ\+FQ +kjmpB6p)Y3,rT+(r9+-IlMhAH2)Qb8P*0QqCM1NEj0=XBrr<&qrr<&urr<&urr<&u +rr<&urrN3#!<3!"!<3&srr<%Ns,I$YQ\+FQkjmpB6p)Y3,rT+(r9+-IlMhAH2)Qb8 +P*0QqCM1NEj0=XBrr<&rrriE&!<<'!rr2rurr2rurr3$"rrE&u!W`6#rr3$"rr@ZN +NW0!FK'7gMo&p<H4<b[i2IB/UkQ$t7rsp\=2(+*@P%ncJB>W]hZ&\b^qu?ct!<3!& +!<<'!!<3&ts8;ourrE&u!W`9#rW)rt!<<+Os,[0[Q\+FQkjmpB6p)Y3,rT+(r9+-I +lMhAH2)Qb8P*0QqCM1NEj0=Vrs+::/rrAC;k^r$hkQaL<+rVac?VLC]!13!N%kTXr +-\[_HC27Tt_W0[]Ne7:_s5<nWQ\+FQkjmpB6p)Y3,rT+(r9+-IlMhAH2)Qb8P*0Qq +CM1NEj0=Jns+::/rrAC;k^r$hkQaL<+rVac?VLC]!13!N%nfYm:ipu.AnPafOe88& +m"57hs5<nWQ\+FQkjmpB6p)Y3,rT+(r9+-IK)^H&\c2YrK'7gMo&p<H4<b[i2IB/U +kQ$s$s+:9]rrAC;k^r$hkQaL<+rVac?VLC]!1/<;K)`C]!1/<$K';dh#=LZu)C7:K +9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)Y3,rT+(r9+-IK)^H&\c2YrK'7gMo&p<H4<kaj +2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC]!1/<;K)`C]!1/<$K';dh#=L[! +)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-IK)^H&\c2YrK'7gMo&p<H +4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC]!1/<;K)`C]!1/<$K';dh +#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-IK)^H&\c2YrK'7gM +o&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC]!1/<;K)`C]!1/<$ +K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-IK)^H&\c2Yr +K'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC]!1/<;K)`C] +!1/<$K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-IK)^H& +\c2YrK'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC]!1/<; +K)`C]!1/<$K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+(r9+-I +K)^H&\c2YrK'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd?VLC] +!1/<;K)`C]!1/<$K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4,rT+( +r9+-IK)^H&\c2YrK'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL<,8qjd +?VLC]!1/<;K)`C]!1/<$K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB6p)\4 +,rT+(r9+-IK)^H&\c2YrK'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$hkQaL< +,8qjd?VLC]!1/<;K)`C]!1/<$K';dh#=L[!)C7:K9`4)SQ\,6hs1/.0Q\+FQkjmpB +6p)\4,rT+(r9+-IK)^H&\c2YrK'7gMo&p<H4<kaj2IB/UkQ$s$s+:9]rrAC;k^r$h +kQaL<,8qjd?VLC]!1/<;K)`C]!1/<$K';dh#=L[!)C7=L9`4)SQ\,6hs1/.0Q\+FQ +kjmpB6p)Y3,r]1)r9+-IK)^H&\c2YrK'7gMo&p<H4<b[i2d]8VkQ$s$s+:9]rrAC; +k^r$hkQaL<+rVad?VLC]!1/<;K)`C]!1/<$K';dh#=LZu)C7=L9`4)SQ\,6hs1/.0 +Q\+FQkjmpB6p)Y3,r]1)r9+-IK)^H&\c2YrK'7gMo&p<H4<b[i2d]8VkQ$s$s+:9] +rrAC;k^r$hkQaL<+rVad?VLC]!1/<;K)`C]!1/<$K';dh#=LZu)C7=L9`4)SQ\,6h +s1/.0Q\+FQkjmpB6p)Y3,r]1)r9/a!JsXNElMlJ"K'<$o#=LZu)C7=L9S2J[kecQK +s+9HdkkXEI6p)Y3,r]1)K'7gM_W^:bK'7gMq</&O4<b[i2IB.0k^r$8kkb;\n"3GU +5QXKCkPG41k^r$okQaL<,8qjd?VH(8K':)8qu6bR(gsQH^BD#Z(jPfQs+9HdkkXEI +6p)\4,rT+(K'7gM_W^su"4oMWp\FgjLG6dIs+9HdkkXEI6p)\4,rT+(K'7gM_W_"! +#,a/qs-/5%qYpWK3/@M5K'7gMq</&O4<kaj2IB.0k^r$8kR%:hk:#g!s#^9Dq#:F] +^]4=ck^r$okQaL<,8qjd?VH(8K':)8"98Bl\,QC/49.M=rr_.,p]#j/K'<$o#=L[! +)C7:K9S2J[kecNbs.<]trrP:_4SSjWLNriNk^r$okQaL<,8qjd?VH(8K':)8!rj,# +rVls^!'Gu7,lj_;rrF8"K'7gMq</&O4<kaj2IB/UkQ9i%gOe/:g4IlAeH*EMr;QaZ +rW!'`,ldq?r;QeBLP"`AkkXEI6p)\4,rT+(r9+7>i/UH^0S2"%0EHZQr;R$b!!';( +o/m"!r;Qf,8:p&WkkXEI6p)\4,rT+(r9+7<NciQts+:9orrHN"r;Qg\!'L8\"/>hr +bl.PBa#J\7K'<$o#=L[!)C7:K9`4)Uge5hBrdt-lrW--!r;Qg\!'L8\"3^`Fbl.PB +h]RO7K'<$o#=L[!)C7=L9`4)TgG&X)K):/sbkhESQi-jb49.MCrr^IF!6kEA!P^mO +k^r$okQaL<,8qje?VLC]!o,L+K)(#ob4u'nGl7RC49-],rr[rT-0G1+!O#=Ok^r$o +kQaL<,8qje?VLC]!SfA\pO`.]pAr;or;R$b!!#m?UEon;r;Qe*T7Z9YkkXEI6p)\4 +,r]1)r9+1:0S8ulo`5$me+E_A!;6$a!8@)H!!'b+!rj\#rVls^!+R>S!!+D!rVlrn +)"3(?K'<$o#=L[!)C7=L9`4)TgbA!cquH-W!<<,To`5$mrq-9l!8$lE!!)W`!<<,[ +o`5$mp@SFd!8-rF!!)W`!<<-!o`5$me+EeB^Hhbt#F'qWk&`_-k5>5\BUAaNk^r$o +kQaL<,8qje?VLC]!o,L&lgt2X!9s+V!!(gH!<<,JoDnple+<Y@!;?$c!!([D!<<,k +oDnplht-pL!:oaas8Qc!o)Ag43<0#1k^r$okQaL<,8qje?VLC]"5GU&o^)/M!!)rg +"TSPo!;#g\!<2Tg!!2]_r;ZlioDJ[eo*YNuo)S@^!;#d^!;$*gqXaXc"7lKmoDARg +oDSahoDJ[doDJXqoCDq^oCDq^oCMn\$hF>uo)Jd^o)Jd^oDJXlo)Jd^oDJXioCMk[ +r::F!!:p3^!!)W^!!)Tj!;#g\!;uHf!!`#p!:p3^oDJXioCMk[!;$0iqt'ad!V>p] +!!Vuc!!)W^r;cigr;Zihr;Zul!!)W^r;ZlioDAUWo)Sgko^`4cs7[r!o`#'_0\?@) +K'7gMq</&O4<kaj2d]8VkQBTooCM>>!<<,to)/Omnc/[\nc/[fncSpmnc/[hnc]!n +o'ub\rUTme%IsK!o'ub\nc/[\nc/[enc8^jrpg^&!:g*io'ub\o'ub\nc/[\nc/[g +ndb^#o'ub\nc/[\nc/[\!!)ug$NL1t!!)T\!!)Qi!<)I!!!)Qi!:o[\!:g*io'ub\ +rUTme&Fof$o'ub\nc/[\!!)T\!!)ug!rr>lo)/P#nc/[\nc/[\!!)T\!!)T\!!)ug +!<<,une(p&o'ub\nc/[\!!)T\!!)Qi!<)Hh!!*#h%fcV#!!)T\!!)Qi!:o[\!:KCY +!!)``rr3&G.$sZ-!k0Serr7T6K'<$o#=L[!)C7=L9`4)VgbA?km.(/W!;uBg!!*#h +qZ$Zfo)&Ihnc/[ho(rFcnc8^jrpgKu!:o[\!:g*io'ub\o)/Oinc/[hndPR!nc/[\ +nc/[\nc/[\qZ-TcqZ$Zfo)/Ojo'ub\rUL6p!:g*io'ub\o)/P#o'ub\nc/[\nc/[\ +!!)T\!!)ug!<<-!nd,9ro'ub\nc/[\qZ-Tc"TSPnnc/[hndkd$o'ub\nc/[\nc/[\ +nc/[go)/Oho()YX"7cElo(rCgnc/[gnc8^jrpgR"!:g*io'ub\nc/[\nc/[go)/Og +o)/Ranc/[ao)8Rjmq=]4qYpZ\?qBJZs+9HdkkXEI6p)\4,r]1)r9+7<0_4f$nGrUi +r:'df!<2Kh!!)re#QOkpnGiRZ!!*#g!<<,qnGrUirp^Bs!:fRZ!:^$hnaQSZqsa[e +!<2L!!!)Nh!:fRZ!:fRZ!:^$hq=+Ic!;l<b!!Dc]!!)uf$31(r!!)QZ!!)QZr;[E! +!!)Nh!:fRZ!:^$hnaQSZrUBmg!<2Kr!!)QZ!!)Nh!:^$hq=+Ug!:fRZ!<2L"!!)QZ +!!)Nh!:fRZ!:fRZ!;uBc!!;Zj!;u?i!!)Nh!;u?f!!)uf!<<-!nIGU"nGiRZnGiRZ +!!)QZ!!)HW!<<,nnb`=na!`WkLVJn"5T$-js+9HdkkXEI6p)\4,r]1)r9+7<0_+]" +n,WLhr9s^e!<2Hg!!)rd#QOkon,NIX!!*#f!<<,qn,WLhrpU<r!:]IX!:TsgnF-DX +qsXUd!<2Hu!!)Kg!:]IX!:]IX!:Tsgq="Cb!;u<l!!)NX!!)Kg!<)Bm!!)Kg!:]IX +!<)C"!!)Kg!:TsgnF-DXn,NIXn,NIen,WLhrpU9q!:]IX!:Tsgn,NIan-&dlnF-DX +rpUI!!:]IX!:TsgnF-DXnF-DXqX=Uf!:Tsgr9sgh!:Tsgr9s^e!<)Bf!!*#f%fcV! +!!)NX!!)Kg!:]IX!:]IY!!)Z\q>UZFIs=4tJ%tgZK'7gMq</&O4<kaj2d]8VkQBTo +naYr7qu?ff!!)uequ?cenGE7enF6DW!V#UV!<)Bf!!)uequ?rj!!)NX!!)lbrW!Ju +!!)Kg!:]IX!:]IX!:]LU!;u?a!!r&o!:]IX!:]LV!!Mck!:]LU!!)Ne!!Vl]!!)NX +r;[)ln,NIXn,NIen,WLhrUB^b"RlBknF6>UrU9sj!:]IX!<)Ec!"8;c!!)NX!!)NX +!!)uer;cidqu?lh!!)NXqu?cenGN=fnF6DW"RlBknF6AV#Oq3_!:]IX!:oU[!!)3O +"RkX90^ODTK';dh#=L[!)C7=L9`4)VgbA6eK("<[_!_Eol/FD`K'7gMo&p<H4<b[i +2d]8VkQ0HmK("<[^@)3lkM\,^K'7gMo&p<H4<b[i2d]8VkQ0HmK'IsQ^?PjaiS6-S +K'7gMo&p<H4<b[i2d]8VkQTd-`89>+K&2+9_qkRQgXj#%mt0bTkjmpB6p)Y3,r]1) +r9+7?IVGj7d"9W[cih\&AqT],k^r$hkQaL<+rVad?VLC]"6A[.97ejL0Y]:D5_S_# +K'7gMo&p<H4<b[i2d]8UkQC2@oCRY-iUqftj7rWH"8;H]l[n>PkjmpB6p)Y3,r]1) +K'7gMK'7gMUZ_qN4<b[i2d]71k^r#Mk^r#nkQaL<+rVad?VH(8K'7gMK'8un#=LZu +)C7=L9S2J[k^r#MkbI>H6p)Y3,r]1)K'7gMK'7gMUZ`"P4<kaj2d]7QRf8TQP_,'M +P(JjKP-:#KPl@!WS>&D6,8qje?VJtmrl,&X_SO(a_"kb=^APZr]RmeJ]RmfI]`#GB +^&GeT`QU_4,8qje?VKM:rn@G+rn-hopX];m!S,`re:Q/$dt6&#e)AaUdeqPreC)do +rm_D.gI+.K)C7=L9^D!CkQ'fFkk"!5k547ljFZHEjFZIGjS\'8iW.s9iX"R44<kaj +2d]8Vn+5uCm/cS?qs3k=K'@mOK'@mOjQQ^/kks]AkR$G86p)\4,r]1)rU'dTmI'E; +mJ6)Llg+H5q<@kA!U8j#k^r#Mk^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)L +lg+H5q<@kA!U8j#k^r#Mk^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)Llg+H5 +q<@kA!U8j#k^r#Mk^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA +!U8j#k^r#Mk^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA!U8j# +k^r#Mk^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA!U8j#k^r#M +k^r$TkkXBLk2tji6p)\4,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA!U8j#k^r#Mk^r$T +kkXBLZa8iX6p)Y3,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA!U8j#k^r#Mk^r$TkkXBL +Za9\p6p)Y3,r]1)rU'dTmI'E;mJ6)Llg+H5q<@kA!U8j#k^r#Mk^r$TkkXBMk5YJE +6p)Y3,r]1)mJcDOm.9Q;lM]rLkih9qqrmn>K'%[IK'%[Ii8t%$qr[k=#=LZu)C7=L +9_@ZFl4*"Bkih9qkih9qkih9qqrmn>K'%[IK'%[IiT:.%roO`tZf^DVZfU::4<b[i +2d]8Ulh9W>kl^/5l08*/pZDS>k5OOqk(;`Ik(;aOjq"f)s5gSns5cX2+rVad?VL@] +rp'CFp#u57!TiGAk(;]HjauTGjj`B*jT#8AjT#8@6p)Y3,r]1)kND'mp?2A9nDs]3 +jS.\die$0Aie$1MiWeH&j5T(Yj8%[>6p)Y3,r]1)o&BQ*p##l.hu2Jbhh'a;hh'b< +h\G#)Za8NFZa8NFZa8KD6p)Y3,r]1)o\B,okh:XAK%Yb/K%],9'=5%FfsA$bfsA$b +fL.hG)C7=L9^^O(f(%:Be:Q2%e:Q3-e.hr_eC=NueC4HtdmQ;B)C7=L9\eFsh;d;f +gOe.2g4J%1g=P$dg"=qF4<b[i2bm^Rnk+L%Jjb2YJjcq5#Wsaa)C7=2:.=_<JinWI +JinWIZTJ@L/gD8WYTr-Ong!]LnK[TKiZn"<dNdcrnK[TKJg8;\nfk=`![&C$Jf94Z +Jf94ZS/M +~> +grestore +currentdict /inputf undef +currentdict /pstr undef diff -r 4acc6d51f389 -r b76e86966e7e docs/figs/acm_overview.eps --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figs/acm_overview.eps Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1463 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%BoundingBox: 0 0 1106 631 +% +% created by bmeps 1.2.6a (SCCS=1.78) +% +/pstr + 1106 string +def +/inputf + currentfile + /ASCII85Decode filter + /RunLengthDecode filter +def +gsave +0 631 translate +1106 631 scale +1106 631 8 [1106 0 0 -631 0 0] +{ inputf pstr readstring pop } +image +K)^H&K)^H&K)^H&VuHbSm(WPPK)^H&K)^H&K)^H&K)^H&_Z']3LFD?d!FYAJs-s#g +mt/<E^B!_Ss+:9&s+:99rrL.gjT#<(hh(m!rrLFWJcM;@!=6Gls+:9&s+:9<rrMk= +rW!!JGdm%S"J83b!'#T1Sc8\>JcM5>!.TV#K)^H&K)_5<"F'nH#`%UC")%Z7^OlKW +rr[`N!2kF`T>(F-!.TV#K)^H&K)_8="NLKB.+dV]"7H3iO+RD'rr[`N!8iD.TDnrm +!.TV#K)^H&K)_;>"SX;E#g_T3![%JFK)_GB"+L:Nhh(m#rrN0#ItI]Ps+:9&s-iri +NrT08j8T3X!#YH^s.B;nIfKK+K)_JC!WW4MK)^H&K)^H&Rf<FK!#X_q"HNN_8FM01 +T`5+D!!(o.s.B;m!!%M#s+:9&s+:9>rrN0#B]8sk5lL``3/'U!BSY35rr[`N!8iD. +TDnrm!.TV#K)^H&K)_>?"6TXaTAfeNmmr$1rVut,n"]mbIfKK+K)_JC!WW4MK)^H& +K)^H&S,WTJ!!'LcrrK<QKKoMSrVus9\"s$+IfKK+K)_JC!WW4MK)^H&K)^H&S,WTJ +!!'ccs5*bVcWL/H!-k@?"+L:Nhh(m#rrN0#ItI]Ps.TGnkD+Y=\UOX@n&YM2hZ*Yk +K)aX+"Lf3J!5GE2"+L:Nhh(m#rrN0#ItI]Ps.TGm0S0;6!!$-Brr_-Y!5F-cg]%E> +&-*jIVuHjK!!(o.s.B;m!!%Mbrrqk`Im?71JcM_L"UI@YBRe@Ks+16Z!!#:*rr_-Y +!5F-cgA_8I!!$u9rr[`N!8iD.TDnrm!.Vod!N/bG!1X#j+E6MdrrN0#ItI^4rrPFc +5fis-hZ*YkK)aO("#p8lpSe)oIfKK+K)_JC!WW4M`W#tJ0`:tR#XCY"Jq'\J!a%]1 +r;Zm)E:;$N!WW4MK)`I_!^H`NaSuA"!!'ccs4RDSQN.$+W;csL!!(oprrg)j@q1b, +rrR9gA,H9+g&B4PrrRm:Z1@nr^P/rgrrN0#=SK'#ldGe6ha%/@!si#,pO`F=rrUf% +./j2I&<G*9!WW4MK)`I_!^H`NaSuA"!!'ccs4RDShZ*YSW;csL!!(pFrrV>:PhZ3= +bWPe'!0mE]!6hqP!3uM'"jI#HYrj?2!!4H/UZh^Yk1T_5!0mH_!87#E"Qh!1!5JC1 +!WW3npQbg@e,KWm(]XOIL\HE#S,WN85lL`aB_TjQ!WW4MK)`I_!^H`NaSuA"!!'cc +s4RDSpAb2cW;csL!!(pKrr@cN,m"&HUYYqNfd6Lq!+Z$."MZ5_-/#j/!'L5\!nmV, +pAb4kk3N$LKd?^]rr2tPrVurBo`"p8rVuqPqYpTs!)*'P!9M`1"fDV+!-%CYs-N`h +^E<LV5k!)"!WW4MK)`I_!^H`NaSuA"!!'ccs4I>Q!!&Xirr[`N!8mMM!O3sH!!#mP +rr>pp!!=Mn4PB`6!'L5\!+WV?!5JL5"&]*ubk;#;--Y`U!%%UE"/GnrL&M&Pbk1o8 +Pl:X_L&1fN!!#[dQ2p$srrfM*!!o3Ks-3Neml1:I3;:i#!WW4MK)`I_!^H`NaSuA" +!!'ccs4I>Q!!&Xirr[`N!8mPN!2K8g!'K-<!87;N!JT\5rr>pq!!%,Prr?R.!!C"9 +s31HB"Asl,;'l/@!'KWJ!%%UE"2Fm9L&M&Pbk1o8L&M&PU\aul!!#[dQ2p$trrgXR +!"cnss-!BbpK.Cq=OI-M!!%M#s1A:45QF'jrr_-Y!5HSS!d$Q0p\t<"4JVfR!d$Q" +qu6bn,s9lYrr[?h4QaEY!WW4mW;csL!!(pOrrAhl!!4H/-2mlE4Pp)<Pl:X_A,6-, +fhj%m\c2aX!!#.\rrC:B!!%`Orr@cO!!&e]rr]Mg-$9.d!/:CP!6k*8!/:CP!6k<> +!WW3npQbg@fDc!:+92DNK)^r4"SY.]!/K#&!WW4MK)`I_!^H`NaSuA"!!'dTrrBh5 +!!%`KrrAhn!!(^Nrr[rT!%%OB"!mpI;>gFr,ldq!^]+?8!2$4i"+L:Nhtd9P^\n-< +-*dLMo-FA:;;V<QA,ZH.bc^sGL&M&PPlC[_bl.SBL&CrNL&M&P;<IlYL&M&Pbk1o8 +L&M&Pbkh>@!!#[dQ2p$urr[3?!0;a3NrK7N+92]1e,KIL!.TV#]Dhpt!'nX*"5a(Y +^W?ETg&1mNU\k&kZ2O_'-2dcC-2mlEU](2mbl.SB-2dcF,ldq!^]+?8!2$4i"+L:N +htm?Ro-OA9!@>tgrr]#B4PB6(!p533rVlo\g%bRL49,@-XoAJL!!">DrrC:B!!%`N +rrC:B!!#.Drr@cP!!(7<rrhKHs8Psq!!(7>rrN0#9D=_Pjk0S8cN!rAK)^f0"4$rI +:t,FG!!%M#s1A:45QEA1YlO+<rr_-Y!5HSS!2KMn!@?FtrrM7.rVur5rVllNr;Zh- +rVlkOr;ZiArVlsG!!%_frrN0#T;_blIfKK+qYpP*rVusFbk(i<k*0@<A#&r$$7,ZP +U]6#o,lf6FrVm8fb`jCR!$u_L4AiB^rr^"u4O!X$"jE3bKqmf/rr_CG-"HlQ"6M]l +;?$S&Yu-bcs1`Y<,pe9BrrM8Hr]C6ZPih]>!2KMn!+Z!-!6kEB!/:@N!5JL5!'L8\ +"6M]lA,Q?/juaqerVlqQ4Al(W!/:CP!6k??!M_dU,m@..!!">-qYpTs!)*'P!9Ml5 +"&Jstc[u1TrrZ't!700p!WW4MK)`I_!^H`4pm(pAdf0F,!!'dRrrAhn!!#.[rr>1\ +!!&8]rrA;^!!#.[rr>1[!!&8^rrXPI!/82f!WW4mW;csL!!(pRrrBh4!!&ecrrI3f +qu?a[bl7VBbl.SC4AktU"GQmUUF#U6!87AO"!mpI4T#-ZKdHWs!@<I!rr@0?!!(7A +rr@cP!!gaJjs:!-PYq;X!2KMm!JMis!!+Bfp\t@Y!!">-rVllArVuqPrVlo\4T5<\ +PlC[_FT)7?bl.PAL&M&Sbl@^rrVuq?rr2tPrVurBr;QaZpAb1>q>UKr!)*'P!9Mo6 +"4mMQBS-8Arr_-a!*IbN!WW4MK)`I_!^H`4pm(pAdf0F,!!'dQrr?R.!!>@`s)e5? +!+Yp+!+Ys-!%%UD!%%RD!/:CO"!mpIKtmWh!!&Xirr[`N!8m\R!)`^q!+YX#!'L&W +"=<[>s310:"""!I4S8[Sg&D!R,ldokrVloB-27HB-/&;\rVurBrVljprW!#Ds310: +!'L8\!+Ya'!/:7K!2KMn!+Ys,!6kEB"_5d#P[c$=!!">Drr>1\!!(7Arr>pq!!CIF +s31HB!'L8\!/:CP!6kEA!'KrT!%%I@!WW3npQbg@g&D/(!!(>ss,$aX:]Ldqec,[N +!.TV#]Dhpt!%.K,!9MZ/"5a(Y^Vp-P4T5<]A$Q"5!'L,X!'L/Z"53_S^\e'34T59^ +,ldq!^]+?8!2$4i"+L:Nhu*KSg&:sP-0Fk"!+Yp,!%%RD"(VB2bk_;?;*=gX!mL[u +q>gL@!Bc)7rrXPI!'L8\!SJdt!!4H/4T,6]L&WIu!!(^Nrr>1\!!:CEbkhA@,s;/, +"$HV`Z2FY),s4:9rVupEq>URD!!">-r;Qc@o`+usrVljDrVurOrVlj[rW!&Es8U=B +!!%-?rr@cP!!(7Brr?R.!!FTXKnWD&!!">@rrN0#9D=_Pjk9Y8-ibBAs+p[WT)\kh +ec,[N!.TV#]Dhpt!%.K,!9MZ/"5a(Y^Vp-Qo-OA9"=4$J--Z5c!%%OC"/GnrA,H<, +-2miG,ldq!^]+?8!2$4i"+L:Nhu*KSFT)7?A+]d$^\n-7A(gmHrW!$Hs8U=?!!8qq +bl.SKU]:A/PftER!'L&V"!mpI4T>?\;>pOr4MUmq!0mH_"blt&!!">Crr>1\!!:CE +bkqGIFQWTL!!#.]s#g8\!0mK_!0mH_!%%LA!/:CP!+Yp+!6k-:!@>MZrrXPI!%%RC +!'L5\"3gfFbl.SBL&V)PL&M&Xbl@_*,ldokbl.PAPl:X_-2IQB!!#[dQ2p%#rr^jQ +!-j+qM#RSG#QRuWrrN0#ItI^4rrPFc-MWl,jjO/2hZ*Yk_uBb]-2[`CPktC[bkhAH +A,lQT!!";F!%%UD"!mpIbeO/Z!!&Xirr[`N!8m_S!'L5\!5J1+!+Z!.!)`^p!+Z!. +!l+cZqu?hQs8U=B!!%`NrrXPI!'L)W!6kEB"$HV`^]"354T,3ZL&M&UL&WG!!%%RC +!'L5\!mL\gr;Zhmrr3-J!!#mr^]"39A,lS(4T,6[A,H90o-FA:-1h$6!6k'8!2KPn +"!mpI-2dcC4T5<_bl@]srVuqPrr2tPrW!&Es8S>_!!&ekrrXPI!'L)W!WW3npQbg@ +gA_8a!!(&ks+gUU:]NK*rrN0#ItI^4rrPFc-MWl,jjO/2hZ*Yk_Z'V#r;Zh-q>UbT +!!"<-!!#.]^]"35L&M&Pbl7VE,ldqh^]+?8!2$4i"+L:Nhu*KV,ldokoD\e:rVurO +rVll4rW!"Rs31EA!'L8\!5JL5!/:@N"!mpI4Sf!Wbl.SE4TGFkrVuqnr;Qb=rW!,: +s!7XF-2dcI49,@-k5W[)!!$O-rro/D4PBaVrW!#)KdHWs!'L,X!+Z!.!/::L!6kEB +!)``L!FmGS!!ah's8OAF!%%RC#<Vtd-0G7-L&M&PL&V)PL&M&Vbl@]?!!">ArrXPI +!'L)W!WW3npQbg@gA_8I!!)K;rrJ@Ko`#!-L$"Qu!p53$qYpWgKp;E5"5.0]k0O&/ +BE01*rrN0#IuaO0ft[N?!L2:&rr^"u-)8lf!^H`4pm(pAdf0F,!!'dNrr>1[!!$O) +rt.?n!'Gr8!%%YT!!">:,ldq0rr3'H!!(6XrrN0#T;_blIfKK+r;QjF!!">:rrXPI +!%%RC!6kEB!epZur;Zh^rr2tPrVuqPr;QjF!!#.WrrC:B!!YRcs#^8]-2[]B4T5<a +g&E>u!%%RC#!;kc-3+"hrVuqPq#:=VrVupEqu?a[U\aunjs:!--2IQ@xxxxxx&CrO +^HDJq##YF#,ldokr;Qj]!!">Err@cP!!%`Prr@cP!!^[Is#^8]4So'[,ldp-q>UKr +!)*'P!9Mr7!e11UeGfYK!!#.Dp\t>j!!"=ErrSrAFRoG3L&<4u!!&ekrrXPI!+Ym* +"$?P`4O=$/IfKK!rrN0#J+EU>g&B1sKfjIRrr@cL!!,3Wm/I/M!!">BrrJ@Zg&D+= +!%.K,!9MZ/"5a(Y^Vg'O;>U=nU\aun,ldpebl.SNUEom?A,eXk!+Z'/bl.SBbeO/Z +!!&Xirr[`N!8m_S"!mpI-2@KCg!'Krbl.SB4T,3Zbl.SDL&[D:!!+D.rr2tPrVuqP +r;QjF!!#.WrrC:B!!YRcs!7XF-2[]K,ldoks8OAF!%%RC#!;kc-3+"hrVuqPq#:=V +q>^OYU\OihA,ZH.U\Xoibl.SBL&1fU,ldokk5Q_-!%%RC"$?P`-3!oEL&M&PL&V)P +L&M&Vbl@]*!!#.XrrXPI!'L)W!WW3npQbg@gA_4f!$Kek!%%UE!@@@5rrAhm!!(6D +rrgOl!!&eerrKANq#CClr;QbNrVupEqu6Ykr;Zi4d/O37!!)35rrN0#J+WaAUHJAQ +!847L!%%C?!)`.`"$?P`-2dcF49,@DgA_4>!%.K,!9MZ/"5a(Y^Vp-PA,ZH34='t- +-0G.*!2KMn"i('`!!#.\!!p@>@fQKTs8U=B!!(6XrrN0#T;_blIfKK+r;QaCrVuqn +qu7#p@fQL+s8OAF!'L2Z!5JL5!gN_=rVupErVlkOrVuqPr;QjF!!#.WrrC:B!!YRc +s!7XF-2dcC^]"3;-3+!-!!">CrrtRc!%%[Fbl.SBL%tZJ4T,6],uMGOrrBh5!!#.V +rrC:B!!%`Lrr>1\!!UUH49,@-r;Qj]!!">Err@cP!!%`Prr@cP!!^[Is#^8]-2RWD +,ldp-q>UKr!)*'P!9Mr7!al!neGfMjr;Zg[qYpQ1r;Zg[WrE&]rVuq?pAY,fpAb1U +r;QaCr;Zhmr;Qb,r;Zh>d/O3?!!(p-rrN0#J+`gA;>:+kL!K]#ffUR&h>[I$pAb1U +mf*AO!!">DrrC:A!!(^,rrPFc-MWl,jjO/2hZ*Yk`W#pJrW!!Gk-=mc!'L2Z##P@# +-3+!Bqu@0Ps8S;`!%$e-bQ%Vhk.got!!&Xirr[`N!8m_S!-J2?!@>tgrrJl@rW!0L +s8OAF!%$e+rr>pq!!:jRL&M&P4T59[^]"35A,Q?/,ldp-q>UH=rW!-bs8OAF!%%RC +!)`^q"$HV`4T5<\bl.PG49,@-s8U=B!!%`Jrr>pq!!,sZqu6]Zbl.PA;>pOqU\Oih +bl.SBL&CrOUJ_!j"""!I4T5<\bl.PD49,@-rr2tPrVuqPrr2tPrW!&Es8R3?!!$O, +rrgOl!!">@rrN0#9D=_PjkB_9?iWI@rr?R-!!%-=rrM^;rVusFo;hlkA,QB-4SSjU +U\k)n,s3LQ!!#.[rrM7.r;Zh>r;QaCr;Zg[d/O3?!!(p-rrN0#J+imB4SJgUL!K]$ +;#gSBk2-+C,ldp-bfmh!r;Zh>n,EJP!!">DrrhI1!!">!rrPFc-MWl,jjO/2hZ*Yk +`r?%'rW!'Ibl@]brVuq?rVm'J!!#.]s-3E]"(VB2g&:sTPlJr-!%#AZ!WW4mW;csL +!!(pSrrM7.rW!'I@teD=qu?g]s8QU.!!GFHs8QU.!!>@`s+UFP!'L5[!6kEB!'L2Z +"!mpI4Sf!Wbl.SE4TGFkrVuqPrr2t.r;Zp^s8RfP!"5%ks5qNO!!">Fs31HB!/:4J +!2KMn!@=N>rs.4e,liZ!s4RAO!'L#U!6kEB"a%tQF?ClI!!B"rs+UFP#aGAhk0,+O +!%%XE!/:CP!/:FP!/:CP"O-oGjsC!,"_6]ps-+i/!!">@rrN0#9D=_PjkB_9?iWI? +rr?R-!!&emrr>pq!!+CiX8`1)qu?^Cq#:?/r;[*LZ2ajq,ldpBrVll4qu?^ZrVlo\ +-2dfD-.)YoT)\lKf)GdO!.XbC!'L2["!r&C4T5<\L!K\u4T5<\bhi@%,ldp-rVlkm +rVupEn,EJP!!">Crr^#5;;'\'!^H`4pm(pAdf0F,!!'dSrrAhn!!+CirVlj[rW!>$ +s8V4-!!%-@s5kX+!!'e5rs0nN!)`c\!!">Crr^#G,uM__!WW4mW;csL!!(pRrrAhe +!!#mqrrM7.rW)pDr;Zr)s8RfP!!#.ZrrXPI!%%RC"!mpI4Sf!Wbl.SE4TGGrr;Zm] +@jV$Q"$HV`U\t2l-2dfG-0G6OrVuqPp\t4Ur;ZpG4?Oqg!!?a2s'u$.!2K;g!6k'8 +!2KPn!2KJmr[%LC"=<41s+UFP!/:FP!/:CP!6kHB!-J/>r[%IB!%%I@!WW3npQbg@ +gA_4^!'ns3!'L5\"=;:ls)e2>!2Jo\!p533rVlo\fua6po-O86!875K!V7W:!!+Ci +rVltp,s9lZrr@cN!!">DrrAhl!!"=lrr\kn!8lB-!WW4Mq#:>(r;Zh-rr3,`,ldq? +cMmlSrVuqPhu<]0rVup\r;Qb=rVurBnG`SQ!!"=mrrPFc-MWl,jjO/2hZ*YkaSu78 +r;Zhmr;Qc3rW!$Hbl>od!!&8_rr>1\!!">Drs_g*!%%Z!!!"=!Ki'-Br;ZhOaSu;A +!2$4i"+L:Nhtm?QU\Ffi-'\?-!0m6Y!+Z$.!0mH_!/:@N"!mpI-2miHjs:!-4Sf!W +bl.SB4T>?\FS5\7L&V)P-2%<?bl>od!!%`IrrL=ipAbFEg&L1\!!">=rrC::!!,3s +r;QaCp&G3=s8RfP!!%`Prr@cP!!(7Arr>1S!!(^KrrN0#9D=_PjkB_9?iWI>rrLe! +rW!!Gk-=jb!+Yg(!SMSo498requ7!L!!&eoKdA#F-&(Xa!d$PYjo5<jrVupErVuqn +qYpP*rVusFbk1o84So*Yg&D!O;>U=nbgHFmT)\lKf)GdO!.XhE!0mE^!+Ys,!jPUe +p\t9VbhW4#UP6I)rW!%BKnZ;]rrC:B!!%-=rr@cP!!(74rrY@`!%%.7!mJmAjo5BI +!%.K,!9MZ/"5a(Y^W?ET-2mlEU\aujL&M&R4TEY)!!(7Brr@0?!!%`Orr@cP!!1;t +o`+usaSu;A!2$4i"+L:Nhtd9R^JQ<V!!4GmL&(`LUF#g<!@;jdrrC:B!!%`NrrY@` +!%%UD!6kEB!)`Ok"$?P`L&M#PKdHWs"Ci_X!/:FP!R)ka!!:CEbl.SBU\=]ho4'*D +!!OZGk5YJ*rVuqPp&>"<q>^RC;5=!f!R)ka!!gaJs5kU-!5JO5"-`cc-2[]CF=$ea +"!mpI-2IQB!!#[dQ2p%#rrQR.5g]N2Z2FY'4=0t,!'L&V!+Yj*!@=N?rrC:B!!,2Z +qZ$VMm/I'\rVurOkPkOerVusFA,ZH.FSl(<^\n-4U\"Kc-2RZB^]+65-2RZB^X<&` +T)\lKf)GdO!.XkF!Tk^-!!$O&rsRLB-):LT;'dLg-):D<!TnM&,m$2Nk4nrWUJ_": +!BcVFrr?R&!!#.ZrrJllr?VJAU[\9`bl.SBL&CrNA,ZH.bl%JEPWU6<4GE\4"$?P` +-2miGo/n<]qYpSM-2mlG-"H*:rrR9g;>L4ojuar3qYpU^!%.K,!9MZ/"5a(Y^W?EW +,ldq?q#:V0!!">Ff`2!urVlu^,lg(*rrqO2!!(6Xq#CLC-"F^1rrN0#T;_blIfKK+ +p\t6UrlbB)pAY0UFT+B'FQWK#!b3NRqu6c',pf>brrC:B!!%`IrrJA!qu6l_PYjPQ +^Y/Sd!/:@N$):um4ER@',pcFfrrQ[V;=jemk+dW-4GBQmrVlu^,lf7`rs.[r4?S=O +UWiE2$):um4ER@',pcFerrV>:g&1jOP_HmJrs>HB4Ca)[s--Bqq>UKr!)*'P!9Mr7 +!al!nci4!?q>^OBbk_8=4SJgX^]4>Xp&G(=m/I'>rVurBkPkNErVutQbl.SB4T#-Y +;>pOqA+T^$jsBm)"*FSC^\Rp1L!fo&T)\lKf)GdO!.XkF!+Z!.!'KrS"Ao.!,uOO> +!%%UD!M^t;!!+C@qu6]@4Sf$\-):M?-1q6<k5PA\;>C1l4RrFObl.SBL&M#OZ2O_' +-2miEYpK8I!@>tgrrY@`!%%UD!/:CP!2KJl!+Yj*"!s`BU](5nFSc";;>pOqg&(dN +5QE/+Q2p$prr_-Y!5HVT!ni:4pAYAO4L+qdZ%^m/rrM9+qYq#04GEh8Yrj<p4AggI +k/@9$!!&Xirr[`N!8klt"!mpnk3;mGU](5n^\%O+k2-+<bh)jpk1BV7!!#[dQ2p%# +rrQR.5gKB0A,?6+U\XoiFSu4=49-],!!?a2s31<>!DtuY!!(71rr@cP!!(7,rr@0? +!!YRcs!7XF-2dcCg&:sP-0Fh!!2KAj"$HV`A,ZH.4T5<\;:5CGT)\lKf)GdO!.XnG +!Tk^-!!'e,rr>1T!!CIFs0;:u!@?n,rrJl@p](CBs8R37!!#.\rr>1U!!$O"rrC:B +!!J#Us5o%6!!%`PrrB>!!!#.[rrY@`!%%UD!/:CP!/:CO!-Iu9![[l]r;Zi4r;Qc3 +rVusFk55/[5QE/+Q2p$prr_-Y!5F-cf`)!Q!2$4i"+L:NhoG`tbi\-h!)`^q!82u( +q>UKr!)*'P!9Mr7!al!nc2Rbir;Zh-q>UW\,ldok^]+65A,ZH1;?-[?qZ$\ms31HB +!2K)a"L2H!4=0t,rB((bmJd4?-2mlH^]4<[rVurBrVlk>rVuq.o)A]"rW!15,ldok +s8ODE!!KPQ!!"=mrr\kn!8lB-!WW4Mqu6Y<rVupqo`"nRqu?dE;,R;m"3gfF-2mlE +4T:$7-2mlEPlC[`fd6Ut#:3lTKd?^!-3!oHftW5<rVuq.rlkBA!/:CP"=7Q3Kk()^ +!%%49!/:CP"!p&U-2dfD4T>?]jsBs+!@9l,!!%`PrrY@`!%%UD!/:CP!6kHB!5JI4 +$&-U<@fQKTs8P4\!!#.Zrr>pq!!$O*rrPFc-MWl,jjO/2hZ*YkK)aL'!WW4mW;csL +!!(oYrrAhn!!"<ss7lTq!!#[dQ2p%#rrQR.5gKB0A,H<,4Sf!WFT)7CPlKm"-2dfG +U]:A<qu?hQs8U=B!!%`Crr=A<!!(^?rr>pq!!H1!bfi3K!!%`Orr>1\!!'e)rr=AE +!!0>NrVuuC^]"3:-3#7k!%$%m".oPnhq%f/!!%NGrr=AE!!'e+rr>1[!!?a&s+UFP +!mL[urVuq.rr3"o-2mlEU]18n;>pOu--ZDhbl.SBA,H9+L&M&PL&:lU,ldokbl@_* +A,ZH.-1_'9L%bQJ4PB`6!+Z!."=:h_s.fPn!%%XE"$?P`-2miDFT)7?bl7VB;>pOq +L&M#TZ%_??s1eL4!/:FP!5JI4!875K!^H`4pm(pAdf0F,!!'ccs4I>Q!!&Xirr[`N +!8k3a"/@.g4T:$7;>gIpKnB@"rrN0#9D=_PjkB_9?iWI<rr@0;!!%-;rrtRc!%#j! +-2[`CA,cK.bl%MA4T>?\^]"35L%50C-2%<>-0F[r!0mE^!@9&h!!#mprrXPI!%%49 +!87>O![[kVrVutQA,ZH0FT4K&!!'d^rr\kn!8lB-!WW4Mr;Qo^,ldokoD\eQrVuq. +rr3G&!!">-s!7XF-1h/$4T,6[-3!oEg&:sP--ZAg!6kEB!/:=M!2KMn!/:@N!2KMn +"GQlj@jV'R!/:"D!/:4K!@;jcrr=AE!!';&rsCjg!%$e-s#^8]-2miD4T5<_bl@^X +rVup\pAY,&rVupErr2sqrVupqq>UL]!%.K,!9MZ/"5a(Y^OlL<rrN0#T;_blIfKK+ +[Jp4QpAb1UK)bTF!WW3npQbg@gA_4^!'np2!2KJm!%%RD!3uG$!%%C?!E$W1rrC:A +!!&8_rr@cP!!%`CrrM89r]L/["E]?O;6fTi!)`@g!%%UD"!mpI-1_'9L&M&R4TD2U +!!,2.rW!#Qs+UFP!-HZh".oPnhq%f/!!%NHrrC:B!!#.QrrbFa!%%78rsFHBZ2`r4 +!!#l<-2[`D4O!g)!/:CP!-J2>!6kEB!/:=M!6kEB!/:@N"_.N4-o!!+Bfnc&TC +rW)p[!E#*YrrC:B!!">Crr@cP!!^[Is#^8]-2miD4T5<_bl@]QrVur5pAY0U-2mlG +L&\pd!!'e0rrPFc-MWl,jjO/2hZ*YkK)aL'!WW4mW;csL!!(oarr>1V!!#lJs7ZHo +!!#[dQ2p%#rrQR.5gfT3U\t/o4TA:X!!+D;r;QaCqZ$[D;8<#.!0mH_!@?n-rr@cP +!!%`?rr@cP!!(7/rr>1W!!+Alr;ZiNrr3'H!!">?rrLfsrVlj[rW!%Ss5kX)!!>@` +s1eO5!'J^0".oPnhq%f/!!%NHrrC:B!!#.QrrY@`!%%F?!6k3<!Bd.Trr>1\!!(7A +rrC:B!!%`MrrC:B!!%-=rr>1W!!4HVk4&BNFT)7?g%YLHU](5nA,Q?,L&M&Vbl@]* +!!">Drr>1\!!^[Is!7XF-1q3;L&M&R-0A_:!!#mkrrPFc-MWl,jjO/2hZ*YkK)aL' +!WW4mW;csL!!(o`rrJ?Hr?VM-A&!Wqp&>'n!)*'P!9Mr7!al!ndf0<^r;ZsHbl?fO +rVupqr;QaCr;ZmFA*3Ue!/:CP!%%UD!/:CP!/9h?!/:CP!6jg0!Tk^-!!dV"^Wapa +s&&aq!0mK_!%%UE!2KGk"S6+'!)`aq!%%UE"3gfF-2RZBPlC[b,ldokdf0EA!!(p- +rrN0#J,K<Hbl.SB4Sf!Yk(T'!rrY@`!%%F?!6k9>!Bd.Rrr>1\!!(7ArrC:B!!%`M +rrC:B!!#.Zrr>1Y!!4HVk3i6O49,@-pAY,HrVuqPr;QbNrW!/Hs8P1]!%%UD!'L5\ +#0d,I,ldp-oD\e:rVusr-2mlE^\Ig15QE/+Q2p$prr_-Y!5F-cf`)!Q!2$4i"+L:N +hh(m#rrN0#9D=_PjkB_9?iWI@rrL=irVusFbl7VBZ2FY&L&M#O-2mlEL&1fPg"HE* +L&M&P4T59[^]"35A*s9uPQ1\0li-rprVupEqYpPjrVupqrr2t?rVusFbl.PBUF#m> +"""!I^]"35-3!oEFSl+>-0G4,!'L5\!2J$C".oPnhq%f/!!%NGrr=AE!!'e2rsFu: +!!$O/s#^8]-2@K?bl%MC,uMGPrr>pq!!(7@rrXPI!/:=M!6kEB!'L2Z!'L2[!@<Hc +rrY@`!%%@=!6kEB!+Ys,$=a&9-0G7-49,@-rVlj[rW!/Hs8OAF!'KlQ!2KAj!)`Lj +!^H`4pm(pAdf0F,!!'ccs4I>Q!!&Xirr[`N!8iD.TDnrm!)*'P!9Mr7!al!neGfQn +-2dfD^\n*3A,QB-Z2Xb'A,ZH/4MUjp#/<8#!5JPfrVup\rVllArVup\m/I-@4L+5P +!%%UE!/:7K#UKHN-0G7-jsC!,"=7Q3@jV$Q"$HV`L&M&P4T>?\bkqG@4T59[A,ZH. +A(1G[T)\lKf)GdO!.XnG!)`^q!@>M[rrKl3r;[$as8P1]!%%F?"m.*2!%$=qrrq)0 +Z2aiXrVuq?r;QjF!!#.YrrC:B!!#.Zrr?R.!!%-;rrJmKo)AeS!!">=rrqO2!!">: +rr3,F,ldokrr3'_!!">Drr>1\!!gaJs#^8]-0G+)!R0^'rr>1Y!!'e.rrPFc-MWl, +jjO/2hZ*YkK)aL'!WW4mW;csL!!(o.s.B;m!!#[dQ2p%5rrDf_rrQR.5h5l8fd6Rs +!2KDj!'L5\"XVCms5kX+!!=N04=0q+!i,dLrVup\r;QjF!!"=prrA;_!!">?rr?R. +!!&8_rrAhe!!#mqrr>pq!!#mprr=AD!!&8^rrAhn!!"=orr\kn!8m&@!;Gs^!WW4M +qu6]M-2dfF4?Oqe!!]4us#^8]-27E>;>pP(4JV'=s1`%D!%$e-g&:sT-,9K[k&gS& +!@?n+rrC:B!!#.ZrrBh4!"!/Zs8Uc:49,@koD\nT!!"><rr>pq!!GF!bbHK`!!%`P +rrY@`!%%UD!'L5\"3gfFL&M&Q4L+nc"GJ-%-0G.*!2KGl!)`Ii!^H`4pm(pAir9#Q +o)AgL!!'dtrrqQ/UP4EGmJd:N;*<(Mrs7ces3/63KqllarrRm:FP6Zq!!&Xirr[`N +!8iD.TDnrm!)*'P!9NSI!a(NXo)Ac!!'o*7!)`[p!2KAi!5JI4!'L8\!M^t8!!>@` +s-3K_!/:@N"!mpI-.Mqp;>pOqL%tZJ^]"354T59[U\Ffi-'\B.!'L5\!/:CO!+Z!. +!@?n,rrM7.rVurOeGfWC!!(p@rrVpSYOVVo!!%NFrrAhf!!+CNrr3'_!!">>rrBh3 +!<+;C!!">Err>1[!<+;B!!%`NrrC:B!!#.Yrr>po!!+Alqu?_=oD\nT!!"><rrBh. +!!#.[rrY@`!%%UD!'L5\!6kHB!%%RDr[%LC!6k??!)`[p!2K8f!^H`4pm(pAir9(P +@,LVV"5a(Y^Zkb!jsBp*![V@JnG`TE!!#.[rrTrh^Y/VeL&NCq!!4HDZ2O\(UP7k0 +rrXPI!6j0s!WW4mW;csL!!(o0rrQ%DKqSGI!!#[dQ2p%5rreqo(m"F`rrQR.5h5l7 +4T5<\U\FcgU](5n-2miEfhqSG!@;jerrC:B!!%`NrrY@`!%$.p"0j-P4SJdWF8u<* +r;Qi5;'l2A![T.Hqu6Y+rVur5rVll4rVuqPqu6XYrVurBeGfWC!!(p?rrZX/0X(*J +!WW4Mq>UJj-2ITC-"HQFrrY@`!%%@=!M^t9!!+C@rr3#C-2%<=-2dcCbl.SB;>U:m +;>1%j4S&LS@fQKTo`"oFq#CFAbl.PD49,@-rVljprVurBrr3#C-27H?4So'XFT)7? +4SA^U5QE/+Q2p%+rri'%!+=^Xrr_-Y!5Idu!0m9Z!@>t[rr[rT!'L8\!87>O!5I7f +!'KoS#*f/fPQ1\0rr3'H!!(6srrN0#T;_blIfKK+e,KJH-"HWJ!i%&=`W$$^!!">$ +rrTrhZ24J%fnH^,rrTH&FPQlt!!#[dQ2p%5rs%ot!!!jsp\+Ug?iWIBrr^J--&)$l +"-b)XFSl(Bfp%1Q;2)d^rrQ[V;>^@qYpC]ke,KI2bk1o9UVHX)!9X:)!9X+W"6NH, +L&:lOZ"'$prr^Ik!)_5F".oPnhrt(?\,H@.0X(0L!WW4Mq#:BWA,R\T4ET`_rrZ*u +!'KrS!p3u=qu?dEA(ge[!SL?J!!O[&@fQKkr;QcMrVuqnq>UMk4=0q+![Tsnnc&^E +,pd[)rrJl@qu?apg&1jPF8u;NrVlu7,lg(*rrV=[-2[`D4JV`P!%%UE!2K5e!^H`4 +pm(pAiVrm[rVut,ht[3RhZ*Ykl2LsA!!"<-4=0t,!@?n!rr[rT!'L8\!2KMn!0l4; +!'L5\q^)4A"/GnrA,ZH4g&M'u!!(6srrN0#T;_blIfKK+eGfN5rVurBp\tBY,ldq! +a8Z;),ldoko`"u7-):)3!Tmnj,m+,I-0G.*"MZ5_!2KGk"PG($!-I&s!WW3npQbg@ +li-rer;Zm9O8&GL!al!n`;]l#k(<X+rrCa#rr\kn!8lu>!#YY7!AL_OrrN0#J*Ht8 +k$qoSo)Aj:^P/H,p\tBLP_Fh+rr3&)L$&:4!jPUepAY<Yb`mh*k1fn9U],rIg%kXK +bfoq`!872J"m2&';2*]urrAhn!!#.RrrPFc-MWl,jl-4>\,64,@,Lh\"5a(Y^Zkb# +K`D*8rr2tPrVuq.o)AfG!!#.[rrQ%D4PB`;49,A'k5>5\fp&92rr^q:-"HrS"!mpI +bhE'u!!&Xirr[`N!8l<+!/:CP!6k3;!0mH_!0kP(!/:CP!/:+G"JYqs-0Fn#!JMiq +!!&8]rr>pq!!#.Yrr?R.!!">$rrN0#9D=_Pjm2pHYPS;$(m"FfrrQR.5_B#jrr\kn +!8lu>!-%f8!AL_QrrN0#ItI^Frr>1\!!&8UrrPFc-MWl,jl$.=&GlG.@,Ln^"5a(Y +^Zkb#K`D*8rVlta!!">9rr[rT!'J^0"$?P`L$nsC,ldqhgA_3S!2$4i"+L:NhphZ+ +L&M&PbkM,;4T5<\bfB_c,ldokp&>':-2mlE^\7[-A+os'L&M#PjsC!,!@?n+rr=AD +!!'djrrN0#9D=_Pjm2pHfD,CJ(m"FhrrQR.5_B#jrr\kn!8lu>!13K]!AL_SrrN0# +ItI^GrrBh5!!">:rrPFc-MWl,jl$.=3;EOT@,Lt`"5a(Y^Zkb#F8u;'rVluD!!">9 +rr[rT!'KlQ!SP]VrrY@`!/9k@"!mpIbhE'u!!&Xirr[`N!8l<+!/:CP!6k3;!'L5\ +!6iOa!5JL5!+Y^%!'L2[!/:1I!+Ys-"!p&l-2mlEL&M#OU\k)l^]"05jsBs+!/9;0 +!WW3npQbg@li-tZpAb73O8&YR!al!nK)^T*".oPnhrk">\+]k'0X(HT!WW4MK)a-r +!+Z!.!+YX#!^H`4pm(pAi;WdZpAbD*huDR6!5Idu"$?P`FT)4AUAt9?rVm)a@lu&" +A+T[!",-^T4T>?_fd.r>r;Qu+49,@-4JVoU!`:8=qYpUo-&)$l#Wr(eL&_1sbi\d% +"/@.gg&D!R,ldqhr;QeO4T6W-;5<:R!WW4mW;csL!!(p+rr@cP!!(7;rraVJ!%$dK +rr>pq!!(^Grr@0=!!#.Vrr@cO!!GF;s8Tk5!!&8^rr@0=!!%`OrrAhl!!#mQrrN0# +'DEgR3U/j0"SMg"(m"Fk?iWHDs+^OUT)\jNk<K#(o`,1MYQ+V&!.TV#cMmkjrVurO +oD\kW!"/KJ!'/t&!$(Y3"CT+I!5Idu"$?P`L&V)TbU!5hA,cK/KdHWs!@?Furr[rT +!'L8\",-^T4T59[U\Xrp4TCWG!%$=rrr\Jc!%%=<!^$G_rZqRF!<+8EFT)4A49,A8 +rr3'H!!(7BrrLe8q>^M*kPkS`!2$4i"+L:NhphZ+L&M&PbkM,>,ldokmJd3OL#2h4 +js:!-4SJdT^\\!2-2IQ@^\n-44T,3\F<sf^rr>1Z!!#.[rr?R,!!#.<s3:TI(lqr& +5_B#jrrA\A!!G!Z!!%M#s3L]F^]"354S&LP5f3R%^Zkb.49,A'beIX6!!"=us8S>Z +!!#.\rr[rT!'L8\",-^T4T>?bfd-Uu,s3LQ!!1<srVup\r;QjF!!#.Srr>1T!!(^O +rrY@`!/:FP"!mpIbl7VB4T5?[-2mlE^Zb\!!!&Xirr[`N!8lc8!p4Ser$;A+g&D!O +L&M&PbkM,C,ldoks8UbLA,-'6Kfk(hs'l$/;?+Cb4Cb/]rrM8Hr]C6ZPih]>!+Z!. +!2K8f!'L,Y!@?n)rr>1\!!#.Qrr=AC!!">Drr=AC!!">%s3(HE#lm5Bs+^ORT@!W= +ItI^HrrAhn!!&8Srr>=%!!'durr>1V!",M$s5kU-!%!?CA,ZH4U]:@J!!#.\rrZa2 +!'L8\$p4Li--ZDhPU03,s'u$.!2KPn!/:CP!2K5e!'KuU!%%UD"!mpIL&V)V,ldqh +s8RfP!!ebgs03jM!/9Y:!WW4mW;csL!!(p9rrJl@q#CClrr2t?rVurBp\tOG!!">F +s!7XFA,?3*Z2O_)U]2Y>!!">C!!+Ciqu6\N-2RZC-$8q^"Qh!1!'KuT!-J2?!B`LD +!!'e2rr@cP!!+D!o`"pEqZ$UBrr2uOqZ$UBhZ(h#"(5(.5_B#jrrA\A!!Ej_!!%M# +s3CWGF<sfSrr>=%!!'durr=AA!!+CNrr2t?rVur5rr39e!!$O/s+LFQ4T>?b49,@D +s8Skn!!'e0rrhp>!!">ErrXPI!'KoR"?ZYa-&)6?r;QjF!!%`Prs^7S!6kKC,ldq! +s5mf;rVurOkl1\a!2$4i"+L:NhrF_:^\7^.4T>?`49,@-k55/cbeJjc,ldoks5kX, +!!';$rr>1\!!8Db-2.B?-0G1+!+Ya'!/:7K!+Z!.!2K;g!SJdu!!0igrVuq?qu6XB +rVuq_oD\fcq>^W4s8R3;!!(7#rrN0#'DEgR3U/j0#5%s"@,Lul!'l/9LAq@J!!#"A +5QE_8!!X!an,E@fItI^4rrPFc$MYqJ3T*.&*q]L95c4S^^Zkb",ldrE,lpl<r;Qj] +!!#mprs=AZ!'L;]K`D*8rr39e!!%-@s%rar;>:(jL&M&RL&[D:!!&edrrY@`!/:+G +"!mpI^]+6@,ldqhs3(HC-*^;nrVusFUZ_XY!!&Xirr[`N!8li:!/:CP#<[^)b]Egb +A,cK849,@-s4O0$4=)<M!!=PIs&&aq!%%RC!2KMn"""!I-2%<=A,cK.Z2FY),s4:9 +rVupEqYpQ1rVup\pAY+TrW!"0s1eO5!'L2Z!0mH_!'KiP!+Yj*",6dT-2mlE4T5<\ +Pi)KB!!#[dQ2p%3s7QEn@,Lt`!al!nK)^T*".oPnhrk">^\7^0&:a0JrrN0#ItI^4 +rrPFc-MWl,jl$.=@.sX*5em?V!!'durrXPI!6k6<"!mpIL&M#XK`D*8s8RcQ!'L8\ +#s81fL&_0!!!'e-rs1^e!%%5!!!#.QrrY@`!/:+G"!mpIbl7VG,ldqhs.fDj![V@= +k5PJ_!2$4i"+L:NhrF_:;>pOqZ2O\(P[ikTrr>1\!!">;!!FVJs5kX,!!%->rr>1\ +!!@?Cs!@UD#>r7[YpBAM-3!oE4T5<\PlC[_Pl:X_-2RWA;>pOqU\FcgPl:Xf-1h0! +,ldokr;QaZrVuqno)A\9rVuq.rW!!^s4RAO!@>#M!!$NdrrN0#9D=_Pjm2pHhtR0P +@,Ln^!al!nK)^T*".oPnhrk">TD8Hg&:a0HrrN0#ItI^4rrPFc-MWl,jl$.=5ktB\ +5em<u"5a(Y^Zkb#,ldqhq#:FB!!%`Ors=AZ!'L;]K`D*8rr39e!!%`Qs!7Xkk4\fT +U](5n4T5<\U\"Kf49,A8p&>+?!!(7Brrj\K!6kIsqu?dEFQVZa!WW4mW;csL!!(p: +rrA;_!!4Hgk5##W4R`=N4T>?\L&M&T-0G7-U](5r-0G7--2mlEPl:U^A,ZH0^]2(J +!!Hg3s._^T!!$O+rrBh5!!#mjrrM^;rW!(Cs3/\5rVurBrVlsG!!">9rrCaO!!ah' +,ldoks)e5?!Fsg^!!#.=rrN0#9D=_Pjm2pH\,$(*@,Lh\!al!nK)bWG!i%l3r;Qhn +4GDbo!L/;Nrr\kn!8lu>!-nA@!YBkMqYpTs!.TV#]Dhpt!%.K,!9N/=!#YS5!AM:d +rr_-Y!5Idu"!mpIbkV2?,ldperVm1$!!$O/s+LFQ4T>?e49,A8s8OAF!6k-9!'L/Z +!%%49"$?P`L%YHJ,ldqhrr3-J!!(7CU](5o4I"h)!WW4mW;csL!!(p9rr>1[!!4HV +k55/Y4Sf$b,pcEBUWgq.!!#.[rr=AE!!?a2s#g8\!+Z$."$?P`-2dcCPl:XaL&Z8o +!!9EZ-2[`C4So'X4T5<\^\@a.A,QB.,piEg!0mK_!6kEB!'KiP!0mH_!^-K/rVuuC +-2mlJ^],S[!%$P&!WW3npQbg@li-ruqu?b*ht[3Q?iWI(rrC9ZrrCaO!!&8_rrCaO +!!&8DrrZa2!)^H0".oPnhrk">./a,I&:a0DrrN0#ItI^4rrPFc-MWl,jl-4>a8>o< +0X(?Q"5a(Y^Zkb#,ldqhq#:S/!!"=hs8Skn!!^4<s+LFQ4T>?f49,A's8P1]!'KlP +rrTr4A,Q?,^\e'3L%>6G49,A8p&>+?!!'e5rs9tO!6kK*,ldper;QhP,uNn+!WW4m +W;csL!!(p8rr>1Z!!+C"r;QaZrW!$_FHk#GrrXPI!'L5[!2KJm!PcDK!!+D.rr2s\ +rVurOrVllArW!"Rs#g8\!%%OC!Bd.RrrAhn!!#mjrr=A;!!#mqrrC:B!!#.Prr>1\ +!!7lSA,ZH.;>pOt-3+!-rVur5i;WiY!)*'P!9NSI!V[0)!!-KbpAY2%!'n6t"S4_U +-)8BX!6kEB!/:FP!6kEB!/9J5"$?P`-,'<\T)\lKkl1Y'rW!!2J+*+2!WW4MK)`I_ +!^H`4pm(pAiVrmkrVusQYPA,"hZ*Ykl2Li3!!(7<rrBh5!!4H/4T5<\4T>?_K`D*8 +rr30b!!#.]s.fPn"!qH24T5<\Pl1O];>pOq-1V!;49,A8p&>+?!!%`PrrsbL!6kKC +A,ZH.-2p"/,ldokkl1\a!2$4i"+L:Nhr+M8UHJGS!'L5["$?P`-2.?@,ldp-r;QaZ +rVusr;>pOqA,ZE-4T5<\bl.PAbl.SDL&X:3!!,3Wq#:IZ!!">-p\t4>q#CFA-2mlE +-3!oEbl.SB4S\pWbh;sp!%%UE!mL\>q>^V-s8R3?!!%-!rrN0#9D=_Pjm<!MY5eQ1 +ht6pM?iWI*rr@cP!!">$rrQ[mZ0M>hbl.SBL&V)Pbl.SBL#`18,ldok^&J2,!!(p? +rrd9@&:a0@rrN0#ItI^4rrPFc-MWl,jl6:CpD<laYP.tuhZ*Ykl2Li3!!(7;rr@cL +!!+D!rr3(S!!#.\rrY@`!)`aq!+Yg)!@?FsrrAhn!!%`CrrY@`!/:+G"!mpIPlC[b +,ldqhrr2s\p](;9kl1\a!2$4i"+L:NhqnA6^JXq0!+Z$."!mpI-2.?@,ldp-r;Qc3 +q>^OBk5G;[4T5<\bl.PAU](5pL&X:6!!4HD^\@a.L&M&PA,$!'U](5p-&%'PbQ@hE +-2mlMg&M*7,ldokk55/`ffT67L&_1frW!'Is8V4-qZ$`Os8Tk5!!#.>rrN0#9D=_P +jm<!K:gi2OrrQR.5e[0tPl:X_4Pp)?@fQKTlMgk.rVuqPrr2uBrVuqPj8T3-!!"=Y +rr\kn!8m&@"8=3nn+-J[!!%M#s1A:45QE/+Q2p%+rrTAXYOqhshZ*Ykl2Lfp,uO@8 +!L+o/!!,48rVlu)!!&8_rr]MP-*dFK!JMiu!!4HVk55/\;#gSBnG`SQ!!%`Grr[?h +-0G4,!^$H/r;QhP,piNj![Tt(kPkS`!2$4i"+L:Nhq\53U](5n-3!oH,ldp-pAY4@ +!!">Brr>pn!!$O,rr>1\!!(7Arr>pq!!8qq;>pOr;<IcU!TqW)rraVJ!%$e%rr>1\ +!!$O*rr?R.!!&8_rr>1\!!,4RrVlnP-2mlH4TGG'rVup\rr2s\qu?^CrVm!H!!">- +iVrrZ!)*'P!9NSI!9`kO!al!n]`/(D,s9E.rr>1\!!(7/rrC:B!!%`PrrC:B!!%`5 +rrXPI!'Isp".oPnhs(.Ap[@VO!WW4MK)`I_!^H`4pm(pAir9#Ao)AgL!!'ddrr^#i +L"Z>&!SQ/trr^#iKqnJD"Qh!1!/9qB",/$`k3`0Kbk_8=k5NTcrrN0#T;_blIfKK+ +j8T1cKtmTd"S3o>!%%XE"!mpI4SJdW,ldokqu6Z2qu?aDk5>5Z4T5<\U]18nL&M&S +-0G6&rVusFU](2tfjc<.L&_1;rVuq.p\t6.r;Zi4qYpQ1rVup\rr2u'r;ZsHFG3R< +qu?h@s8P4\!!%-?rr@cN!!%->rr=AE!!&eQrrN0#9D=_PjkB_9?iWHWrr>pq!!&8L +rrC:B!!%`PrrC:B!!%`5rrXPI!'Isp".oPnhq%f/!!%M#s1A:45QE/+Q2p$prr_-Y +!5Gf="ChE3-0DB1!WW4mW;csL!!(p;rrCaO!!">E49-],!!#.\rrXPI!'KuT"!mpI +-2RWAA,QB-;>^@n4T,9Z-2dfDA,cK.4T,6^,s4:9r;[(4s8P1]!%$e%rr>pq!!#mk +rr=AE!!(^Orr?R%!!%-?rr=AE!!&8_rrCaM!!(^Nrr?R.!!#mTrrN0#9D=_PjkB_9 +?iWI"rrTrh^]"05g#h]%"6Ri-L&M&SUWgsEmf*:2rVuqPrr2uBrVuqPkPkY.s8UdO +!!#-prr\kn!8lB-!WW4MhZ!bS@lukNPi2QBP_Iom!JU.Arr\L>Ktm9[!5JMe!87&F +!87@*!5I@i!^H`4pm(pAdf0F,!!'d=rrXPI!+W/2!WW4mW;csL!!(p;rrCaG!!BM+ +s31HB!'KuT"!mpI-2RWAbl%MA^\e$24SJgU4T59\bU)u`"!uY#U](5nA+op&-2mlE +^\Ig/L&M&PL&M#OA,$$)4MUjp!%%UE!6kEA!%%UE!'L2Z!2KMn!%$V(!WW3npQbg@ +gA_4^!'n6t"6NHCU]19$^An6[k5Sp;!$sb4qu6\l;>VXEFT;Ap,lf5;rW!'I!!"<B +qu6]ZPl<cGFP6Tl!6kEB!/:FP!6kEB!/::L!M`Nk49:/hq>U]^@jNE$,pd[4!!$NB +rr\kn!8lB-!WW4Mhu<^>!<"2F!%#DCrrI4qrr3!]-/JS&@fXaNrs$[n!$rokA,$!) +ffT96,ln!Up\t7k!<+8F!'K-<!^H`4pm(pAdf0F,!!'d>rrAhn!!'d9rrN0#T;_bl +IfKK+j8T.6-2ITB-):G="!mpIL%bNK;#gSBqYpP*rVupqqYpOXp](:Vqu6`h@jV!P +"XR%.s8RfP!!'e-rr[?C!+Ya&"$?Q0g&1jNUHJJT![Tt(qu6a\!!">Crr@cP!!'e3 +rrhI1!!">(rrN0#9D=_PjkB_9?iWI*rrZ*u!%%XE!/:CP!Fn7h!!'e4rr>1V!!:jR +-2%<>-0G1+!FmGQ!!,sMrr2uBrVuqPrr2uBrVuqPr;Qf&-2ITA;>^@oUF#X7!/8,d +".oPnhq%f/!!%N,rsDU'A*3gkk(Nd]k3;mIbQ*@rrrJ@<hZ![f!!(7@rs'hr^]4=D +!/:4J#Wr*@s8V4D!/:7K#]p&Vk5YHk!)_YR!^H`4pm(pAdf0F,!!'d>rrZ*u!%"`H +!WW4mW;csL!!(p9rrM8HrB(*jU\k&mfnG[_rrRn.g%t^K-2mlE^\[s14T5<\;>rZY +A&%g=#Nhe8;*9Q-k5G;^YpBBIo`"sFbk1o9PihfA!87@qq#:H24?TnGrrSEpZ24J& +UEq4.iVrrZ!)*'P!9Mr7!al!n^&J'prW!&Es8RfH!!#mqrr>pj!!:CE;>'ti-3!oF +bWPY#!%%XE!6kEB!/:FP!6kEB!/:CO!2K8g!)`^p!2K2e!/8,d".oPnhq%f/!!%N- +rrV=/-2[]D@fV5IrrUCEL"lV2ffT6\!6kEA!gE\=rVlmE-2IQB^AqdBrrVd<-2IQA +,piKh!^$J9i;WjD!%.K,!9MZ/"5a(Y^U!kA49,A'XT&>%!2$4i"+L:Nhn/mgL&M&P +4Sf!W4T5<\bi\p+k01@8!TrP&rrN0#9D=_PjkB_9?iWI*rrY@`!%%XE!/::M"XRY) +!!">Err=AE!"EFl^S<mk-0G7-P]T#6rVup\re1@*rr2s\r;ZmF@o<4*!%%XE!6kEB +!/:FP!6kEB!/:FP!Tk^-!!">E4T5<a-0G7-jsC!,"?_BlF=$kc!/8,d".oPnhq%f/ +!!%N-rrUCE4T#-[ffWdCrrhJ<@s"LBrsuku;2)dbs-.U*;2)dbP_K&8"J^'9L"ZG) +#JYumk(QZdg%YLNfd.quK`K?qrrP;/k5G;]F9')PrrSEIL&CrO4=0k(!nf\5r;Qh? +!6jC$!^H`4pm(pAdf0F,!!'d>rrUD,;60]u!!&Xirr[`N!8kEg!%%UE!2KAi!'L5\ +!6g&pp\t9p!)*'P!9Mr7!al!n^&J0s!!">Err@cN!!ssqs+LFQ-0G6\rVup\rVlrP +A!Hlj!/:CP!/:=M!+Ys-"-iicbl.SB;?$Rqbl.SBL&V)Pbl.SBL&V)PA,ZH.A,cK/ +^ErjZ"53_SA,ZH.A,ZE.o0!!P!2I7-".oPnhq%f/!!%N,rrOJm^\7[-U\uJ?!'JL( +rrHU0rZqpPA,fCP!$rqFs#_V,rrUD,!<+8F!-J5?!ehqbrZqUG!2K>h#0^T>s+LHs +rVlmE-2dcEUB$#=rrFDlo)AbR!86<1!^H`4pm(pAdf0F,!!'ccs4I>Q!!&Xirr[`N +!8kHh!5JL5!%%F?!'L5\!6g&pp\t9p!)*'P!9Mr7!al!n^&J0\!!">Err@cN!!C"9 +s+UFP"3gfF-2mlF4L+V[!0mH_!/:@N!Tk^-!!&enrrC:B!!%`PrrC:B!!%`PrrC:B +!!%`Prs'hM!'L;]^JXq0!'L8\"!mpI4T#-YL&M&Pbe=#YT)\lKf)GdO!.Wr,"bcpV +-$6ours5k04PBc7PQ3iFrsWuLA+T`l;#lj\bQ*@rrrG5.rr3Wo!/:IQju`Wts8RcQ +!0mN`PQ3$%rrRlSbl.PB,s;,*!mCXSoD\lG!+YX#!l"^thu<aC!%.K,!9MZ/"5a(Y +^OlL<rrN0#T;_blIfKK+]`.t/rVuq?q#:=VrVurBK)bTF!WW3npQbg@gA_4^!'n6t +"!mpI-3!oEL&CuOA,cK.FT)7Bbl@^<qu?a[U\Oihbl.SBL&CrNPl:X_A,ZE-bl.SB +L&V)Pbl.SBL&V)Pbl.SEL&_1frW!"RUHJGS"=;:ls4RAO!/:=M!/:CP!6i.V".oPn +hq%f/!!%N+rrJlWrW!!G4I#gE!^%d^rVm(U!2KSo,piNi#3I4/s3(Isrr30b-3+"? +!+Z!-#P05fs8RcQFT)4@xxxxxxxxxxxxxxx,s;,*!mCX,o`##g!%%7/rr^Ik!5IFk +!^H`4pm(pAdf0F,!!'ccs4I>Q!!&Xirr[`N!8kHh!%%UE!87/I!'L5\!6g&pp\t9p +!)*'P!9Mr7!al!n^&J0\!!">Err@cO!!(^Orr>1\!!(7BrrJl@qu?a[g%t^Kbl.SB +L&CrN;>pOq^]"04bl.SBL&V)Pbl.SBL&V)Pbl.SEL&_1,rVupEqu?aDL&M#Obl.SB +^\e$2L&M&Pbe=#YT)\lKf)GdO!.Wi)$e^4r,ldp-k5YH-4T,3`bQ(N?bQ)/KrrUCE +L&V)V4=1%-;#ni<rru=#bl<@sbl.PCF9'PXrrRlSbl.PB,s;,*!mCX,p&>,h!%#k] +rr^Ik!2JEN!^H`4pm(pAdf0F,!!'dns8L5os8)`s!!&Xirr[`N!8kKi!87>O!'L#U +!'L5\!82u(p\t9p!)*'P!9Mr7!al!n^&J0\!!">Err>pq!!">Drr>1\!!(7ArrV=m +-2dfE-):A;!6kEB!'L2Z!'L5\!6kEA!6kEB!/:FP!6kEB!/:FP!6kEB",6dTL&(cM +-&)6r!6kEB!6k??!/:CP!6i.V".oPnhq%f/!!%N%rs-;$!)`d?!!)mB"TU[bK`Hi& +rrUCEL&V)U4=1%-4=0n)#)*&As+LHsrVlqQ!6k-9!egWurVlmE4T,3\bQ)/Hrr[rT +--Z#]"0j-PUYYqO5QE/+Q2p$prr_-Y!5IUp!FmGT!!4HDg#i;7U](2n,uNLu!Du_k +rrLeMrZqPup&>#%rZqSBg#W/7!!&Xirr[`N!8kHh"(M<WZ1n8#YpBBIK)bQE!WW3n +pQbg@gA_4^!'n6t"!mpI-3!oE4T5<\;>pLp4T5<\bkqDAk(P,\!!+D.r;Qc@rVup\ +r;QaZrVurBrVm#_,ldq!rr2uBrVuqPrr2uBrW!%Ss8RfN!!,3Wq>UH=rVuq?qu6YM +rVurB^&J2,!!(p-rrN0#J)UD.^P2Oa#4j,es3(HhqLo':s+LH,q>UN?!/:FP"["+2 +s#_V)rs"/WPlHF;bl.PCK`K?irrRlSbl.PB,piKh!l"_hp\t>*!'Js,rr]"r-*c8* +!^H`4pm(pAdf0F,!!'dqrrP:_4T:$:49-\Okl1Zn-2miE,uNP!!b23mr;R#T,pdYe +;#k,#rs(Xd@tf"N-/%D[!WW4mW;csL!!(ogrrLg8p&>'Tb_#lfrrN0#9D=_PjkB_9 +?iWI*rrXPI!%%XE!'L5\!/:CO!-J2?!2KAi!V8GQ!!%`NrrC:B!!#.Zrr@cP!!&8] +rrXPI!)`aq!6kEB!/:FP!6kEB",6dTPl:X`4MUam!6kHB"=4$J--Z;e!+Z!.!2I7- +".oPnhq%f/!!%N-rrP:_^\[s6494's,s:u&!mCXdr;Qqqbl>leL&V)V4=1%-;#ni< +rrus5bl<@sbl.PCK`K?irrRlSbl.PB4=0q*!egWLq#:CX!'KlQ"*=MhbhN.!5QE/+ +Q2p$prr_-Y!5I[r!gE[pr;Qh_!'KKF!B_[^rrhq'!!#.ZrrQ$t^]+67@fX:>rrRlS +L&V)R^Aq-mrrN0#T;_blIfKK+K)_JC!WW3npQbg@gA_4^!'n6t"!mpI-3!oE4T5<\ +L&M#OL&M&UL&_1,PhH$8!-J2?!/:@N!6kEB!'L2Z!5JL5!BfuQrrfSQ!!">ErrC:B +!!%`PrrC:B!!n;Ys5kU-!%!?trs.\?,lggBs'u$."XTrDs5m2W!!%_drr\kn!8lB- +!WW4MiVrtD!'L/Y#Nd<Ys8OAkk5G;aUEt$^js;>Orrj\ps3(Isrr30b-3+"0!-J/= +"skSqs+LHsrVlqQ!6k-9!egWurVlq@!2KMm!^%dkq>UM+!+YX#"/>iYo@j3G5QE/+ +Q2p$prr_-Y!5I[r!^$J,qu6^D-0G+)!87,H!TrPBrrG5.p&>$Fp&>$Fp&>3#,lhF$ +4T59]js<.grrUjR;>L4m;'l/?!@9&RrrN0#T;_blIfKK+K)_JC!WW3npQbg@gA_4^ +!'n6t"!mpI-3!oE4T5<\L&M#O^]"374TA:X!!">E4T,6[U\t,lbl.SB4T#-Y-2mlH +-"CF2qu?hos8U=B!!%`PrrC:B!!%`Prr?R-!!FT14=)<Q!!FVJs5kX+!<+;B!!%_d +rr\kn!8lB-!WW4Mi;X`Y!'I%=s8SiV!/:IQPQ3i.s8U:h!5JR6@fU$<rsN<:L&]?s +;?-7f4=1",![RiArr345!-J8@K`K?qrrRlSbk:u;K`K?qrs7a5--ZDh@fU$<rs/.L +PlLcg!%%Kcrr34WL&_28,pfhnbhrF%5QE/+Q2p$prr_-Y!5I[r!`8rmqu6]Mbl.PG +Yrj<4,uNh&rr@cO,n#G,bU!5h,piTk,uO[A#3KDA!$rqUrVm+";;"em!$ua]rrkMI +Z2Z+4rVlqo!/:@N!@9&_rrFDljo5A^!2$4i"+L:Nhh(m#rrN0#9D=_PjkB_9?iWI* +rrXPI!%%XE!)`^q!6kEA!6kEB!^-K[pAb1Uqu6Z?rVup\qu6Yko`,(Vs8U=B!!%`P +rrC:B!!%`Orr>1T!!&enrrJl@p&G(i^&J2,!!(p-rrN0#J)C8-49,B\,m"&mFT)4E +@fRf;4=(!&rVm'a!$s`R!+Z$."sj6qL&X7]rr35I,lf5R,lhHSrrRlSbl.PCK`K?i +rrRlSbl%JFUEq3K,lg(+rrpUH4TGFYq#CC@rr3*I-3+"0p](<<i;WjD!%.K,!9MZ/ +"5a(Y^ZPP!YlH(lg%bRQUAuToKjt*/k5PB#;#i_4Kff?Fo7\J:Kn]R,,s;5-js:"; +KnVVhA,cK64=):NKleU@L%tZJ^]+66,s;/+!egWhr;Qd[-1h-<@fV5ErrN0#T;_bl +IfKK+dJj70L&O18FMHc6!JQcorrKBhqYpQXre1@7p&>0WP_Fgdnc&WDo?[F<!!#[d +Q2p%#rrQR.5e[1"@fQL+rr2tPrVurBr;QsI!!#.]juiG>!)`Um!6kEB!0m?[!M^t< +!!c@`!!">Fs4RAO!5JO5!87>O!5JI3!JMir!!,3sr;QfA4So*],p`NkKt[KgT)\lK +f)GdO!.Wl*!P`aU49:/uqu6i7F?D[-g&(dPUJX-NU](2sflU)ds-/68rreQK4Cc/) +rrTrhoDS[j^P2:PrrTrhoDAOjfjd-,Pl1Obo7`G/s-3;4rr3+TL&_1fpk8_>i;WjD +!%.K,!9MZ/"5a(Y^ZGJ#F<pne,uKohrVlu^,pi0^rs,;!;?-Zk!)`^p"["*ns#_V+ +rrsc3s8PprPl:Ue493.rs#^9krr3&D,pi3`!@9l,rrRlSbl%JB493V"rrh";,li&J +rrN0#T;_blIfKK+df0BD,lmoj!WW41kPkVG;9]%>!@9kbrrUCj4T#-YU\lD<L%kTP +F<po5,lf78o`"u&!6idh!WW3npQbg@gA_4^!'n3s!McFgrr_CG-$9%a"*>hObl7VC +^LR4)!JT5%rrR9g;>:(tPYjP*FP6]oF?Hi-rrTHZU\t,nZ%\tKrs$5l@m"jtg%bRR +fnE9cKp:`Q@thSq".oPnhq%f/!!%M#s1A:45QE/+Q2p$prr_-Y!5IUp%H_aY,ldok +;=jhfPQ6sGrrtS3s8Pprbl.PF^P2^f4=0t+"XQ;2s!8uhrs-:=;?-YY-0G1+!@9&a +rrFE.rVlqQ!6kB@!^$J,p\tDl4?Oo9UZMLW!!&Xirr[`N!8l9*"2=g^U]18q^H;L< +kl1^<!6kHB!JQcqrr^Ik!'L2Z#ep@%k5XR+!5J@0#dF@l^]4=u!%%=<"(M<2bg6:j +!!#[dQ2p%#rrQR.5_B#jrr\kn!8lB-!WW4MK)`I_!^H`4pm(pAdf0F,!!'dmrsIn` +@jM+;s8PprFSpgr,ll0h,pi?d!B_\,rrj]2s3(I?qu6gG4TGFD-2dcD4=0Y"!@9l, +rrRlSbl%JB493Utrr^Ik!5I[r!WW4mW;csL!!(p*rrQ[1U\t,njs;>;rrRlSbhN.# +KdA#F4T,3\;#nB1rrV=/;>L4n4=0.grrR9BPkb7^ffT6\!6idh!WW3npQbg@gA_4^ +!%<I!LAq@J!!(p-rrN0#ItI^4rrPFc-MWl,jjO/2hZ*YkhZ!fO491WG4951'"3gck +-2@K@4=0t+"XQ;2bQ*@orrj\ps8P2-r;Qd[-1q3<,s;/+!egWur;Qd[-1_';UB"fd +rrN0#T;_blIfKK+e,KJ3!6k??!b4@GrVm#8Ki*Q=qYpY^@q1c&rs4<U!-Eqds+Q^8 +rreQrA!H-Srs+dQs1`YQPih`?"]57^bU#CLrrFDlr;Qd[-2IQA;'l/?!mCXuq>UZP +,pe8!!6idh!WW3npQbg@gA_4n!"ab^LAq=9!!(RL!WW4MK)`I_!^H`4pm(pAdf0F, +!!'dsrrUk"A,?30^Aq.2493V#rrFDlq#:@W-2miI,s;4O!)`Xn"XQ;2s#_V*rrG5. +o`"q<4T59]PQ6F8rrFDlq#:?Ir;QiB!'KED!WW4mW;csL!!(p*rrR9BA+fj&@fZKS +!<?!qrt2L^!$rok--ZB8,lf5;bl8tOrr34u,lf5;!%"E>rs1_L@fRf$!%$=nrrlo- +s8OB-rVlrC!)`[o!b25SoD\l6!0m<Z#0^T>s+LHsci4%H!)*'P!9Mr7"-3E^pO`F# +rrREF(tJWf!!%M#s1A:45QE/+Q2p$prr_-Y!5I^s"6LmUoDAOlYlJnGK`IA8rs"_& +s8P1]g&:pSUEu]84=0t+"XQ;2s!8uhrs$4<;?-YY-2dcD4=0Y"!@9l,rrUjR;>pLr +js<.crrFDlr;Qhn!+Y0k!WW4mW;csL!!(p*rs&'@!$tL,g%t^cF9#hBs8QR/A,lSk +,pfhrs03jrs8RcQbl7VZ,s;5-fd.rLs8Th[!5JR649-\Bs8QR/;=skh,s;/+!mCXu +r;QhP!2K2d"7mfbk4S`UK`K?CrrN0#9D=_PjkB_:VZ6_KK)^W+!al!^ec,[N!.TV# +]Dhpt!%.K,!9MZ/"5a(Y^ZPOu;#i`@rVm,b493.rf`4/5rs-ao-3+"?!+Z!-"]59Q +s#_V+rrsc3s8PprU](2s;#mBks#_V*rrG5.o`"q<4T,3\4=/5NrrQ[1U\Xok;#ljZ +rrP:_^ZPOt!!&Xirr[`N!8l6)!p3u=rW!!GA&&!B!@9&irru=Hk5TN'Pl:Ud@jTh. +K`K?rrrsc3s8QR/U](2t^Aq.2s#^:drVlmE-1q3<,s;/+!mCXur;QhP!/:(F!^$I: +o`"uH!6idh!WW3npQbg@gA_8q!!&@;s+gUU(][+WrrN0#ItI^4rrPFc-MWl,jjO/2 +hZ*Ykjo5WL!$sa]Ki',rA,cK6F9"Fub`jCRU]19549/m+^LI7Rs8Ppr;0;j<,s;5- +fd-W?beI!T;?$Rr4=0q*!B_\#rrFE.r;R#,!%"Da@fSXirs_gObl@^r,liYCUHANd +jo5A^!2$4i"+L:Nhp;<1ULPSr!!%`Qs1\PUr;QtT!0mLG-0G%'!egWurr3-J4TGF- +-2[]G,piTk4=0q*!B_\#rrFE.rVlrC!/:@N!egW.p&>(U!+YX#!egWuci4%H!)*'P +!9Mr7"8<?,5_B#lrr^"9!/K,)!WW4MK)`I_!^H`4pm(pAdf0F,!!'dprrHUUrW!!G +4JViS!JMj!!!+C@r;Qq1,ldokFT2:Ffd-VEk5Q`)rr32U;'c2B-&)<t!Dt0@rrGtC +o`"q<;>^@sYpBAM,uOU?!`:8frr32H4='t--&(F[!WW4mW;csL!!(p#rs.\?!!'e6 +K`Lrq"9=/U,pi?d!egWurr3-J4TGF-4T#-^494(74=0q*!B_\#rrFE.rVlrC!/:@N +!egWLp\t?K49/m^rrRlSbg6:j!!#[dQ2p%"rrZX/!9\t6M>mZk!!(p,rrN0#ItI^4 +rrPFc-MWl,jjO/2hZ*Ykir9,6bfo5ErrUltg%bRJbfoq`!87,H!p7_Ng]%?!bi\Ns +!p7_Nir9&[!2$4i"+L:Nhp_T+Pe[(p#)*&!s+LGMqLo$ds!8udrrRlSbl7VG,s;5- +,s;))"Zue<s#_V*rrG5.o`"q<4T59]bQ)/NrrR9BbkV2?bU!7Cnc&ZE!6idh!WW3n +pQbg@g&D/`!!&(3s,-gYpD<lieGfRM!.TV#]Dhpt!%.K,!9MZ/"5a(Y^OlL<rrN0# +T;_blIfKK+eGfTo!'L,X#0['Es.]R9q#:@W-2dcIk+hPJK`K?rrrj]2s8OAkqu6gG +-3+!--2dcD4=0Y"!@9l+rrFE.r;Qg\-0G%'"0j-uU[\9bK`K?CrrN0#9D=_Pjk9Y: +pFlRapO`F'rr\;^!2n?H!WW4MK)`I_!^H`4pm(pAdf0F,!!'ccs4I>Q!!&Xirr[`N +!8l9*![RiAqu6kB!0mNG,piKh#%Jsas'l&(rVm(D!2KRJ!6kHB"slD3s%rd$rVm): +!'L;]4=0q*!B_\#rrFE.r;Qg\-0G4,!qR^#q>UQM,pge(rrRlSbg6:j!!#[dQ2p%! +rr]G)!0;a3N;j"S(]Z8=rrN0#ItI^4rrPFc-MWl,jjO/2hZ*YkK)aL'!WW4mW;csL +!!(p*rsGM$!+X7Qs4Ll^-3!oG@fU$<rt;(,-3+#-,pge8s3)c8s8RcQFT2:P,s;5- +^AoS(s8V4D!3uS(4=0q*!B_\#rrFE.r;R%t!'KlQo/m#Jrr34fL%G?E490L#bQ[V< +s7:r/qYpVN!6idh!WW3npQbg@fDbq,!"db6s,I$\BE/%9e,KIL!.TV#]Dhpt!%.K, +!9MZ/"5a(Y^OlL<rrN0#T;_blIfKK+df0WK,ldok,ldp-bl.PH49-Zi,lf78rr3S* +,pbZ9,pge8s1\O6--ZB84T>?cUEq3K4=);-rr3!]-2dcD4=0Y"!@9l*rrus5,s3IR +A,ZE1493V*g%YONL&_1s!'L,X!egWuci4%H!)*'P!9Mi4"Le@2+Qn@VO8f<;!!#:4 +rrN0#ItI^4rrPFc-MWl,jjO/2hZ*YkK)aL'!WW4mW;csL!!(p(rs%VM;*6sNU\auo +ULQDKPihoD"m0nh4ET`ars#`<A&&%tPl:Uck&`^JFQWQ%!L/<9rrJ@<o`"rGPktC_ +Yu*V\U\t,pP_J`/oD""C^]4?*Kp;H6!l'H\ci4%H!)*'P!9Mf3"HNN_3;8%)OoGQf +!!"/1df0@K!.TV#]Dhpt!%.K,!9MZ/"5a(Y^OlL<rrN0#T;_blIfKK+K)_JC!WW3n +pQbg@ec,bc!!"_1K)_&7"HNN_&D,>0!WW4MK)`I_!^H`4pm(pAdf0F,!!'ccs4I>Q +!!&Xirr[`N!8iD.TDnrm!)*'P!9Mc2"ntOf!#X%6s-<TeBE/#<\'Y-V!!%M#s1A:4 +5QE/+Q2p$prr_-Y!5F-cf`)!Q!2$4i"+L:Nhh(m#rrN0#9D=_PjjX50E;fh<@,HS9 +RK!G_+92Bacd2Um!!%M#s1A:45QE/+Q2p$prr_-Y!5F-cf`)!Q!2$4i"+L:Nhh(m# +rrN0#9D=_PjjO//Qi6sd#\^Dns.95lhiBJj!!,(BcMmqG!$HkY]0HE/!%.K,!9MZ/ +"5a(Y^OlL<rrN0#T;_blIfKK+K)_JC!WW3npQbg@dJj7);#L@q&7C9F^SJUGQ[^^f +!!*q'bl7YKJcN7[!%.K,!9MZ/"5a(Y^OlL<rrN0#T;_blIfKK+K)_JC!WW3npQbg@ +ci4$l:kA\9!!4!upWNR:QhE[r-Gh)0BD@bmjjO/2hZ*YkK)aL'!WW4mW;csL!!(o. +s.B;m!!#[dQ2p$krrVAM5_9!/!!4!N^V'SuQFN4\jjO/2hZ*YkK)aL'!WW4mW;csL +!!(o.s.B;m!!#[dQ2p$frrCZ&^SS[FpUL6TQFN4\jjO/2k5YLSK)aO("5a(YT;_bl +IfKK+K)_JC!WW3npQbg@K)^H&T`9V0\<[-VdJj7J!.TV#g&D0+!!'L,rr[`N!8iD. +TDnrm!)*'P!9Jh4K)_MDJsNp4!9MW.![%IkK)aO("+L:Nc`$jGIfKK+K)_JC!WW3n +pQbg@K)^H&T`9V0\<[-VdJj;n!!'ccs4dPUpD<lQVuHjK!!(o.s.B;m!!#[dQ2p#u +s+:9Ds+6QHQ2p$orrgpZ!$L`^s4mVVBE/%)VuHjK!!(o.s.B;m!!#[dQ2p#us+:9D +s+6QHQ2p$nrr\Sf!*FjQh>[Sd!!#Qerr[`N!2kF`T>(F-!)*'P!9Jh4K)_MDJsNp4 +!9MQ,"@)qe37ic^iVs)UGQ7^TkGJ7ZIt@Zh!!#[dQ2p#us+:9Ds+6QHQ2p$mrs%@/ +!!!:<f7O%ars%YI+92BQ\#'*)^OcHS!!$L&Q2p#us+:9&s+:9FrrMk=JcOU,!D)CK +rrC[E^AtZnE2[^UHM3X)jb!Mas+:9&s.KAma%1d^i;`lqT9]EVnq*0tQ2p#us+:9& +s+:9BrrM;t]70fVr;Zh9Z@;nYa-6N'nq*0tQ2p#us+:9&s+:9&s4.,LTD\`ihh(mE +rrDVAQCO6@jb!Mas+:9&s+::$rrA\i!!(o.s2"^8nq*0tQ2p#us+:9&s+:9&s4.,L +TD\`ihh(mErrDVAQCO6@jb!Mas+:9&s+::$rrA\i!!(o.s2"^8nq*0tQ2p#us+:9& +s+:9&s4.,LTD\`ihh(mErrDVAQCO6@jb!Mas+:9&s+::$rrA\i!!(o.s2"^8nq*0t +Q2p#us+:9&s+:9&s4.,LTD\`ihh(mErrDVAQCO6@jb!Mas+:9&s+::$rrA\i!!(o. +s2"^8nq*0tQ2p#us+:9&s+:9&s4.,LTD\`ihh(mErrDVAQCO6@jb!Mas+:9&s+::$ +rrA\i!!(o.s2"^8nq*0tQ2p#us+:9&s+:9&s4.,LTD\`ihh(mErrDtKjdbE4pk&Nt +s+:9&s+::$rrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9& +s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9Q +rrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i +!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o. +s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9& +s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9& +s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9& +s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9Q +rrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i +!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o.s+:9&s+:9&s+:9&s+:9QrrA\i!!(o. +s+:9&s+:9&s+:9&s+:9XrrC+:rrA\i!!(pSrrMT?K)^H&K)^H&K)^H&K)^H&]Dhto +(hhP#rrA\i!!(pUrr]H,#g\,&K)^H&K)^H&K)^H&K)`I_#PT&8!%;N1?Msj.G(3U2 +!!#iIs+:9&s+:9&s+:9&s+:9]rrA,M!!(>ss+:9&s+:9&s+:9&s+:9]rrMj2o)Jbe +K)^H&K)^H&K)^H&K)^H&\,QGho)Jd:K)^H&K)^H&K)^H&K)^H&\,QL')"dk/:kJ_! +s+:9&s+:9&s+:9&s0_k,O7`JQc[u1Ks+:9&s+:9&s+:9&s0_k-pDEW)!)S:IK)^H& +K)^H&K)^H&K)`1W!0?jS!7-8sK)^H&K)^H&K)^H&K)`1W!V[H,!!#iIs+:9&s+:9& +s+:9&s+:9UrrA,U!!(>ss+:9&s+:9&s+:9&s+:9UrrMj2qZ$UmK)^H&K)^H&K)^H& +K)^H&YQ"T`qZ$WBK)^H&K)^H&K)^H&K)^H&YQ"Xt)#XF7:kJ_!s+:9&s+:9&s+:9& +s/l;$O8T%Yc[u1Ks+:9&s+:9&s+:9&s/l;(pD<l1:kJ_!s+:9&s+:9&s+:9&s/Z/% +NrT1+K)^H&K)^H&K)^H&K)^H&X8`7q(f5haK)^H&K)^H&K)^H&K)_hM!KYQYs+:9& +s+:9&s+:9&s+:9&s+:9&s+:9&s+:9&s+:9ds+8"U^AuT3s+:9&s+:9&s+:93rr>$1 +!1NrgBS-89s+:9&s+:9&s,m<]hgtis!!"-ns+:9&s+:9&s+:95rr_-Y!-j+1T>(Fu +!$HmnK)^H&K)^H&K)^u5"5a(YT7[*8rrQR.+G0WFs+:9&s+:9&s,m<`hZ*YKK)_JC +!al!NK)^H&K)^H&K)^H&OoGO@!!&XCs.B;m?iV=$s+:9&s+:9&s+:95rr_-Y!2"lC +TDnt#!$HmnK)^H&K)^H&K)^u5"5a(YT7[*8rrQR.+G0WFs+:9&s+:9&s,m<`hZ*YK +K)_JC!al!NK)^H&K)^H&K)^H&OoGO@!!&XCs.B;m?iV=$s+:9&s+:9&s+:95rr_-Y +!2"lCTDnt#!$HmnK)^H&K)^H&K)^u5"5a(YT7[*8rrQR.+G0WFs+:9&s+:9&s,m<` +hZ*YKK)_JC!al!NK)^H&K)^H&K)^H&OoGO@!!&XCs.B;m?iUu:YlN%#s+:9&s+:9& +s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm +^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XC +s.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H& +K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfn +K)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lC +TDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9& +s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXN +s+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8 +rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YK[Jp8lUTjb!UQiUp!al!ApQbfnK)^H& +K)^H&K)^H&SGr]K!!&YVrr[s;L$$e_"$?P`FOC*hYrqq1!Frn1rrZa2!'J-u!al!A +pQbfnK)^H&K)^H&K)^H&SGr]K!!&YWrr@cP!!4HVk0s>4,ldp-dJj1mq#CFmk3`0N +49,@-r;QkQ,pf>0rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKli-rIqu?dE;5;\A +"!mpI4OX60bkD)<--YfW"$?P`-2miDg&:sO--Q;i?iUl7Q2nXNs+:9&s+:9&s+:9@ +rr_-Y!2&TW!'L&W!@<HOrrXPI!'J^0!6kEB"!p&l-2dfE-1gU*"$?P`-2miDbl.SC +-0EGO!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&YWrr>1U!!,3sg&D.#!!#.0rrC:B +!!%`PrrJl@xxxxxx,EJP!!">CrrZ*u!+X4P!al!ApQbfnK)^H&K)^H&K)^H&SGr]K +!!&YWrrtRc!%"mI-2RZBL"cP/,ldp-df0<^rVuqPrVm#E,ldokn,EJP!!">BrrLg+ +b5VNN!#,*m!5='bK)^H&K)^H&K)_A@"5a(YTBlL_49,@-s8V4k-2[`CA*X'pbh;Xg +"!mpI4OX60L&M&PPl1O`49,@-n,EJP!!"=^rrQR.'DIdm^4QB:s+:9&s+:9&s.')k +hZ*YKli.&L!!">CrrI3fr;Zh>q#:?/re1BJk55/a;#gU$s5q(M^\[s4,ldp-q>UQ@ +P_HmLrrV>:^\Ig1UP7k%rr@cP!!(7@rrY@`!%%LA"3cIQbkh>A49,@-r;QhnKsCLS +"m0nh4Cb/arrTrhk4nrWPa(J5!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&YWrrY@` +!%%OB!R*\)!!';$rrJ?1qu?dE;;(sK!87>O!^'=+rVusFFSu.@,ldp-qu6\N-2dfE +-&)?u"Qh!1!5JC1"-`cc-1h-:L&M&Pbl.PEfd-Uu-2miFo4'*F!!,3er;Qj]!!">D +rrB>'!!(^MrrJl@qu@!KL&_1X!!">:qYpY-!!#m^rrQR.'DIdm^4QB:s+:9&s+:9& +s.')khZ*YKli.&L!!">@rr>1\!!#.Zrr?R(!!FV1s8U=:!!$O-rrXPI!'L2Z!'L&W +"*FSCPl:X_4So'X-2mlEbk1o8L&M&Pbl7VCbU*5g!/:FP!R)kc!!';&rrY@`!%%UD +!/:CP!/:CO!2K;h!d+H>rVuq.qu6Z2rVupEli.#o!#,*m!5='bK)^H&K)^H&K)_A@ +"5a(YTBlLZ49,@-q>UKX-2mlEU]18nPl1U]-2dfGFT;Bbo`,!,rr3'H!!#.[rr?R' +!!C"9jsC!,!-J/=!/:CP!'KlQ!+Z!."Ja2*;'l2A!%%UD!'L#V!%%UD"$?P`-2miD +L&M&PU]18ofd6Ut![TrTrW!!^s.fMm!3uJ%!)`^q!+Y?p!al!ApQbfnK)^H&K)^H& +K)^H&SGr]K!!&YWrrY@`!%%F?!/:CP!'L8\!%%UE!/:FP!-J2?"$HV`bkqGC4GAK! +rVupqrr3'H!!#.\rrAhm!!?)n^HDJq"&]*uL&M&Q-/&7s!%%UE!2K/c!'KuU!@>M[ +rr?R-!!?`GUF#m>!0mK_"$?P`-2miDL&M&Pbl7VB;>pOqA,cK4YpC]ks8Psq!!#.[ +rrBh5!!+D.li.#o!#,*m!5='bK)^H&K)^H&K)_A@"5a(YTBlLZ49,@-q#:T],ldok +s8S>_!!IEDs1_G0!!AJcs31EA!/:CO"!mpI-3!oH,ldp-rr2s\rVuq.rr3,m,ldok +rr2s\rVupqrr2tPrVupEo)A\Pp](=Wbl.PA-2mlEPlC[_^]"354T>?_49,@-rVljp +rW!&Es8Tk5!!#.UrrLe!rVuqPrr2sqrVupqlMgon!#,*m!5='bK)^H&K)^H&K)_A@ +"5a(YTBlLZ49,@-p\tXJ!!">Fs#^8]-1dloqu?^ZrVlsG!!#.Zrr>1\!"R6Qs!7XF +4TGHD,ldokoDS[hA,ZH1bl@^<r;Zr7s8ODE!!%`Drr>1Y!!4H/Pl1O]U](5n4T,3] +,ldokrr3'_!!">Drr>1\!!CIFs&&aq!5J7-!+Z!."""!I^\n-4^Zth#?iUl7Q2nXN +s+:9&s+:9&s+:9@rr_-Y!2&TW"$?P`-27EH,ldoks8OAF!$rrh!!+C"r;QjF!!">C +rr@cP!"$mLs!7XF4TGH*rVup\r;QbNrVurBrr2sqrW!!^s-3K_!%%18"$?P`-2u*g +k5,)XL&M&PL&CrQ49,@-rr3'_!!">Drr>1\!!^[Is!7XF-2%9=o-OA9!d+H>rVupq +l2Lfm!#,*m!5='bK)^H&K)^H&K)_A@"5a(YTBlLZ49,@-q#:T],ldoks8ODA!!+C" +qYpXD!!">Crr@cP!"$mLs!7XF4TGG8rVuqPr;QbNrVurBrr2u5r;Zkn4T5<\L%50F +,ldp-pAY+TrVurBr;Qj]!!">ErrY@`!%%UD!'L5\!mL\grVuq?o`"oFrW!!G^ErjZ +!5Idu!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&YWrrY@`!%%F?!/:CP"&]*u-2[`D +4JV]O"!mpI-2dcCFT)7Hbl@\h!!#.]s.fPn!/:@N!/:CP!6kEA!+Z!.!%%UE!%%.7 +"!mpI4SJdTA,ZH.bl%JC49,@-rr3'_!!">Drr>1\!!:CEbl.SBL%G<E4T5<\-2mlE +;<\#]?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2&TW"!mpI-2IQAbU*5g"/Gnr-2mlF +;8;i)"!mpI-2dcC-2mlNg&M'u!!#.]s31HB!'L2Z"$?P`-2dcDjsBm)!/9qB"!mpI +4SJdTL&M&PFT)4Bjs:!-4T>?_49,@-rVlj[rW!#Ds4RAO!+YX#!2KAj!5Iat!al!A +pQbfnK)^H&K)^H&K)^H&SGr]K!!&YWrrXPI!%%LA!R)kh!!#.\rr>pq!!%-<rs<cn +-0G7-,ldokrVlk^rVupErr3'H!!#.\rr=AE!!&enrr?R.!!#mnrr?R,!!">6rrXPI +!'KuT!87>O"XVCms78AP!!&8_rrY@`!%%UD!'L5\#L*5J,ldok^]"07k$pNKqu6XY +qu?^okPkTk!#,*m!5='bK)^H&K)^H&K)_A@"5a(YTBlLW-2mlFA&&#e!i'6Or;Zi4 +rr2u5r;[!I;2']d-2mlHPlLb0rW!$H4?Oqg!!%`PrrXPI!'L8\!/:@O!^&Rkr;Zi4 +qu6]Z-2dfDFRT53,ldp-p&>"hrW!$H4?Oqh!!">DrrY@`!%%UD!'L5\"3gfFL&CuV +;2'^6,ldokqu6Z$qu?`3kPkTk!#,*m!5='bK)^H&K)^H&K)_A@"5a(YTBlLW-1_*: +U\t,lA+fm*-0G7--2.B>4T59^,ldp-rVlj[p](;9q>UG:rVusFk3r<P,ldp-p&>'G +-27H?Z2O\)49,@-rVlj[rVurBrr2s\pAb1>qYpOXrVup\k5PKj!#,*m!5='bK)^H& +K)^H&K)_A@"5a(YTBlLWFS,V7-):>:!L+o+!!,48rr2sEp](:Vr;QjF!!$O-rrM7E +q>^M*q#:=krVuq.mf*Ad!!$O$rrKk\qZ$XCU\t,o49,@DrVm"S!!">-rVljpq#CFm +g%t^K-2mlEUZVRX?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2&QV!l&4kq>^RC;;(^D +#F&(J,pbZq^\n*3-2moC,lp,mqu6bn4Ak8<rr@cO,lplXq#:N[,ldokk3`0LKn]*t +!Tmnj,lqN<qu6cB4?UCVrrRmOZ2=P%UJ^t9!Frn?rrAhn!!#.CrrQR.'DIdm^4QB: +s+:9&s+:9&s.')khZ*YKkPkb$Ki'sdKtlgN"!mpI-/8G"A,ZH.A%2I<k4\fT4T5<\ +UZMLW?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%:2"!mpI-/8G"-2mlE^T@G8^]"35 +-05(-?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%:2"!mpI-/AM#Pl:X_4KJJ^;>pOq +FQEH'?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%:2"!mpI-/AM#4T5<\UTFJ!js:!- +-0F:g!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y2rrXPI!%$J$!87>O!%"]G!0mH_ +!'K<A!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y2rrXPI!%$J$!0mH_!+W)0!)`^q +!2JTS!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y2rrZ*u!+Xjb"Qh!1!5GT7"0hh+ +-0"q+?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%71!L/i'rrV>:^T%57^P1h0rrQR. +'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K +!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H& +K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!A +pQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y +!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9& +s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y;rr^rubiXNW +ec,\Y!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT@*Z>KdH]u![Tt6k5PJE^]+66;'k&u +!l$&*qu6YMrZqSBg%PFHUHJN%!E%PErrLeMrZqPSci4&S!#,*m!5='bK)^H&K)^H& +K)_A@"5a(YT@3`G@fRfsKnWAM!0l^I!nelRrr3!r-/SY(bU!85r;R"3!)\Gl,ph7> +rs4;Y-$4iN!%$=ors.4'-$4iN!'JX.!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y? +rr^pS4S/OO"3`&;k3;mIbQ*@NrrfSQ!!(7ArrTq8;?$RsbU$-^rr_C04S/RP!i#`m +q>ULn!5JO5!egW=dJj8U!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT@<fAK`Hi(rrQ[1 +U\k&kk4\fTbl%JBbQ*@irrCaGrrC:8rrlm4-"?r!rVlq/!5JL4!`8sNqYpV]!/:@N +!@9&grrVd<4T59]bQ'cQrrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKe,KK6!+Yp+ +!qXY-rVlk-r?VH.r;R>];'c2g;;(tH,lf5;L&Y!rrVm(s4='tR;<IlX#DFJq@jM+$ +;>:(pbU$cjK`K?qrrFDlr;QhP!0m?[!qX1Ar;QdD-1h-<^Aq-YrrQR.'DIdm^4QB: +s+:9&s+:9&s.')khZ*YKe,KR5,lhGip\tI\!+U_:490L&rt3!l-$4i_,ph6/F9#0l +^]-DBrr3XR!%!>Q@xxxxxxxx!4?S=O49/7Rrs&)Ws8RcQbl.PB,s;,*!mCXuoD\m, +!'KoR"6M]G^X<&_?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%^>#GWRF!$sa]g&1jO +@fV5]rs(Xdg&M(7!5JO5#,;0.s3(Isrr33c-3+"u!'KlPrs,;!;?-ZM!'L5[![T/T +p&>)I!6kEA!@9l+rrUCE4S/RS492Y[rreQK,pf>5rrQR.'DIdm^4QB:s+:9&s+:9& +s.')khZ*YKd/O034=0t,!BeU*rrFDlr;Qu9!-J7o!'L2Z"bj5]bQ*@rrrtS3s8R0@ +U\t,r494(7K`InHrrQ$tbk:u;K`K?qrrFE.r;QiB!'KoR!^$Hmp&>2*4?NU+bgHFl +?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%O9$,:R.!%$=uf`3>rKa)W!4TD/VL&(`M +bQ*@rrrtS3s8P1]g&1jSF9')UK`K?qrrRlSbk:u;K`K?qrrFE.r;QiB!'KuT"7nVT +A+BR#UAuUfrrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKb5VZU!)`d?!!)jA"B#2Q +!/:7K!mCXurr3-a-3+!--2[]HK`Hi,K`K?qrrRlSbk:u;K`K?qrrFE.r;QiB!/:1I +"3`%kA+0F!@fW:PrrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKe,KG24Sf!\,piT8 +!'L&V!i#aLq>UN?!/:FP#!=43s#^;7r;QtT!5JPf!6kEA!egWup&>)I!6kEA!@9&i +rrSDbL%tZMYpBCFo`"p_r;QhP!/8l$!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&Y? +rrOJH^\e$8o-HO!s!8uhrs%VMg&K7r;>gFt4Al.&!/:FP#!=43s)\79r;Qs`!87C+ +!6kEA!egWup&>)I!6kEA!`8sNrVlq/!6k9="3`&;Z1\+ubU$-arrQ[1UXK/D?iUl7 +Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%a?",-_$^\n*:@fV5_s%rc\rVm+4!/:IQ4=/5N +rs$4<;?+i?FT2:E4=1%-^ApCprs-:=4TGG8!6kEA!egWup&>)I!6kEA!i#a*rr3&D +,s;#'"7mfbbk(i9,pge7rrUCj-.2_o?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2%^> +$"Er84EQ9e,lg(,rs7a5!+X6f@fSXjrt2L9-'ZW<,ph7Ef`3=?Z2Zp4rr3F;!'I%# +KdA%[s8RcQbl.PCK`K?irrRlSbl%JG49/m8UEooFrr35I,uO^BF9!Wa49/7XrrFDl +rr38!!%"DaPU-=)dJj8U!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT@*Z?KdA&E!!+C" +r;QuS;'c2B,uOU?!O4cd!!,4+rr314,lhHT;'l2@#)+?'!$tLqrr3%R--Z>f!ehrE +p&>)I--Z8d"_/hY!%"E=rrpUm;?-Ynpa,q>!@9&jrrJl@rVus]Z-`LP?iUl7Q2nXN +s+:9&s+:9&s+:9@rr_-Y!2%U;"6RhOg%YLIbfok^!nkfNqYpQKp\t<=bi[^\!p7_N +iVru4bh:;A!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9& +s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR. +'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K +!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H& +K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!A +pQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y +!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9& +s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7 +Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(Y +T7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H& +K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m +!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YK +K)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XCs.B;m?iUl7Q2nXNs+:9&s+:9& +s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H&K)_A@"5a(YT7[*8rrQR.'DIdm +^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfnK)^H&K)^H&K)^H&SGr]K!!&XC +s.B;m?iUl7Q2nXNs+:9&s+:9&s+:9@rr_-Y!2"lCTDnt#!#,*m!5='bK)^H&K)^H& +K)_A@"5a(YT7[*8rrQR.'DIdm^4QB:s+:9&s+:9&s.')khZ*YKK)_JC!al!ApQbfn +K)^H&K)^H&K)^H&SGr]K!!%7q^Rr7B8,s=tQ2nXNs+:9&s+:9&s+:9@rrCr.!1Elf +'DIdm^4QB:s+:9&s+:9&s-s#g."VGg!!"\HQ2nXNs+:9&s+:9&s+:9?rrDfd^Aru% +E!0#@!"rnaDua@LDub%SQ2nXNs+:9&s+:9&s+:92rrB=<Q2hp(!!#g:Q32(9!%O_/ +!5='bK)^H&K)^H&K)^l2!3s8(r;Zgjad)oHrVuq2UQtnoK)^H&K)^H&K)^H&NrK*a +^6\]t!)(G"r;ZgjUQtnoK)^H&K)^H&K)^H&NrK*a^6\]t!)(G"r;ZgjUQtnoK)^H& +K)^H&K)^H&NrK*a^6\]t!)(G"r;ZgjUQtnoK)^H&K)^H&K)^H&NrK*a^6\]t!)(G" +r;ZgjUQtnoK)^H&K)^H&K)^H&NrK*a^6\]t!)(G"r;ZgjUQtnoK)^H&K)^H&K)^H& +NrK*a^6\]t!)(G"r;ZgjUQtnoK)^H&K)^H&K)^H&NrK*a^6\]t!)(G"r;ZgjUQtno +K)^H&K)^H&K)^H&NrK*a^6\]t!)(G"r;ZgjUQtnoK)^H&K)^H&K)^H&NrK+F^?,:n +!-63Cr;Zh<UZDLDK)^H&K)^H&K)^H&K)`smr;ZhIaoD;>!.TV#K)^H&K)^H&K)^H& +K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H& +K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H& +K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV# +K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;> +!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhI +aoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8 +r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H& +K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H& +K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H&K)^H&K)^H&K)b*8r;ZhIaoD;>!.TV#K)^H& +K)^H&K)^H&W;cn9Xi8'R!!%Mjs8;otItI]Ps+:9&s+:9&s+:9Mrr=dg!!%5bs8;ot +?cBb[Y(H\*s+:9&s+:9&s+::6rrBsN!!#C.s1\O7"Ik#CK)^H&K)^H&K)^H&l2LaF +^&S.0aoB'T!#^CgK)^H&K)^H&K)^H&l2LaU^An9Kn&bS0$,6H?$A/;0s+:9&s+:9& +s+::8rrA\i!!&q9^AuEsrrI?F^]4?NK)^H&K)^H&K)^H&K)b*8!2'2i!8iY5!Ul`$ +^Aph(!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9& +s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-n +s+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`i +hh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9& +s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+ +!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O` +TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9& +s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mN +rr?I+!!"-ns+:9&s+:9&s+:9&s69O`TD\`ihh(mNrr?I+!!"-ns+:9&s+:9&s+:9Z +rrC[9^B"#RrrA\i!!(oAs6@?!a3Xbc@/^-++G0WFs+:9&s+:9&s1/.1Va0DF!D)D# +rrA\i!!(oErrVqM.-LX4#^H*lrr?I+!!"-ns+:9&s+:9&s+:9_rrM:Rj8]3'n'V.8 +TD\`ihjXQGa!g!K!*I\L!+>d+!$HmnK)^H&K)^H&K)`L`#,`"4!"`PAlG!F/!!$uc +rrA\i!!(oGrr@<C!!+L/lG!J*-ia7Ve,KDUrVup@K)^H&NW0&i;<EK1K)^H&[JpEV +#QOj4n)s]P5QDqSrrA\i!!(oHrreYg!!nACrr_Ei!-$Ee!+>d+!$HmnK)aX+!b4@- +p&>)g4L)m*"(M<2;?$Rqbk(i8g#dndK)^H&b5VV=0E;Bfjo5F<!!)K9rrA\i!!(oI +rrh3b!%?I\rrP.[8CRS=@/^-++G0WFs5!\W@fQKTpAY9K,ldqua8Z.SrW!-bs5kU- +--Z)_"(M<WZ%E"-s+:9orr[`N!/KY8"1J71T@3`>TD\`ihjscL5QCf)jSo<q!!qK3 +rr?I+!!"-ns+::,rrY@`!%%@=!+Z!.!6iL`!+Z!.!i,dLrVusFZ2">!A,ZH.4G*Tb +s+:9prr_]q!''$="SW`5!-$D:!)NOn!,oDt!f+P2l2Ljp!!%9(rr]_1!#X48!&4BP +!"cSg!gg[RK)_qP"$?P`-2.?@,ldok`r?5h!!">Fs1eL4!@?Fqrr@0>!!%_)s+:9& +s31KFT)\khir9"fJcPcM!Z5nFm/I/q!!)3Arr?_a!<)s!.%c+kY5\Sd!!">=rrXPI +!%#\c!0mH_!/:FP!2KJm!'L/Y!3uJ&!+UW\K)^H&bPqZh!!r>XrrL/2JcPcM!>rlE +rrP.[5iDYCT.kisrVusikCW`<rrY@`!%%C>!6kEB!%#\c"$?P`-2dcCU\t/mA,ZE. +jsC!,!'Gl5K)^H&b5VNF!&0$)hu<bmO!su-!-mr3!Z1oVK)ad/#OfEW(]XOI[t=Xb +rrY@`!%%C>!6kEB!'KZK!R06RrrBh5!!$O+rr?R-!!%`Prr>1\!!+D.m/I+>fn06U +s+::0rrPFc5_B$krre)_!!&ASrrN0#ItI^Vrrqk!!!!;^K)`Rb!Mac7491*6rrY@` +!%%C>!6kEB"[)hbk(USFrsb`Wk5YHY!!';(k.cVbpAY--re1BJk4S`S;>pOq^\[s1 +4T,6]U]4j&!!';!rrCaOK`RFkqu7"F!!%`Qk&`^34JRN.K)^H&l2LfM!'l/9g]%E. ++92])nG`Oi!.TV#g]%AZ!!#99s1nX8UF#^9!2KPn"$?P`-27E>bl.SH4TFOi!!'e1 +rrnVe!%%ZurW!!^;'l2A!@;jarrJ?1qu?dE;;(aE!5JL5!)`Rl!V7W:!!+C"r;Zh- +q>UK14So*Z4L+kb"XO-K-)2da!!%+ms+:9&s6BUc5QF'$s4[JT^An7!nG`Oi!.TV# +gA_8"!!&@;s2+d9Z1e4uL&V)S,ldokq>UNYbbP.;!^-LIrVup\qYpOArVuuCbk;#: +A,Q?,A,$$)-0G%'!)`^q!5J=/!R)kd!!#.WrrAhg!!';'rr=A>!!+D.K)^H&K)b0: +!^H`NK)aO(")%Z7fCAkB!!%M#s4[JTpF$"aK)`^f!'L5\#:2KBF<pnePlC[h,ldp- +s8UceKfo>\qu?g]s5kX,!!%-=rr@cP!!5:_bk1r9^]+65Pl1U]-2dfDFSc";Z2O_' +;>1"iZ24M%-/&.p!SJdu!<"5C!!#.\rr=AB!!+AlrVuq_K)^H&K)b0:!^H`NK)aO( +"5a(YJ+<O?!!%M#s4RDSLB%=pK)`ag"=4$J-1h-9!p2U-rVm$I!!"<--1q6?;?-ZM +rVusFg&:pN-2mlGU]8R9!!>?;Kk()^!)`aq!%%UE!/:FP!-J2?!'L,X!'L5\!5J4, +!/:=N!3uA"!)`^q#\3#ss03jM!%%XE!%%OC#!DMK,ldpeK)^H&K)b0:!^H`NK)aL' +!\aU>nc&Xj!.TV#g&D0C!!&@;s24j:4T5<];;(aE!%%+7!/:FP!'L5\!)`aq!/:CP +"""!Ibl%MAL&M#U,ldoks8S>_!!IEDs1_G0!!&8\rrAhn!!$O$rr>1[!!+CiqYpQK +rW!*as8V4k-2mlE;?$Rq-2dfD4T>?_,ldp-K)^H&K)b0:!^H`NK)aL'!al!Vnc&Xj +!.TV#f`)!a!.TV#_uB_Ar;ZmF;8;u-!%%F@"XPHWFG4i9!!%`PrrAhm!!C"9s!@XE +!/:FP"!mpI4T,3Z4T5<dbl9d*!%%634T#0Z4So'\,ldokk4S`S4So*Y4So'XL&M&S +Z+j-^r;ZjEg&D!O-2dfD^]+68,ldp-K)^H&K)b0:!^H`NK)aL'!al!Nnc&Xj!.TV# +f`)!q!.TV#_Z'V2qZ$Xok5>5Z-2mlI,s5\%bl%J@xxxxxx&M#O;>pOs4TCZF!!">D +rrXPI!%%RC!/:CP#0d)n!!";kqu?aDL&1fLL&M&PA+fj%A,-*)A,H9+4T5<\-2[`E +-"H*9rr=AE!!#.\rrC:B!!#-5s+:9&s6K[d5QF'$s4I>Q?iV>>rrN0#J'7iqg!#/( +UY1q4![%JmK)`[e!P_M0!!+C@rVlsG!!#.UrrC:B!!%`OrrBh4!!/iWrVuqPrVlsG +!!">Crr@cP!!:CE-2ITB-&)0p"nO#?!%%71rr?R-!!-Sor;Zi&r;QaZq>^RCA*3^h +!Tk^-!!&8_rrC:B!!#-5s+:9&s6K[d5QF'crrR:)U\k&nUEr%UVZ-^*!$Lh3!WW4M +c2Rgt4So*Z4L+b_!l'H(U&P0:!.TV#^]+AM@jV'R#J^<=js:!-4SSjUbl.SBL&CrN +A,ZH.-2mlE-2dcF,ldokr;Qb=rW!#Ds!@RC!Bd.Orr?R.!!%`Hrr@0>!!>@`s&&aq +!@?n,rr>1Z!!4I#k5,)Xbl%MAbl7VBbl.SB4G*Tbs+:::rrPFc5f3O'K`D*!qu6aE +!!#lnrrQR.+S#I5!!%Mnrr@cJ!!$O,rrCaO!!'d.rrO;CItI^6rrM7ErW!$ts8U=B +!!$O'rrC:B!!#.ZrrM7.qZ$VMr;QjF!!">Crr=AE!!:jR-2mlF;8;i)"Qh!1!%%@= +!2KJm!'L8\!V7W:!!#.[rr>1\!!,3Wp\t6;rVupErVm#_,ldp-K)^H&K)b0:!^H`N +_Z'T^rVuqnrVllArVupEVZ-^*!$Lh3!WW4Mc2RctrW)pDr;Zh>rVlkmrVuq_UAk9; +!.TV#_uBbjbl%J@xxxxxxxxx*rVuqPp\t6;rVup\qu6Y+qu?^Cqu6aE!!">DrrA;_ +!!=PIs&&aq!-J,<#';.;k5YHkrVuqPp\t5gr;Zg[r;Qc%r;Zh-rr2t_rVusrk5>5_ +PU.W\s31HB!%%RC"!mpI-%c/Ks+:::rrPFc5f<U%g&1mNA,ZE-L&CuObbtIB?iV>> +rrN0#J'IuqK`D*8rr3"o-2mlEg&:pP;'e>urrO;CItI^=rrfS,!$tMAK`F77!!?*u +s31HB!/:1I!6kEB!'L/Y!Tk^,!!%-<rr=AE!!=N04=0q+",6dT^\n-9,uKAM4=0t, +#*f/f,ldokp\t5gr;ZjEbkqD?A,QB-U]18n-2mlJ,s6m8;'l2A!`B!ArVupEr;QaC +rVurOK)^H&K)b3;!^H`N_uB_$r;Zg[rVlj[r;Zh^VuHg+!$Lh3!WW4Mc2Rm"!!#.[ +rrgOl!!%_ArrO;CItI^=rr@cH!!C"9s+UFP!/:1I!6kEB!'L,X!-J2?!@?n*rr=A> +!!#.[rr?R&!!=P0s+UFP!/:4J!Tk^-!!+Ciq>UFWr;Zr7s8Ske!!9G*bl.SB4T,3Z +4T5<\b_#kHs+::;rrPFc5f<U%A,QB--2miD-2dfDL%#$Cfho#errQR.+S#I5!!%Mn +rr[rT!'L2Z"$?P`L%kTPUP7D$s5qPLXT&>E!.TV#`;]l04S\sX-):J>!2KMn!2K8f +"!mpI4So'X;>pOqA,?3*-27H?4T#-ZPU6,*#X$f?s#^8]-0G"&!6kEB!@>tbrrL=i +rVuqPrr3#64S\sX-*dIL"!mpI4T,3ZFT)7?b_#kHs+::;rrPFc5f<U%4T#0]g&M)e +qu?^ZqYpT2A,[bT;5=*i#UKHs^N;Ra4GCZP!al!Nnc&Xj!.W8n",-^T4T59_o-FA: +L&V)`fd.r>s8Th6!'Kj_,ldokbkqD@^LR6h!E#Wjrrc1]^]0#d,m;Hl;'i"6rrQ%D +L"H>++96nCs2+d:PW\mj!^(Ser;Qh?4Ce'a"/@t@bkqDDjs:!--0G((!%%UEr?VJ, +Pkb7`PYjOh,s6:arVlss!!$O&rrY@`-,90R"MZ5_-,9BX#GYck,pbZ`U\t,o;#ho; +r;Ql6,lg&Zs+:9&s6K[d5QF'err=AC!!B"rs'ts,!%%OB!+Yj*"$HV`bl.SB-2[`C +4N%1#?iV>>rrN0#J'IuqK`D*8rr3#64T5<\g&D!UK`D*8s8RfP!!">C!!#.Zrr?R* +!!bXds-*K`,piHh"[&"L!%$=rrr\Jc!%$7s![%JmK)_>?!+Z!.!+Yj)"!mpI-0>.- +Pa(h?!6k'7!p54!mJd42k5,)Yk0/GWK)^H&lMgoN!'nL&!6k<?$"O#8,ldok!!">C +rr>1[!!+AlrW!#Ds313;!-H0Z!al!Nnc&Xj!.W8n!/:CP![TrTr;Zh>rVm(U!!#.] +s31??!%%UE!6kHB!'L2[!@9&k!!:CEL&1iQ,ldokg&:sO4T,3],ldp-fDbmp!.TV# +S,WI7rVur5q>UOC!!"<ss+:9&s,R*\5QF'frs=AZ!$s`-!'L:rrVuqPrVurBrr2tP +rW!6e^]1P=!%%[Fbl%MG-$4i'!!"=`rrQR.+S#I5!!%Mnrr@cJ!!+D.rVm(3!!#.] +s31B@#aG?O!!%`Qs+UFP#s?!&YlFbMs8RfO!!bX$bQ%Vhs'u$.!2KPn!/:CP!2J0G +![%JmK)_A@!0mH_!'L&V"!mpI-%c/Ks+:92rrPFc5fE[749,@DK`D*!s'l$/-1`D_ +!0mK_"!mpI4T>?_K`D*!rr3'H!!$O.rrhp>!!(6^rrQR.+S#I5!!%Mnrr@cI!!+Ci +rr30b!!#.]s1eL4%!;OL49,A8s8OAF!'L8\#)*$W-3+"!rW!@:s8U:C!%%[:,ldok +rr3'H!!#.4rrO;CItI]jrr>1\!!&ehrrXPI!%!6sK)^H&NrK/G!'nL&"=4$JFNj^a +&>LNO!+Z$k!!$O/s.]Po-0G4,",-^T4T>?_,ldqhrVlsG!!%_lrrQR.+S#I5!!%Mn +rr[rT!%%Vu!H]Xe!"(%Ds8P1]!-J8@L&M&P-3!oN49,A8s.]Po-0G4,$&&?Z4TGG8 +!!">DrrlmpU]:@JrW!"Rs-3K_!2J-F![%JmK)_DA!87>O!%%C>"!mpI-%c/Ks+:92 +rrPFc5fNa'U](5s^],S[!'L5\$bu^O!!">Fs+LFQ-2miGK`D*8rr3'H!!%`OrrY@` +!/8Dl!al!Nnc&Xj!.W8n",-^T4T,3ZPl:XhFT;A'!!%`Qs+UFP!-J5?#Wr(eL&Zi, +!%%UD$&&?Z4TGG8!!#.Urs1^e!%%5!!!#.3rrO;CItI]krrA;_!!$O'rrXPI!%!6s +K)^H&NrK/G!'nO'##P@#-3+!Bqu@-Os8S;`!%$e-K`D*8rVlu7!!#.\rrXPI!/:CO +"$?P`KuO&n?iV>>rrN0#J'IuqK`D*8qu7(7!!#.]s#^8]L&_1,rVurBrr36d!!%`Q +K`D*8rVm2=!!#.]s+LFQ4SSjUU](5n4T5<\UXfAG+96nCs.0/mjs:!-^\@a1;#gT+ +K)^H&K)^l2!^H`N`W$,g!!#.]s-3E]"(VB2g&:sTPlHF;!%%UD"3^`F-3!oH,ldq! +rVlsG!!&8&rrQR.+S#I5!!%Mnrr[rT!'L2Z&\gF.!)`dr49,A8s8QR/!%$e,rs1^e +!+Z%_!!">Drs?mL!%%[FK`D*8pAY+Tqu?^CeGfRm!.TV#SGrZQKtm<\!L/h#s+:9& +s,I$[5QF'hrs7a5!!%-@s5kX+!!'e5rrj\K!)`d2rVur5rr3>1!!">-s8OAF!/:FP +!+Z!.!85?k!al!Nnc&Xj!.W8n#_`6Y4TEX#@jV'R%);iB49,A's8P1]!%%UD"]57" +4TE1q!!'e5rs>q1!%$e-K`D*8pAY--qu?_NeGfRm!.TV#K)^H&K)^H&QN%"O!'nR( +!6kEB!0mK_!'L5\!%%UD%8d**-3*uk!!"<eKi'/q!"!08s!7XF,pbZ"rVupq`;]mH +!$Lh3!WW4Mc2RctrVupEq>^Mjrr39e!!#.]s'l$/-2miQK`D*!s8OAF!$u`@;'l2A +"_7Rd!!#.Srr>pq!!"=orrO;CItI]Ps+:9&s+:9:rrPFc5fWg(bl.SBbl7VBFT)7? +L&M#OL&M&Rbl=I4!!=PIs!@I@!@?mHrrQR.+S#I5!!%Mnrr@cJ!!,3srVm0d!!#mr +s+LFQ-2miJPQ1\0s8Skg!!O\KK`D*8p&>#erVuqPe,KIl!.TV#K)^H&K)^H&QN%"O +!'nR("5*YS-2miGjs:!ir;R&b,ldqhs8T>Mr;['bF?BOLs8ODA!!,sM_uBdG!$Lh3 +!WW4Mc2Rgt-2dfG,pd'9qu6u-,pfhrs-*K`;>pLsf`2!urr3#(-2dfM4EN[c-3'_? +!)`Fh"&T$u-.;ep+96nCs8;ltPb[jM!L0A,rrL@+K)^H&K)^H&hu<aC!'nO'!jRI4 +r;Qf[bkh>@Yrma<rr^K0PhH'9$^BfRs!7XFFHhKDftm[i?iV>>rrN0#J'@omk5ENn +rrSF=k5>5\P_Ifgrr^K0PhH'9"dJ0Ls-/61rrhI1!!%`$rrO;CJ%GX\g!&a]!R/dG +rrY@`!-Io6"$?P`FOU6l,lf7Ro)A`q4T$K+A&!WqK)^H&K)bWG!^H`NU&P3@!!%_d +rrQR.+S#I5!!%M.rrcg3!%$dUrrO;CJ%P^_K`D*8q#:DL,uOI;"(M<2;;qNW,ldp- +p&>+?!!#.2rrC:B!!%`Drr=A@!!,sZU]1F+,s9DmrrIgqg]%B<;'f(ks+:9grrPFc +5b\2[,ldq!^&J.A!$Lh3!WW4MNW0),!!$NVrrO;CJ%P^\4T5<\PktC[Z2O_'A,?3* +^]"35-/nk+,ldp-p&>+?!!#.2rrAhn!!%`ErrC:;!!+Cih>[Q=Kqm9"!p533q>UGZ +rVup\ao;I-!!#mZrrTrh^\Rm0;>pOqFFsOEs2=p=5QF'CrrXPI!/8,d!al!Nnc&Xj +!.U%/!2KMn!5Hq]![%Jm]DhkQrVup\qYpOXrVupEqYpP*rVup\iVs!+!!"><rrXPI +!'Jd2!/:CP!0m*T!6kEB"!p&l-2dfE-1g!n"!mpIPh?!<,ldq0qYpPLrVupEb5VIV +rVupEkl1XtrVurOqYpOXrVuq.K)^H&`;]m(!'m7X"!mpIKt[Kf?iV>>rrN0#IuaO2 +;#gSBd/O.i!.VW\!87;N!87;M!2KGl!878L!%%UE!2JNQ"!mpI-2%9?,ldp-eGfN& +rVurBoD\g7rVuqPrr3"o-2mlEA)I:dbl.SB4PB`7bl.SB4So'\ju`ViUW`Z<o-O>8 +!6j^-!/:CP!/::L"L06Q-/!nMK)`dh!^H`NU&P3@!!&e-rrQR.+S#I5!!%M/rrY@` +!-HTf![%Jm])MaVrVuq_r;QaZqu?`3r;Qo^,ldoki;Wm*!!"><rrXPI!'Jd2!/:CP +!6k'7!5JL5!/:CO"O&.l!%$P&!6kEB!%$=u!6kEB!%%F?!R0]Krr?R,!!&8Jrr@cP +!!$O(rrC8ps+:9frrPFc5b\2ZUHE&!rrQR.+S#I5!!%M/rrUD,;:#7D+96o&rr@cP +!!#.[rrM7.qu?_Nr;Qb]rVupqi;Wm*!!">BrrQ\-g&D!R,ldp-eGfMYrVurBoD\fE +rVuq_r;Qj]!!">%rrXPI!%$:t"!mpI-0"q*g"G?a!3uD$!+Y9n!6kEB!+UW\K)`@\ +!^H`NK)aL'!al!Nnc&Xj!.TV#f`)!q!.VT["Qh!1!%%UD!0m?\!-J/=!'L5\!2KAi +"3cIQbkh>H^Qdm\s5p(u4ET`brrXPI!%%RC"$?P`-3!oH,ldp-q>UQ@P_HmFrrBh5 +K`Kg$rs.\.4=):9PW\pF!86uD!/:CP!6kB@"$?P`-3!oFUSIhg"PK#L4I#[A"3d!` +^\e$5@jNE`rW)mC!E&"VrrAhnK`Jm^rrqP,4?R,Kr;Qk/,pb\Q!<"2E;<IlX!gJDl +q>UTNUP5K*qu7"F!!%`Qk&`^34JV3A!V7W7!!#.Urrp/I4?R`#rVm#_;'dMNrW)mC +!+Z$.!p52jrVlq/;;(gG!el?jqu6Ykre1?eK)^H&hZ!XB!'l/9f`)"\!$Lh3!WW4M +K)aL'![%Jm\c2XlrVur5rr2s\qZ$UYrVllNrVupEqu6`h@jV'R!BdXcrs$4<!%$<. +-2dfD-3!oH,ldokrVlj[rVupErr3'H!!#.YrrIg"r;ZjEL&(`LKdHWs!Bd.SrrI3f +p](:?o)A]DrVurBrVm;Z,ldoks8RcQ!)^L.qu?^or;QeO-2dfE-&)?u!5J1,!-J2> +!H]Xc!!+BUqYpSk-2[`G-&)C!^\%R2FT;A_!!">BrrKAer;ZjEA,Q?1,ldokUF#g< +!-IQ,!+Z!."ApHF!%%F?!+Ym+"?`shs)do6%);iB49,@Ys8Ppr!'L/Y"&T$u4T59\ +F=$hb!@;6-s+::/rrPFc5_B$grrQR.+S#I5!!%M#s4I>Q+96o%rr@cP!!IEDs5kX) +!!">Drr?R.!!$O,rrL=iq#CE"rr2tPrVupEq>^kes8OAF!'L;]ff]35!/:FP"!mpI +4T,3Z4S\sWFSu.>ff]$0!-J2>!+Y^&!%%49!/:CP!6kHB!R)kh!!@rTs#fuT!87AO +!'L&W"*FSC^\%R,FT2:?4SSmV4T,3ZU\FfjFT9,K!!@?Cs#g8\!6kEA!+Yg)!'L5[ +!%%@>!@?mqrrBh5!!4J/4T5<\bkh>>A,$$*Z2\q=!"$F?s!7XF-3*ukrVur5rVm#_ +,ldokrr2s\p](:VK)^H&iVrsE!'l/9f`)"\!$Lh3!WW4MK)aL'![%Jm\c2Z_rW!$_ +s8S>_!!FT1!!">DrraVJ!%$e*rr>1V!!">Err@cL!!">E!""AZs!7XF4TEVOr;Zh- +rVlsG!!#.[rr?R'!!'e5rrM^;r;ZmF4=0t,!'L8\!/:@O"!p&l-2dfD-1_'9A,ZH2 +UWes"-2mlE-3!oE4Sf$X-2mlHbl@]QpAbE4s8Rd8,piKir]C0Xrr2t.r;cgCr;Zi4 +rr3#P-2mlG,s3LQ!!YRcs+NQ]-2diC49/7XrrbFa!%$e,rrA;X!!%`Prr=AB!!+Al +rVuq_mJd/KrW!"Rs'u$.!/:=M!0mE^!^&RkrW!.Vs8QRk,piKir]C1&rr30K!!">F +s+UFP!)`^p!-J2?"(VB2A,QE,-2dfD^OlK;s5O%[5QF'$s4I>Q?iV>>rrN0#ItI^Q +rrO;CJ%5L_,ldoks8P4\!!-S>rW!&Es8Skn!!#morr?R-!!?`GUF#m>"-iicL&:oP +A&$7e!!n;Ys!7XF4MN3@!!$O,rrXPI!'L8\!2KJm"&Yi.4T5<\;?$Rq;>gIsL&_1, +rVuqPrr2sErVuq_rVlk-rVupEo)A\PpAb4?^]+654T,6^-$7gorW!#Ds.fMm"&Yi. +4T5<\;>^@q,ldokqu6Z2rVusFU]18n4T5<\L&V)P;>pOqA,cK1YpC]kqu6aE!!">A +rrY@`!%%XE!Tk^-!!>?Jb[^VP!%%XE!%%OC#!DMK,ldpemf*9@rW!$_s8S>_!!#mn +rr=AE!!&enrr[s$4PBZ4!6kEB!'L,X$RGcQ4TGHD,ldokk5PA\-2mlGg&Jhd!!+C@ +rr2s\rVuqPK)^H&ir9'F!'l/9f`)"\!$Lh3!WW4MK)aL'![%Jm\GlPNrW!#7jsC!, +!Palu!!@rTs&&aq!5JI3!%%UE!0mK_!5JL5"$HV`L&CuRU]:A<rW!.Vs8OAF!%%OC +!-J,<"!mpI4T>?\4T5<\A,cK5o-FA:-3+"[r;Zhmrr2tPrW!&Es8Skn!!%`MrrXPI +!'KiP!'L#V!BeU)rr>1\!!FUls8RfP!!:CE4T5<\A,cK2o-FA:-2[]E,ldokqu6Xn +rW!)+s8SiVr;ZrQs8Tk5!!#.QrrXPI!%%LA"!mpI-3!oEFT)7?4T59[;>pOtbl@\h +r;Zg[rr3'H!!#.MrrM7.rW!%qs8U=B!!">Crr@cP!!$O$rrC:B!!#.YrrCaO!!#.\ +rr>pq!!@xxxxxxx"&]*u;>pOuZ2aj!4T,6[fn06Us5O%[5QF'$s4I>Q?iV>>rrN0# +ItI^QrrO;CJ%5LY^]"36FG9\o!^-M,rW!."s5kU-!'L2Z!2KMn!'L2Z"sj6L-3+"! +rVuq?rVm'a!%$e-s!@LA!)`Um$RGcQ4TGHD,ldokoDS[hA,ZH0bl;2P!!%->rr@cP +!!^[Is'l$/-2RWD,ldp-o)A\PqZ$[D4I#aC!'L5\!3uP'$K`W74TFOi!!">:rVlk- +rVurBr;Qj]!!">BrrsbL!'L:8-2[`CA,cK.;>pOq^[qI-49,@-qYpXD!!">Err=AE +!!';&rrAhn!!@rTs!@UD!5JO5"!mpI4R`:M;>gIp4T6Z+!!+D.rVm!H!!">:oD\n= +!!#.YrrC:B!!#.\rrBh5!!=PIs&&aq$)@P#,ldp-s+Mcs!!$M\s+::0rrPFc5_B$g +rrQR.+S#I5!!%M#s4I>Q+96o$rrqO2!!#,-rW!4gs8OAF!%%YerVuq_r;QbNrVuqP +r;Qs`!!">Fs+UFP!6kB@!6kEA!%%F@!0mB\"sj6L4TGH*rVup\r;QbNrW!/Hs!7XF +-0G1+!/:CP#0d,I49,@-qYpXD!!#.PrrY@`!%%Wg!9X+W"$?P`-2[]Ebl@^erVup\ +r;QbNrVurBr;Qj]!!">CrrC:B!!+Alqu?a[U](2p,ldoko)AeS!!">ArrXPI!%%XE +"!mpI-2dcCbl.SEL&_0!rVup\rr2uBrVup\nc&XP4S/URU]18nbl.SBA+KX%,ldp- +qu6Z?rVup\rVlj[rW!5=js:!--3+"hrVusF-2[`D4JRN.K)ad/!^H`NK)aL'!al!N +nc&Xj!.TV#f`)!q!.VKX!%%LB!%%XE#UKHN-.sRE!%%OB!'L5\!6kB@#!;kc-3+"! +rVurBq#:?<qu?^CrVusFbl%JF,ldp-s8RfP!!%`Nrr@cP!!UUH,ldokr;QbNrW!/H +s8P1]!'L,X"!mpI4S&LS,ldp-p&>+V!!">?rr@cP!!%`Nrr@cP!!(7@rr>1\!!(^N +rrC:=!!,3Wr;Qc@rVuq?o)A\PrVurOqu6jH!!">Fs31HB!'L2Z!6kEB",6d;-2mlE +PlC[_bl.SB4RrFObjtf7A,cK.L&M&P^[hC,,ldokqu6Z?rVup\rVlk^rVut/A,ZH1 +L&_1sq#CFXUOrMts5*bW5QF'$s4I>Q?iV>>rrN0#ItI^QrrO;CJ%,FXA,?6+FT2:? +;>pOq;>pOqFSl(<A,ZH.bl%JF49,@-s8RfP!!(7<rrC:A!!7964T5<]-1h*8"sj6L +4TGGVrVuqPr;QbNrW!,Gs!7XF-2dcCPl:Xebl@]*!!">ArrXPI!'KiP"!mpI4SA^V +49,@-q#:>hrVuqPr;QbNrVurBr;QaZrVurBrVllAqZ$Xo^\[s1bl.SBL%>6D4T5<\ +bkqDI,ldoks8V4-!!#.ZrrC:B!!7lSbl%MAbl7VBbl.SB4RrFOL&M&R,s5'(K`TDm +rVupErr2tPrVurBo)Ae<!!">BrrC:B!!#.ZrrXPI!%%UE!%%XE!6k<?!E$U`s+::+ +rrPFc5j&(Jg!&.9rrV>:Pg'./k02'?rrSsLg"HB,?iV>>rrN0#J*-b4bfo59rrTrh +Z-<4Lg!%\2rrJ@<f`)!q!.VKX!2KGl!@?n-rr@cM!!+D.qu6YMrVuq?rVm,b,ldp- +s8RfP!!(7<rrC:B!!H1!s4J^t!!#mprrsbL!'L;]bl.SB4T,3d49,@-s8P1]!%$e+ +rrC:B!!B"rs'u$.!0mE]"S3o>!'KiP"!mpI4SA^V49,@-q#:?<rVup\r;Qj]!!">B +rr>1\!!(7ArrC:A!!-T_q#:?IrVuq.o)A\PrVurBqu6aE!!">ErrXPI!%%RC!+Z!. +!mL\grVupErVm#_,ldp-nc&S8rVuqPqYpdH!!">-s8S>_!!&ebrrXPI!%%OB!6kEB +!'L2Z!+Ym+!/:FP!6kBA!Fsf7s+::)rrPFc5jA:Mfd.sD!!4HD^[M1);#gT\rVlo\ +bh2psKdAk\,m=8K,pcE`r;QfNg&D!Rf`2!ug&D+]!$Lh3!WW4Ml2M$a,p`Nk,pd'` +n,EJ9!!(^NrrLg+f`)(a,s3J"rW!$H-"F^frrL@+rr3(b!!#mLrrO;CJ%,FXg&(gM +;>pLpbkhA?;>U:mg&:sT--ZDho0!!P"-iicL&M&PbkV2<^]"35L&V)PU\t/mPlC[b +,ldp-rr2sErVuqnrr2t.rW!$ts8QU.!!%`OrrAhn!!?a2s1eL4!0mK_!SKU7!!">9 +rrXPI!'KrS"$?P`-27E>-2mlEU]18nA,ZH.;>^@n4T5<\bl%JD,ldokPl1Ogk#!Ee +s8OAF!%#DYrr_Cn4JVfR!'L5\!6k??"!mpI-3!oE;>pOqA,cK.U](5q-3+"hrVupE +r;QjF!!">9rrA;_!!+D.qYpP*rW!%Ss8UdO!!,4ErVlu7;*<)"rrXPI!%%OB!6kEB +!'L2Z!878M!@?n,rraVJ!%!m-rr_C\,s6eZK)aj1!^H`Nl2L`nq#CD:nG`SQ!!%`P +rr]MP!'Js7!%%==%6WeQs)\5@FT;Bb!!"=urrQR.+S#I5!!%N5rr=AA!!+C@nG`S: +!!(7Brr[?C!-Hrp!6k*9!)`aq#s826Z2aiX!!#.7rrO;CJ%#@W-2dfDU\t,l-2[`C +^\Rm0;>pOt,s4:9rVupErr2tPrVurBq#:>JrVuqPrVlk>rW!0Lk5YH-!!#.\rr@cO +!!58F-2dfG^]4>Kr;Zq0^Q_Uo!!">Err>pp!!=N04=0q+!%%49"!mpI4SA^V49,@- +p\t5Ir;Zm]4=0q+!5JF2!'L5\!6kB@!/:@O"XRZ4F?ClK!!:jRL&CuV;2'^6,ldok +qu6XYrVurBqu6aE!!">ErrBh4!!4H/4T,6^L&_1srVupEr;QaCrVurOoD\eQrVuq. +q>UH0rVupErr2sqrW!'I@tfV6rVup\qu6aE!!">BrrC:B!!#.Yrr>1[!!$O,rr@cO +!!OZYKlfF'rVurOK)^H&j8T0G!'ofK!^$G_r[%LC!+YR!"$?P`L&V)PA,ZH.bhE's +-1q6Hg&M'u!!">Fs3(HC-/&;"?iV>>rrN0#J*Ht7,ldrE-2dfDU[e?d,ldqhrr3'H +!!">!rrC:9!!=PIs5s:\##YF#K`D*8g&D*r!.VHW!)`^q!@@@8rr>1[!!">?rrLe! +p](<!rr2tPrVurBq#:>JrVuqPr;QaZrW!.Es8OAF!'L5[!'L#V!-J2>!'KoS"GQmU +jsB^$!@?n"rrXPI!'KrS"$?P`-2.?=4SSmVFSc";4T5<\bkqD?4SAaT4T>?\4SJgU +-2[]B4T5<\bkqDB,ldokrVlk-p](:Vrr2uBrVup\r;QaZrVurBo`"pErVusFk4nrV +4T5<`g&M**-2.B>;>^@q,ldokqu6Z?rVup\qu6YkrVusFk55/Y4SAaT4G*Tbs5O%[ +5QF(6rs(Xd!/:IQUHJMU!5J+)"$?P`L&V)SYpBB4g&D1$!!%,Ur6,4r4GEe7$$6.I +FT;Bb!!"=urrQR.+S#I5!!%N5rsC%P!6kKCKd?^!-1V!;,ldqhrr3(B!!%,prrgOG +!%!?sbQGV%4L+nc#s81fZ2aiX!!#.7rrO;CJ%#@WPl1R^g&1jMPl1R^L%kTJ^EraW +!@=N>rr@cP!!(^IrrCaO!!&8]rrBh5!!\/Ws!7XFA,ZE.juiJ?!+Yp+!'L)X!%%UE +!'L8\!TlN@!!FSJ!%$e!rrZ*u!+Y^%"$?P`-2.?>juiJ?!+Yj)"$?P`-2IQAF=$b` +!@;7Rrr>pl!!,sMqu6a\!!">ArrZ*u!'L2Z!+Yj*!'L2Z"!mpI4T,3ZFT)7?bk(i: +,ldpep\tB2!!">-rr3#C4Sf$Y-"HfO"!mpI4So'[,ldpTqYpXD!!#mlrrI3fq>^OB +@tO`4s5EtZ5QF(6rrY@`!/:CO"$?P`A+KX%49,A8rVlo\bh2pt,ldqho`"sFbl7VE +bQ%Vhg&D+]!$Lh3!WW4Ml2Li3!!(7BrrgOl!!&ebrrXPI!6kEA!SP]Mrr^IF!%%7: +!R06rrr[rT!'Js7![%Jm[Jp>+,pd[1rrhI1!!#.SrrM7lr?VJSk5>5]^EikBpAY2J +4GEY3!i%kfrr3(q4Ak8<rr@cO,lplXq>UJj4T6W2;5=/r,pfhorsHMN4=):9FP0M; +L%50DKn]1!",/$IFS,S5L&E:u;8;o+"/@.gFSPkAk(Po[,pb[-k5,)YUJ^t9!Frn? +rr]#B-$9"`"6O*'g&(dMUHJN%!Bd.SrrZ*u-):D<"2?,^4S&LRk(T&mrrTH&^\e$3 +PW\mj!HdK"rrZaW-*d=H!l%TSq>UQ@4Ajf,rs7b@4?Oo94GDpLs+::/rrPFc5jA:N +49,A8rVltR!!#.PrrY@`!/8l$"!mpIbjYQ6bQ%Vhg&D+]!$Lh3!WW4Ml2Li3!!(7A +rrY@`!/:"D"!mpIbgZRobQ%Vhmf*BC!!#.7rrO;CJ#`MNfnG.Bk5PG7OT,@Dk2H=? +k2ZIAk4JZRk2H=@bi\d%!TqVWrrD3RrrD25s+:9ZrrPFc5jA:N,ldq?rVltA!!#.Z +rreR.4GCQJrrY@`!/:FP!mEc(qu6i7;'dMNPl:U_FCY.H!b5a&p&>+?!!(79rrSrX +FT2:BbQ%Vhqu6l8F?DZ_Pih-.!al!Nnc&Xj!.X;6"O$iG-0G1+"$?P`L&M#Tk(R;B +L$&=5"!mpIbl7VDUHEYqrro/[,pcE`rr3&Q@tjdZ!ngG)p&>-<!!">;rrR:)U]18q +K`D*8qu6hp@luk`UZMLW+96nCs+:9&s+:9&s-EZd5QF(6rrXPI!6kHB"O&.l!0mK_ +!L+o.!!%->rrY@`!/:FP"$?P`L&M#OU\b#q-):KM!!#mnrr[rT!)`Fh"=4$J@m'`: +"$A\Cg&:pW,ldqhs8U:C!%%RC!+Ym+!@=N(rrQR.+S#I5!!%N6rr^IF!%%UD!2KMn +!87AO!H]Xd!!+C@rVlsG!!(7BrrXPI!6kEA!+Ym+#!CT=49,A8qu6aq!!&8WrrpUH +!$u_LrZqV.4Ce?i"3^`F-3!oHK`D*8rVloO4So*Z--YQP![%JmK)^H&K)^H&K)_/: +!^H`Nl2M5>!!(7Ck(P)]!%$e-s+U7K!0mK_"$?P`L&V)S49,A8rr2u5r;ZgDrW!!G +s)e5?!0mH^"Qh!1!)`Fh!%%@>!'L5[#pfQObl@^e!!">Drr?R(!!(^9rrQR.+S#I5 +!!%N6rs-aJ!%%[Ffjk!]!'L8\!)`Rm!@?FurrXPI!6kHB"!mpIbl7VBL&M&Q,piNj +##YC_!!"=urVlkmrVuq_pAY-:p&G)&rr3)E!!">Err[rT!'L5[!'L&W!%$h.![%Jm +K)^H&K)^H&K)_/:!^H`Nl2Lf2!!*!Er;[;%s8Uau!!"<TF<pne-3!oH49,A8rr3'_ +!!%`Prsq3l!%#D[^H;Kns77N:!%%UD!+Z!.!5J4,!%%@>!'L5[#pfQObl@^e!!">E +rrAhn!!d#Xb`jCR!/9Y:!al!Nnc&Xj!.X;6!6kEB!@9&j!!FV$s8S>_!!4HgA,ZH. +;?$Rt,ldqhrr3TW!!(7Cs4J[u!'KE+UEonos1eO5!)`^p"$?P`-2%9<bk;#:FT2:B +^An6[rr3(S!!#.\rr?R.!!e5%b]G-2!6j[,![%JmK)^H&K)^H&K)_/:!^H`NlMgnI +-2ITB-):J>&Q&N.--ZDhbU!5h^]4<r!!%`PrsC%P!/:IQK`D*!bl.PAbl7VBPl:Xf +FT;C',ldpBo`#%?!!"<Bqh5%4rr2uBrW!/Hs8U:C!%%XE#<VtdA,lS(4T5<\^Zb\! +?iV>>rrN0#J*R%6U\Olj4O!g)$7,ZP4S/UQPQ1\0rr30K!!(7Cs31HB#0d,I;#gSY +r;QcMrr2t.rW!&*s8Skn!!%`GrrC:B!!+BUr.P-8rVltR!!">Ert0qb!'L;]js:!- +PlLc;,ldokkPkT+!.TV#K)^H&K)^H&QN%"O!'oiL!6k?@"!o78k5G;^,ldpTrVm0d +!!%`Qs#^8]L&V)Y,ldq?s8OAF!+Yd'#!;kc-0G5;rVur5o`#">!!(7:rtETV!%$e- +s3(HC-3+"u!!"=hKdHZt!+Y3l!al!Nnc&Xj!.X;6!/:=N![TsnrVllArVuqnrVmWZ +!!(7Cs!7XFbl@^e!!">-s5kU-!2K>h$K`W7!'L;]49,@-o`#$;!!"><rr[rT!%%XE +%#"Z]4TGGG!!#.D@jV'R!2J`W![%JmK)^H&K)^H&K)_/:!^H`NlMh%3!!"=hbkh>> +bl.SBbl.PJ49,A8s8P1]!/:FP#pfQObl?>r!%$e%rrB>'!!Qm4,ldpBoD\n=!!(7: +rr^IF!%%XE$HrJM-3+"[!!";kr;Zj\UZVRX?iV>>rrN0#J*R%;K`D*8bfoq`",-^T +-2dcX,ldqhs8OAF!6kKCbQ%Vhs8S;`!%%@=!-J2?!MdF/!!%`Frr^IF!%%=<",-^T +4T>?fK`D*8s8R0@!$rri!!,s3k5PK*!.TV#K)^H&K)^H&QN%"O!'oiL"3^`F-2@K? +bl.SBbl.PJ49,A8s8P1]!/:FP#UKHNbl>le!%%=<"Ao.!-"HoS!5J.*"!mpIbkD&= +bQ%Vhrr32H!!">Fs+U=M!Bd.<rrQR.+S#I5!!%N6rr[rT!'L&V",-^T-2dcX,ldqh +s8OAF!6kKCbQ%Vhs8RcQ!)`Fh#:0?M4Ac(Y-1h-=bQ%Vhp&>,J!!#.\rs"/W!'L;] +4T#0\,uMG<rrO;CItI]Ps+:9&s+:9:rrPFc5jJ@ObQ%Vhq#:?IrVurBrVm0M!!&8` +s#^8]L&V)X,ldqhs3(HC-2%9<^\\!24S&LS,ldqhpAY6=!!">Ers$[I!%%[FPl:Xa +,uMG:rrQR.+S#I5!!%N6rr[rT!'L&V"-`cc-2miZjs:!-g&M'u!!(7Cs3(HC-3+"! +!!#mhrr@cM!!$O#rr^IF!%%=<",-^T4T>?bK`D*8s8Psq!!4HVk2QCB+96nCs+:9& +s+:9&s-EZd5QF(7rr^IF!%%C>"!mpIA,cK8UAt9?k5YHD!!%`Prs9tO!6kK*,ldq? +rVlr]KtmQc!+Yp,!2K,b"!mpIbkD&=bQ%Vhrr3>L!!">Fs4IAP-'\?-!l&6!kl1]l +!$Lh3!WW4MlMgs?!!#.VrrCaO!!&8_rrZa2!%%XE&1%;Vbl@^e!!">Fs.]Po--Z>f +!l'HOr;QaZr;ZjEk4ATTbQ%Vhp&>,J!!#.\rsFG[!'L;]PQ1\0^\n*5UJ\;[rrO;C +ItI]Ps+:9&s+:9:rrPFc5jJ@ObQ%Vhp\t5'rW!!sKk()^!)`aq"$?P`L&V)V,ldq! +s8Psq!!d#K^LJPi-0G1+!Tk^-!!#.OrrXPI!6k0:!6kEB#0d,IbQ%Vhrr2s\rVupq +re1G:!!">/rrQR.+S#I5!!%N6rr[rT!'L#U!'L5\!b6p]rVuqPrr30K!!(7Cs31HB +%F"kP,ldokFNgLW!!#.ZrrAhm!!$O"rr^IF!%%=<",-^T-3!oWK`D*8s8V4-!!"<T +KnXUp!!#.FrrO;CItI]Ps+:9&s+:9:rrPFc5jJ@ObQ%VhpAY+Tq>^OBk5PA_49,A8 +rr33L!!%`Qs4J^o!!+D.r;Qb,rVuqnnc&\;!!(7:rrC:B!!^[Is3(HC-3!oFfd6Cn +!)_t[!al!Nnc&Xj!.X;6",-^T4SSjVbU*)c!'L5["sj6Lbl@^erW!&Es8Skh!!#.Y +rraVJ!%$durr^IF!%%=<",-^T-3!oHK`D*8rr2tnpAb2Ikl1],!.TV#K)^H&K)^H& +QN%"O!'oiL"6Lm0;>1"jff]04!BeU)rrZ*u!5JO5"&T$ug&D!PbWPb&!E%PIrrY@` +!'KcN"!mpIbk:u;,lf7jrr^pS!'L5[!p3?+qu?aDA*<jn?iV>>rrN0#J*R%9YlFcX +pAY/u-2[`C;>gFq,lf7irrOJH-2miEUF#g<!@;7QrrhI1!!$O!rr^IF!%%=<"2=g9 +;?$RtPQ1]*rVlo54So*Z-&(O^![%JmK)^H&K)^H&K)_/:!^H`Nl2LeHbk(i;ULQD` +U\aukKqnSG!R06orro0-4?R`=qYpQ1rVuqnnG`PP!%%:;!p7_hrVlr(L$&:4!Tp0V +K`JmLrrQR.+S#I5!!%N5rrLg+oD\rX;*8@'qu6`NKtmTd!p7_hqu6ha;*6t*k5,)\ +K`D*!k4/HRjs:")o`"sFbl%JAPa)%E!SN_:K`K?YrrO;CItI]Ps+:9&s+:9:rrPFc +5dC=k;#gSBmf*:2_>aRE!$Lh3!WW4MZ2XnP!!#mbrrM9+_>aQZ!.TV#K)^H&K)^H& +QN%"O!'mji"Qh!1!/7QT!al!Nnc&Xj!.V<S!2KMn!5GZ9![%JmK)^H&K)^H&K)_/: +!^H`NZMt&L!!">-XoAH1!$Lh3!WW4MZMt"h!!"=HrrO;CItI]Ps+:9&s+:9:rrPFc +5dLCl,ldpBXT&?0!$Lh3!WW4MZi:0j,ldq!XT&>E!.TV#K)^H&K)^H&QN%"O!'mji +"!mpIUTFIs?iV>>rrN0#J$].XbQ%Vhk,eRa+96nCs+:9&s+:9&s-EZd5QF'TrrQ[V +4KJJ`?iV>>rrN0#J$T(U4=+L<rrO;CItI]Ps+:9&s+:9:rrPFc5_B$grrQR.+S#I5 +!!%M#s4I>Q+96nCs+:9&s+:9&s-EZd5QF'$s4I>Q?iV>>rrN0#ItI^QrrO;CItI]P +s+:9&s+:9:rrPFc5_B$grrQR.+S#I5!!%M#s4I>Q+96nCs+:9&s+:9&s-EZd5QF'$ +s4I>Q?iV>>rrN0#ItI^QrrO;CItI^crr>R2!!"*ms+:9&s+::6rrPFc5_B$grrQR. ++S#I5!!%M#s4I>Q+96nCs6BUb*>6OK!>kfgs+:9&s+::6rrPFc5_B$grrQR.+S#I5 +!!%M#s4I>Q+96nCs6BUb*@/g8!A=G)s+:9&s+::6rrQ!s5_B$grrQR.+S#I5&-.33 +s4I>Q#QT@+s6BUb*@/g8!A=G)s+:9&s+::6rrQj6+G0XGrrP^k5k4jU-idY,s4I>Q +!!%e+s6BUb*@/g8!A=G)s+:9&s+::6rr[`N!9\t6gA_9L&--,.rrPFc."_KPrr]_1 +!2kGKlMgl*,g0Nq0*$V(K)^H&K)b$6"2=g9LP#Q[rr]G)!2oAe"+L:Na+F?FrrZ@' +#k*BFlMgl*,g0Nq0*$V(K)^H&K)b!5""4-Tf7O%Xrrhd-!#YJ#rrh3b!%@Sns4mVV +^An71K)b*8!?EH/?NDe[K)^H&K)^H&k5PP0#QQi9s4mVV?iU2!n,EKV!!%7qs5!\X +pE0GIkCW`urrF,cb?k9'!.t6&s+:9&s5j7`IfKI>kCW`lrrhdu!!#RWrrbRe!-n6i +s5<n[a!^ofT7[+,rrF,cb?k9'!0[?^LWMd]T7[)ps,d6bpG`-Q&=;R3s5a1apSSi. +!$LIlrrq9k!!"FNK)am2!T//$!!#iIs6'C_*@/g8!A=G9rrE*,b7am]*J4<Cs,[0\ +mpQ(o!'#QqjZieOrVusikNi-Kf/Wa0!"a`IjZif"rVus)LP#QgrrF,cb?k9'!0[?_ +!%,l`!?E24s+:91rrKSGJcO^/!>qHlrrIl\JcO^/!BA\_s5j7]*@/g8!A=G9rrE*H +b=r!X*J4<Cs,6mXYAgO-r;Zg?^d%s7TC:nA!r&TpY<W(!rVup0]KcLBc[u2WrrF,c +b?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_ +!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24 +s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\' +!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB +5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+ +rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9' +!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l` +!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9& +s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M# +s3(EB5lL``5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL`` +5_B$+rrF,cb?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,c +b?k9'!0[?_!%,l`!?E24s+:9&s0D\'!!%M#s3(EB5lL``5_B$+rrF,cb?k9'!0[?_ +!%,l`!?E24s+:9&s0D\'!!$BF^Aum*rrC*Y^Aote!!#99s.')i*@/g8!A=GrrrM:) +aT);fb=r!X*J4<Cs+:9Vs1\O7%&h>K!J:Nj!!#'3s.')i*@/g8!A=GrrrTq8;p0%Z +!%,l`!?E24s+:9&s0D[=!!!nZrr<A?!!"-ns.')i*@/g8!A=GrrrTq8VT[cr!%,l` +!?E24s+:9&s0DY)$,6H?#L!,IfY.=c.Y@\jrrF,cb?k9'!6bBD^At.Sh#RL&b=r!X +*J4<Cs+:9Vrr@\d!!!bWrrCrk!!*,!K)_A@!?EH/?NDe[bPqXY!2drq!<=Ii9`Z7T +K)^H&K)`+U!RZtI^Aph(!!".brrCsT!!%5_^B1s,mt1S/rrF,cb?k9'!6bBD^At.S +h#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NTT7[)ps4mVT*@/g8!A=GrrrTq8 +VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT!!&XCs+::+rrF,cb?k9'!6bBD +^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NTT7[)ps4mVT*@/g8!A=Gr +rrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT!!&XCs+::+rrF,cb?k9' +!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NTT7[)ps4mVT*@/g8 +!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT!!&XCs+::+rrF,c +b?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NTT7[)ps4mVT +*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT!!&XCs+::+ +rrF,cb?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NTT7[)p +s4mVT*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT!!&XC +s+::+rrF,cb?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscbhu*NT +T7[)ps4mVT*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".brrCsT +!!&XCs+::+rrF,cb?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-++Nscb +hu*NTT7[)ps4mVT*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+!!".b +rrCsT!!&XCs+::+rrF,cb?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i@/^-+ ++Nscbhu*NTT7[)ps4mVT*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::Arr?I+ +!!".brrCsT!!&XCs+::+rrF,cb?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s760i +@/^-++Nscbhu*NTT7[)ps4mVT*@/g8!A=GrrrTq8VT[cr!%,l`!?E24s+:9&s+::H +rrDNbrr?I+!!"/<rrDNArrD6ZrrCsT!!&YgrrDM>s+::2rrF,cb?k9'!6bBD^At.S +h#RL&b=r!X*J4<Cs+:9&s7uZr:fsq"rr?I+!!"/?rr^kl+QqJY"0X,.hu<WUhu*NT +TDnimpRauqK)^H&j8T-#,g0Nq0*'2q!l"`4bM<1!-Hf*a*?Bb3K)^H&K)bZH#L<AM +(hf8N;>pP#*P\M%0E;)lf`).0!!#96\#90)#CO:A?jH`<kCW_cs5X+[*@/g8!A=Gr +rrTq8VT[cr!%,l`!?E24s+:9&s+::Grr>md!!*Agf`(rTnGiQ.K)^H&ir9$",g0Nq +0*'2q!l"`4bM<1!-Hf*a*?Bb3K)^H&K)bWG!7139!-$Nh!&4!E!=7k?s+::1rrF,c +b?k9'!6bBD^At.Sh#RL&b=r!X*J4<Cs+:9&s7cNn;"O_g#j9e=!3bto!-!PiK)ag0 +!?EH/?NDGQb<Q+_!1_6g!<=Ii9`Z7TK)^H&K)^H&p\t6>oDel1eGfM&o`,!ukCW_c +s5EtY*@/g8!>baZ0ENL"I*:=H!%,l`!?E2KrrBfcJ"1ug[t=Y#rr>mh!!*AgeGfNP +o`+u2K)^H&i;Wfu,g0Nq(BDXo!g!D0bM<1!-Hf*a*?CUK!3^tSRK*>kK)`pl!71?= +!-$Bd!&4-I!=7k?s+::/rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X*Ld!.It@Zh!!%M# +s2Y->;"t"k#j9Y9!3c+s!-!PiK)aa.!?EH/?NCrCbJ41@!.;uG!<=Ii9`Z7TRf<G= +!!%WNT)Sil!.TV#a8Z.cp](;5d/O)"q#CF$kCW_cs53hW*@/g8!>ba\^]r$0X?`?= +j3?B\!%,l`!?E2LrrRZM!.t6BrrN0#ItI^?rr>ml!!*Agd/O*Lq#CD6K)^H&hZ!Ts +,g0Nq(BDt#"O>ren+l\W"T7uamc;mR!<=Ii9`Z7TRf<G=!!%WNT)Sil!.TV#`r?%b +q>^M7cMmkuqZ$X&kCW_cs5*bV*@/g8!>bag^]VO-l20iI"9%iVhq6`c!%,l`!?E2L +rrRZM!.t6BrrN0#ItI^>rr>mn!!*AgcMmmJqZ$V8K)^H&h>[Kr,g0Nq(BE4*!lEOQ +jo5D]oB=oa!<=Ii9`Z7TRf<G=!!%WNT)Sil!.TV#`W#qaqu?_9bl7Ysr;Zj(kCW_c +s5!\U*@/g8!>bal^]MC0qr%JTr9E(n!<=Ii9`Z7TRf<G=!!%WNT)Sil!.TV#`;]g6 +rVus)kKNr+YPeG$E.\+As4mVT*@/g8!>bam^]E$\pAY9I[srm8r'1BmIt+rZpAY0h +k2+np!%,l`!?E2LrrRZM!.t6BrrN0#ItI^=rrCCE!!$u\rrb"U!!qb>s+::+rrF,c +b?k8d!8tWn`pNR$!lodMn,NMTLX5bq!V5.+h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M# +s24j=:]Ldab5VRI!!$tis+::*rrF,cb?k8d!9(]of_bOF!nV)kl2Ul&Gh;fl!W;-> +h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M#s24j<cN%q*rrOk[kCW_cs4dPS*@/g8!>baq +^]<QorrKSgj8]3?\,-+)mc*%'!%,l`!?E2LrrRZM!.t6BrrN0#ItI^;rrH6baSu:E +E.\+As4[JR*@/g8!>bar^]<QprrL_BhuEdKhu!ESo%rH`!<=Ii9`Z7TRf<G=!!%WN +T)Sil!.Tq,\\A-T`kMM[Y.ju"K)`%S!?EH/?NCrCjhLo6lhg\^GkV1B)eEf*TqT-u +f*8m]TlOpM'_hY/#`&<W!VP=2h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M2rr^l&5VRci +U]:N'5Y.7!K)`7Y!?EH/?NCrCk.h#9mJQtbh`1E3!ZPIKnCI`8<ttH1!BA^/rrMfL +k1p%<-Hf*a*?CUK!e11Mdf0B`L"YMd"6NH,FRK/0biX`]!WW4MPlCgZLF@`SRfEIC +YCce`rrF,cb?k8d!9_,u_Xm^*!RD>S!!3@2Y3OU>Ti(Xd!>*TTrrD`Sh#RL&b=r!X +*Ld!0IfKK?rr^q#-"H':"2=g94QHGAL&M&PbjbW849-[)^UjFHUQjojrrN0#J!L$7 +T-4(4"!D9,LP!:>^BD#qIom9\!!+dgK)`C]!?EH/?NCrCkJ.)\r;Qf4&GlG.0=Bro +!N74>!!*YWr;QcbkM6.=-Hf*a*?CUK!e11MoD\efrVurOk5PO;!!">*rr@cP!!(75 +rrA;]!!,s3^&J4F!!">-ec,[N!.U@8!T,=)!!49^c[u1hrrTZC)#aL98FM01]DhmP +,g0Nq(BE[7!8.5L!P\p<!!*:Ej4==YAbuH.+Q*+s!9WM$!<=Ii9`Z7TRf<G=!!)Wj +!'L5\!6jU*"$?P`4QHGAL&M&Pbjk]5L&(cN-$8:brr=AE!!&86rrN0#J!g6>^CUAF +(nZE[Rf<TdIh2S[.+a(N]`/!Q,g0Nq(BE^8!QtB>rrL^_qu?aT[G]X;W$;->!?gk0 +rrN&Ul.l@?-Hf*a*?CUK!e11MoD\eQrVurBk5PNG!!#.Arr@cP!!(75rr@cJ!!+Bf +_>aKtrVurOec,[N!.UF:!13Zb!Isiqs-N`hmoTPi&@[8k^&J*R,g0Nq(BE^8!:Tmd +!Uh0/!!,4/p"'8fTn`J\!f`o#p"'5e./X&G3;<CO!:oC1!<=Ii9`Z7TRf<G=!!)Wj +!'L5\!6jU*"$?P`4QHGAL&M&Pbjk]5L&M&Q4=0k)!BeTDrr_Cn4L*E9!WW4MRf<Mo +!!!;&K)_&7"GZsW#g\,&^Ae3S,g0Nq(BEa9!8.5L!+>^)!Bea(f)s0?6Oi_h!uk*l +d.l2nasd/f!.XqH!9WS&!<=Ii9`Z7TRf<G=!!)Wj!'L5\!6jU*"$?P`4QHGAL&M&P +bjk]5L&M&SbiXU*qu?aDUQb]Z!!%M<rrg@J!"dJ.s,m<aY5ePFkCW`KrrF,cb?k8d +!:.E$_YO01!2'/h!Bea)f)j*+%Ia?!%;!]Xf)a#Br;Zj(ci*kDq<Hc:!%,l`!?E2L +rrRZM!;$3j4T5<\bi\p349,@Ds8TifL!8f]!/:CP!6k!5!/:CP!6kHB!M_dT!!&e] +rr^q:4O!g)!R/dBrr^qO;;(sK!l'H5p](08!9WhO!WW4MSGr`T(]XiVK)^o3"HNN_ +3;8%)_#FEU,g0Nq(BEd:!8RPQ!V[H0!!+%cq:>Y:'^Pf#)lWSa!Q,BF!!#RfrrD9K +h#RL&b=r!X*Ld!0IfKK?rr>1\!!(76rrKlEr?VJdk5G;`49,@D@jV'R!@=!*rrJ?H +r?VJS^\n*3L&M&Pbjk]5L&M&Pbl%J@L&CuP--Z5c!M`Nk,lqN<r;R1&!!#.]YpBAM +-):Kor?VGtq#:AZ4T6W-;5=$g"&U?jg&D!U49,@Ys)]Rd!!,4+r;Qhn4=0n*!@>#A +rrN0#J"6N@Du]m)K)^i1")%Z7O+RDIrrF,cb?k8d!:7K%_YO01!0@$X!0m<2!++jh +!-n=k!-nDA!3cA$!;Ys:!<=Ii9`Z7TRf<G=!!)Wj!'L5\!6k*8!V91b!!+Bfrr2s\ +p&G)&qu6]@4S\sWA,ZE-L&M&Pbjk]5L&M&PbkqD@^ErjZ!'L2Z!SKU4!!+C@rVm!H +!!"=0qu?aD4So*YL&:lNUF#a:!BeU*rrC:B!!$O.rraVJ!$sc)!!#.[rr?R(!!#.P +rrN0#J"?TAhZs3YK)^f0"SW`5)#&X^_>aNV,g0Nq(BEg;!8.8M!V[H0!!#C_f)a5c +q>^U/:k,,8^B:*X:^Hmt!*B!J!%@dG!&4?N!9WY(!<=Ii9`Z7TRf<G=!!)Wj"$?P` +-1q3<fd6@m"3gfF4S8[SL&M#PjsBa%!2KPn!/:CP!6k!5!/:CP!6k<>!R)kh!!&8_ +rrM7.q#CFAg&D!R,ldoko)Jb:r;Qb,pAb1Urr2uBrVup\rr2sEp&G30s8Skk!!">E +!!#.PrrN0#J"?TA:]LLAK)^c/"0V\)O+RDJrrF,cb?k8d!:7K$n,<7dO8T%Z#/'ib +!RNt+!!,'Wp&>*fT-4"2!)`UE!3#eq!5JL4!:oL4!<=Ii9`Z7TRf<G=!!)Wj"!mpI +-1q3;4T,6e;3[h%!!">-s8P4[!!GEZbfjSr!!+D.rr2sqrW!'IFG5EGrVupqrr2tP +rVurBnc&TCrVurBq>UGKrVup\rr2s\r;ZmF4=0t,!)`aq!%%LB!'L/Z![V>&rVurB +rr2tnr;ZpGFKo?T!!$O.rrC:B!!%`Prr=AB!!.2+rW!%Ss8R3?!!d#Xg&J<'!/:"D +!WW4MT)SoM!!#iIs,$aW0E;rAs2"^9*@/g8!>bb'^];IRrr=bO!!$@%f)T.T!!+4W +nG`N]&GuM.Er+Af6i?ub;#UCprnd%u!<=Ii9`Z7TRf<G=!!)Wj"!mpI-2%9<L&CuO +U]18q,ldokrr3*`!!"=0r;Qb,rW!%Bs8Tk5!!PLVs8ThrrVuq.rr2tPrVurBnc&TC +rVurBq#:OE!!">-s.fMm$^C\kbU!5h-0G7--2[`DL!9Jq"&\4\FT)7?PlC[_-2mlI +4S/UQL&M&PU]18n^]"35L&V)P-2[`LU]:??!!#mrs'u$.!0mH^!SO7<rrN0#J"HZB +LB%=hK)^]-",?jV^OlL&rrF,cb?k8d!:@Q%hYmHS^\e'3[JSPUY5A8#+Q)Ve!RD>U +!!*;,qpth;r;Zj(kPbD\l0[:-!%,l`!?E2LrrRZM!;$3m,ldokp&>"<rVuq_rVlsG +!!#.\rrY@`!'L,X"sj6L4TGFkrW!&8s.`Hh!!'e5rr@cP!!(75rr@cP!!(7<rr>1\ +!!:CE;>pOqFT)4>FT)7BU]:??r;Zn`s31HB!'L8\!6kEB",6dTPl:X_4T59[L&M&P +bl7VBL&M&PL&V)P-2dfDFT2:E,ldp-s8Skm!!,3WmJd4f!.UU?!^H_sK)^Z,"5a(Y +BS-9$rrF,cb?k8d!:@Q%n,<7d@/U'*0Da9#0DtkO&D-dY#5R`J^Y\\_qYpT2#lO`' +./MNq'`A"3L].5Qo'P66!%,l`!?E2LrrRZM!;$3m,ldokpAY-:rVup\r;QjF!!#.\ +rrY@`!'L,X$TnCh-3*uk!!"=!4T#0[-):G=!/:CP!6k!5!/:CP!6k6<!'L5\#0d)n +!!">-rVllArW!%Ss8ODE!!?a2s4RAO!'L8\!87>O"$HV`4T5<\Z2O\&L&M&Pbl7VB +L&M&PL&V)P-2mlE-3!oIjs:!-4T>?\A,H<-4JVBF!WW4MTDo#^!!$DYs+gUU2uk@Y +s2+d:*@/g8!>bb(^];=Nrr<W/!!%cNf)VuO!!'5#rs\_YaM>TQ!.<VYipZjDrrA,X +!!'2!f)TUb!!"_OrrE#bh#RL&b=r!X*Ld!0IfKK?rrXPI!%%@=!/:CP!/:@N"!mpI +4T>?_49,@DqYpa^!!">Fs!@I@!@<Hsrr@cP!!(75rr@cP!!(7<rr>1\!!UU/,ldok +r;Qc@rW!.Vs8OAF!%%UD"!mpI4T59d,ldp-s8OAF!%%RC!/:CP!6kHB!/:CP!/:FP +!%%UE!+Z$.!6kEB!'L5[!H]Xc!!,sZnc&Xj!.UX@"4$rIYCce0rrRZM!.t6frrF,c +b?k8d!:IW&eG]CI^\n-5#138!!(6\b!*K1!!U%>u^]KStI/Vk%i:[$J!&4?O!(6Y8 +!5/40!8mbT!93G&!<=Ii9`Z7TRf<G=!!)Wj"!mpI4SJdTL&M&PL&CrQ,ldp-rr3'_ +!!#.XrrtRc!%%[F-2RZC-&)0p!/:CP!6k!5!/:CP!6k6<"XO-K-3)3g!!#.ZrrC:B +!!\/Ws!7XF-2miG,ldp-rVm0M!!">Fs!7XF-2dcCL&M&Pbl7VBL&M&SL&_1sr;Zi4 +rr2uBrVup\r;Qi\@jV'R!@?FirrN0#J"Q`C[f?ESeGfS[4L+SZ!jOkAW;ck[n,NC2 +"2@\qg&(dOk#"7UqYpZN4=,^-rr\kn!9\t6_uB`X,g0Nq(BEm=!9!hU!/LLQ!&+6$ +!Q,-?!!(@DrrMZ,r4iAq!.=_#!T*\OrrB8#!!'G(f)QN`!!&qqrrD<Oh#RL&b=r!X +*Ld!0IfKK@rrC:B!!#.TrrA;_!!%`NrrY@`!'L8\"$?P`4T#-`fd-Uu4TGF-r;Zj\ +U\FcgL&M&Pbjk]5A,ZH.bk_8=L&M&V4TGF-!!">CrrAhn!!]4us!7XF-2miG,ldok +rVm0d!!">-s!7XF-2dcC^]"35bl7VBL&M&SL&_1srVusFk5PA\bl.SB4Sf!XKdH]u +!)`=e!WW4MTDo"c!!)34rr?R.!!%`IrrAhn!!&dorrR9B4S/RSk$o_7!!#mnrrY@` +!%%LA!'L5\!5Hn\"1J71c[u27rrF,cb?k8d!:IW&li$h`=T&4"?Mi=SGl7UB;#L=n +bko0WO8s\*h#Q[:rr=bO!!%9@f)S2:!!%9BrrDQVh#RL&b=r!X*Ld!0IfKK@rrC:B +!!#.Xrrh#/U]8R;!!#.ZrrY@`!%%XE"$?P`4T,3[o0!!P#F,8g,ldokU\k&mk*2,0 +rr@cP!!(75rr>1\!!(7>rrAhm!!B"rs!@XE!5JL4$9S:g-0G7-,ldokrVls^!!">D +rr>1\!!:CE4T5<\^]"04bl.SBL&V)PL&M&SL&_1srVupEr;QjF!!">?rrgOl!!">9 +rrN0#J"Q`BIfKJurr>pp!!&8ZrrAhm!!&7arrAhn!!&8VrrJl@q#CC@r;Qblr;Zhm +r;QcMr;Zh-d/O3g!!'ccs24j;*@/g8!>bb(^]=!)rr=bO!!&#Uf)Rr3!!'5$rrDB] +^]KStI/;Y!q>L<nO8T%Y;>\rFEr>t<;#UCoo^:N9!%,l`!?E2LrrRZM!;-9kbl.SB +FT2:Bb`ksNrW!"Rs!@XE!0mK_!L+o0!!B"rs#g8\"XS9*b]G01!!#.\rr@cP!"C6. +g&M)rF<pneU]:@JrVurBnc&SOrVuqnqu6YMr;Zg[rr2tPrW!'IUWgJ8rVupqrr3'H +!!">Drr>1\!!(7Brr@0?!!8qqPl:Xd4Qc\Dfhq_K!'L8\!/:CP",6dTbl.SB-2dcL +,ldoks8R1'FMIhT"MZ5_!%%49!WW4MTDntB!$Kek!SJdt!!'e2rrL=irVup\X8`4R +-2mlEA+op&U\=`g-2dcC;>gIp;>gFoPl1R^-.)YohZ*YkK)`ag!?EH/?NCrCm_Ai" +rVlj'r;Zi*r7:tr#5nN%hu3QTde^`\O8s\)h#Qd>rrBh4!!"5?f)V<=!!"GGrrDl_ +h#RL&b=r!X*Ld!0IfKK@rrBh5!!=N0,piBf!^-Kmr;ZmF4=0n*"&]*u4S8[S^]"04 +-2[`D,piHh"2Fm9L&M&Pbjk]54T,6[-2fq+-2dfE-/&7s!%%C?!@?FurrXPI!%%UD +!-J2?!6kHB!/:CP",6d;-2mlG,s3LN!!C"9s+UFP",6dTbl.SB-2dcC4T5<]bfp"c +r[%LC!)`=e!WW4MTDntB!$Kbj!R)kh!!+D;r;QaZrVusFk,\L^4T,6[4SSjUU\k)n +;2',k!!">Crr=AD!!">Crr>pp!!"=lrr_-Y!5F-c_uB`X,g0Nq(BEp>!65!;!8%,K +!7:Yq!3#hr!#YY6!6"`L!g!D0qV;/1rVlllqu?`Dr7:qVqu?`krr2usmbImD-Hf*a +*?CUK!e11Mo`"odo)Jlts8P4S!!:jR4SJgV-*dCJ!R*\#!!$O.rr@cP!!(75rr?R$ +!!+Cir;Qf4-2@N@U](2p49,@-rVlkOrVuqnrr2u5rW!%1s8Ske!!?*us-3K_#DN3X +js:!-4T,3Z;>pOsbiU5H!!+D!o)Aak!.UX@!e11mdf0<^r;Zg[rVlk-rVusFbcCaD +L&:oN-2@K@bU*5g!@>M[rrZa2!'L5[!Tk^,!!">Crr=AC!!(6jrr_-Y!5F-c_uB`X +,g0Nq(BEp>!6G-=!5JI4!#5=^!0-pW!(d(g!;60'!g!D0q:u&JrVljGr;Zi#r7:qq +qu?`SrVu<A!<=Ii9`Z7TRf<G=!!)Zk!Tk^'!!=MnA(gh\!FmGS!":/`PU-;Uk5V\4 +,s3LP!!4HVk5##XKdHWs![U^KrVlu)!!#.MrrGtCpAb4Vg%t^LbWPe'!BdXbrr[rT +!)`^p!/:CP!/:FP!87>O!)`aq!O4cb!!PK[49,@krr3'_!%$e,rrXPI!)`[o!0mH_ +"53^h4So*[,uN@crrN0#J"Q`BIfLV=rrA;^!!?a2s+UCO!0ljM"5-OKg&D!Q^P0nS +rrLe!qZ$W?q>UFWrVusFbl%JBFCX#&rrBh2!!(7BrrCaL!!'d]rr_-Y!5F-c_uB`X +,g0Nq(BEp>!7(QC!5JI4!%@`r!-8#<!-nJB!9a0n!g!D0q:u&ErVlj_r;ZhkqptfW +r;ZiTrVu<A!<=Ii9`Z7TRf<G=!!)Wj!O4cc,m6>-KtldGrrhJZKnZ<$rrUl-^]"06 +k5YJ[bk1o<g!#/7bk_8>g!&g_"I)"p,lmoj!Frn<rrBh5K`Jm`rrLfsr;Qc3rVurO +rVltA,s9lYrrC:BK`Kg*rrJ@Kr;Qc@r;Qi54Ce6f!b4?trVllNrIk9Ik3r<O!!%M@ +rrRZM+OL,gA,QB.KtmQd!)`Ok!L,_F,lqMjr;Qs`!!#mrF=$nd!BeTlrrP;/;<@fX +4T5<\-2mlEPktC[FT)7@--Z#]!/::M!/:FP!/::M!/8i#"5a(Y^OlL'rrF,cb?k8d +!:R]'d/EtE^\n-42>bu*C]+55J,TBIi;(.iO8s\(h#R0Irr>=_!!&_if)Qcg!!(pT +s6e\D!%,l`!?E2LrrRZM!1*Wck02W\!l'H([/U1-!.UX@!e11mci3u-r;ZgDrVusF +oD8IfbWP\$!+Z!-"=4$J,s;&)!'KWJ!0mH_!6jX+!/:CP!Bc)8!!$O+rrM7.rVuq_ +oD\eQqZ$V+rr2s\qZ$V+dJj=+!!'ccs24j;*@/g8!>bb)^];a[rrBh4!!"nRf)TUb +!!%NIrrD!Q^]KStI/2RupAP!k5lCZ_U&3FA)uTa:hu3TCh#RL&b=r!X*Ld!0IfKJ# +s.95l!!%M@rrRZM+O9ue4Sf$X^\[s2jsBa%!2KPn!%%==!5Iq$!/:CP!6j[,!Tk^- +!!0@KrVupEqu6Y+rVupqo)A\9qZ$aFs8V4-qZ$UYdJj=+!!'ccs24j;*@/g8!>bb) +^];a[rrBh4!!"nRf)TUb!!%NIrrD!Q^]KStI/2RupAP!k5lCZ_U&3FA)uTa:hu3TC +h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M@rrRZM+O9ufbU*/e!0m<Z!)`^q"=8/DKi.gL +!)`aq!%%LB!HaS*!!%`?rr@cP!!(7,rr>pq!!Z=#s!7XF-2[]B-2mlE^[qI*g%k[N +-3+"0rW!'`,ldokdJj=+!!'ccs24j;*@/g8!>bb,^]W$Cn+6MX!5JI4!&aZ*!,MN5 +!.XtI!;H<X!oq&Pq=XgerVlj_r;Zhkqptfer;ZiTrVlunoBYE,h#RL&b=r!X*Ld!0 +IfKJ#s.95l!!%M@rrRZM+O0od;>gIp4Sf!W^]"3:4S/UQ^HDJq!+Z$.!%%OC#,D4u +,ldpBnc&T2r?_FCr?VGcmJd0krW!'Ik5YHDrVur5rVlkmrVup\o)A]SrVus]4T5<^ +^]-Fq!!/<HrVurOdf0F,!!'ccs24j;*@/g8!>bb.^]DaRq>UH0r;ZgTqptg`r;ZhI +jSo3Fr;Zhkqptfer;ZiTq>UKfj7M..!%,l`!?E2LrrRZM!.t6BrrN0#J"Q`BIfLV: +rr?R+!!';#rr?R.!!C"9UJ^ph!5JO5!%%RD!-J5?"!mpI4S&LQjsB[#!6jm2!'L5\ +"B!BsKdH]u!/:CO!+Z!.!0m'S!'L5\!L.^*!!dW.,ldoks'u$.!2J!B"5a(Y^OlL' +rrF,cb?k8d!;=2/_WU[n!5JI4!&aZ*!,MN5!.X)0!'pJ_!29;A!#tk:!8mPN!:BI8 +!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UX@!e11mci4!!q>^OBoDAOk,ldokKfo85!@=N> +rr=AE!!">ErrhI1!!#.Orr>1T!!">6rrM7lo`+tSrVlj[rVurBo)A\9rVuuP^]"36 +4I#gF!`Au^rVuq.df0F,!!'ccs24j;*@/g8!>bb0^]<]orrBh4!!"nRf)TUb!!%N0 +rr>=_!!&_if)Qcg!!(pMrrM`JpY>iM-Hf*a*?CUK!e11MK)_GB!WW4MTDntB!$KYg +!2KJm!B_\-!!#mnrr=A@!!+C"qu6XBrVuq.rr2uBrVup\nG`U7KnX%9!!K(@b_>3J +rr>1R!!">Drr>1\!!(77rrBh5!!ahMs!7XF,piNj!i,e>rVupEdf0F,!!'ccs24j; +*@/g8!>bb1^]<*]rrBh4!!"nRf)TUb!!%N0rr>=_!!&_if)Qcg!!(pLrrDZbh#RL& +b=r!X*Ld!0IfKJ#s.95l!!%M@rrRZM+OU2hU\t/o-1eD?!!&8]rr=AB!!+C"qYpQ> +r;Zi4rr2uBrVup\mJd0?rVurBli-rIquH[A!B_\-!!(7Brr>1\!!'e0rrSsL^]+65 +A,ZH1;?-YYqZ$UBrr3*I!!">-e,KO-!!'ccs24j;*@/g8!>bb2^]DIRr;QeQ+LV7O +5aV6CrrD-Th#RL&b=r!X*Ld!0IfKJ#s.95l!!%M@rrRZM+O^8jbU*5g"=;:ls'u$. +!@>tgrr=AD!!,3Wq#:?<rVusFk5PA\bl.SB4RN.KL&M&Pg$J_=^\n-5UWiZ9!+Z!. +!/:FP!-J2?!)`Xn#j+ta!%$e-s!@XE"-iicFSc%<A,cK.4T5<\UXT5FhZ*YkK)`ag +!?EH/?NCrCpqQmirVlom33iMb0^nu?!;6-C!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UX@ +!e11me,KHm-2mlF--Z>f!'L5\!'L5["=4$J-):A;"m2&6s8U=B!!">CrrXPI!%%%4 +"0hh+-0tR2;>pOq4So'X^]"354T>?\g&1mNA,ZE.KdHZt"3gf--2mlHbl@^rqZ$W2 +rr2tPrVupqe,KO-!!'ccs24j;*@/g8!>bb2^]=91rr?H2!!#:_rrN,Vq:u&O-Hf*a +*?FVK!8"@Q!e11MK)_GB!WW4MnG`L?Z2XlT!$Kek!R)kg!!';%rrBh4!!#mqrr@cP +!":0-g&M)rF<pneU]8R;!!">CrrXPI!%%"3!l'HOm/I+K-2mlEU\Xoi-2mlEg&D!O +A,QB0,s4:9qu?g]s8U=B!!">Drr=AD!!">DrrBh5!!"=orr_-Y!5F-c_uB`X,g0Nq +(BF9H!6kEA!8"@R!8mbT!9a16!<=Ii9`Z7Tnc&Z_+LeKQ!e11MK)_GB!WW4Mo)Acp +0UK'E!e11mec,[4-2dfDU\aujL&CuOA,cK.-2[`D,piHh!l+cZrVupEr;QaZrVurB +ec,VkrVup\q#:>9rVuq?rVlj[p&G)&rr2tPrVupErVlk-r;Zh-r;QaCrVurBeGfX. +!!'ccs24j;*@/g8!>bb3^]<$crr@<B!!#!gIfL>a!!'5$rrD?[h#RL&b=r!X*V9:5 +T-++NXT&?O!!("<!-J2d"$A\f^OlLFrrN0#J+WaDY:oq^n$2loIfLVArr@cO!!&eh +rr>1[!!M!Ts3*V"!!d$6s5kU-!'L2Z!)`^q!6j!n!)`^q!2K>h"Qh!1!'L2Z!'L&W +!BdXcrr@cP!!#.[rrBh4!!'e3rr>1\!!%`&rr_-Y!5F-c_uB`X,g0Nq(BF9H!8.8M +!+>a*!2$e$!+>a*!2'5i!:'C9!<=Ii9`Z7Tp&>&b+T;?@E30'@IfKJgrrAhi!!+C1 +K)ap3!WW4MpAY/s0`D%P:pBs$IfLVArrA;_!!&efrr>1\!!(^NrrIg"qu?dE;6g*" +"!mpI;>gFoPl:X_g"$*)ffUQjpAY5i,pg>'rrJlWr?VJAU\k&k^]"35U\t,o49,A' +qu6YMrVuq_eGfX.!!'ccs24j;*@/g8!>bb3^]<$crr?I*!!&YjrrMB.]u9tDr;Zhi +rVll_q:u&O-Hf*a*?FnS!M:M4!!(?HrrRZM!65$=L%bQJ4P>>dk5PJ_!.XeD!O"3T +!!'4,rrRZM+OpDmKfl.'rr_ji-&)3q"PM"QPg'"(!l$j-qYpV,4L)j)!9WSH!i&Vf +qYpSkbk_8?F<tGGrr_-Y!5F-c_uB`X,g0Nq(BF9H!8.8M!+>a*"/#Vn`Oh'/2#RCS +TDecilM96:!%,l`!?E3VrrJ`7qZ$U5X8`6N!!(%=!/:CP!@9&h!!+C@K)b$6!WW4M +qYpT"0_tbLpTXZ!IfLUCs+^OUhZ*YkK)`ag!?EH/?NCrCq7m!_rVlk*r;Zqls7_Sd +MuY^5!!&YirrD?[h#RL&b=r!X*W,j;T-3q0!'mUb!e11M`r?$mrW!)Fs3-]iqu?`3 +K)b'7!WW4Mr;Qf$0_k\K+KteHIfLUCs+^OUhZ*YkK)`ag!?EH/?NCrCq7m!_rVlk* +r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9`Z7TrVlnj+SPj9@&s;/IfKJgrr@cP!!(7A +rrJ?1rVupEK)b'7!WW4Mrr3#&0_YPI5d11hIfLUCs+^OUhZ*YkK)`ag!?EH/?NCrC +q7m!_rVlk*r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9a)OXs8S]6RfLJ.!/:CP!6kB@ +!R)kh!!&8Js8:(@k3`0Lbi\d%!R0^"rrLg+q#:EKbfo2Kr6,0'ir9/^!.Y$P0Ve[O +0W0C#+G0WJrr_-Y!5F-c_uB`X,g0Nq(BF9H!8.8M!+>a*!h]M^\r6VGr;ZhirVll_ +q:u&O-Hf*c*?CapR/l+D!^%c+m/I'>rVurBqu6Y\rVup\qu6]3A,R\S4I#^B!i%k( +qu?aDZ2=P%UJ_":!Ft9irrXPI-/&4r&L@E'Z2aj!,s9l\UHBh&!'Js4rrKAerW!!G +;8;u-!P`.C,lp,mqYpVl4=0n*!@>#2rrW6$="p9I!cn>aK)^T*"5a(Y^OlL'rrF,c +b?k8d!;XD1f_tgM@/U',TE"DlMuY^5!!&YirrD?[h#RL&b=r$Y&eLE1hu<\@rVurB +mJd/`rVurBqYpXD!!#.Zrr@0:!!+CirVlk-p](:VrVloO4So*Z-):J>!2KMn!/:CO +!6kEB#DN3X,ldpB4So*Y;>pLpU\OliA,Q?,FSPn;--Z>f!+Yd(!'K<A!WW3/T)\pk +!$HmnLAqA5!!'ccs24j;*@/g8!>bb3^]<$crr?I*!!8emn@FPY2#RCSTDecilM96: +!%,l`"<ANOIh8%Khu<\1rVurBmJd/KrVurBqu6Y+rVup\rVlk>pAb1Urr2tnqZ$UB +rVup\rr3#]-2@ND-/&=uL&M&PL&M#OL&M&SL&_0!pAb1>rr2u'pAb3;rr2t?pAb1U +rr2tnqZ$UBrVup\j8T5^!.0bDU&Y9,HN51?s+^OUhZ*YkK)`ag!?EH/?NCrCq7m!_ +rVlk*r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9a2UYs8VP;&G?)(33.N156(]@rr@cP +!!(71rr>1\!!(7ArrM7lr;Zh>rr2u5r;ZstKnXUprW!&Rs8R3?!!d#Xg&J<'!/:FP +!'L2[![TrTrW!$ts8Psq!!&emrr@cP!!@rTs!@RC"XRY)!!">Err=AE!"*5[b]G-2 +!87DP^\n-8;2'^G-2mlHg&M(orW!15bh<$$,liYZrrrH'J,f8()"mq0.'\7)Qfihu ++G0WJrr_-Y!5F-c_uB`X,g0Nq(BF9H!8.8M!+>a*!h]M^\r6VGr;ZhirVll_q:u&O +-Hf*a*?G+Y!q1UMp](:rX8`6N!!)'Z!-J/crW)mC!-Ic2!'L5\"a#HP@lu(9!!+D; +rr2sqrVuq_rr2tPrW!'Ik5YHkrVuq_rVloOU]18nU\t0"PlLd-,ldokk5RRC!!(7A +rr@cP!!@rTs!@UD$&/EZ49,@-s8RfP!!#mprrUl-^]+65;>pOqPlC[_L&M&T-0G7- +A,ZH.Pl:U_fq[R,!WW4Mrr3&oNu7Wl!'%1^!e11mK)^T*"5a(Y^OlL'rrF,cb?k8d +!;XD1f_tgM@/U',TE"DlMuY^5!!&YirrD?[h#RL&b=r!X*W,j<msboF!!#!ZrrRZM +!9F.\jsB[#!6k$6!'KoS!@>thrs7a5!!#mrk&_pJ!!#mqrrAhm!!,3WqYpOmrVuq? +rVlk>rW!"ps#g8\!6kEA!/:CP",6dT-2mlEPlC[i@fQKks8OAF!%$e&rs7a5!!#mr +k&_pJ!!#mqrrAhm!!,3WhZ!WW!.XqH!r%`mq>^L4YQ"ZR!$HmnLAqA5!!'ccs24j; +*@/g8!>bb3^]<$crr?I*!!8emn@FPY2#RCSTDecilM96:!%,l`!?E3VrrVY=&GuM/ +&GN:+!e11Mj8T*Ap&G(=nc&SOpAb7@A*3ai!2KMn!d%ouqu?^or;Qb,qu?a[U\t,p +,ldokk5G;[bl.SDL&X:7!!(7Arr@cP!!^4<s!7XF4T,3^@o:qZU](5nFSGe8U](5p +FCQWp!!#morr?R,!!,3Wi;WiY!.XkF!r%`mqZ$WZYl=cS!$HmnLAqA5!!'ccs24j; +*@/g8!>bb3^]<$crr?I*!!8emn@FPY2#RCSTDecilM96:!%,l`!?E3TrrVY=&H)S/ +YH7a*IfKK.rr^K!Kk()^"Ja2bL$%q*!'L#V!@>#Jrr@cJ!!,s3qYpS<-2[`K;<IoY +js:!--2dcCbl.SDL&X:7!!(7Arr@cP!!^[Is!7XF4S\pVA,ZH.g%YLHL%kWK;8;u- +!H]Xc!!,sZir9&[!.XeD!r%`mr;ZhYYl=cS!$K\h!R.><K`Rt2lMgs?,s9D's4I>R +hZ*YkK)`ag!?EH/?NCrCq7m!_rVlk*r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9`Z7T +p&>3aIh2S[:osZuIfKK+rr@cP!!(71rr>1\!!">B!!+Bfr;QbNqZ$[D;8;l*!p3u= +r;ZpGg&K:q!!#.ZrrC:B!!7lSFT)7?bl.PAL&M&Vbl@\h!!#.VrrY@`!%%@=!/::M +![U^Yp\t<W@jV'R!@?FZrrN0#J+imGpQ$-k!&1YW!e11mdf0;EqZ$[D;8;Jt"!mpI +4T,3\k(UR7rrTrhg!Tg%hZ*YkK)`ag!?EH/?NCrCq7m!_rVlkBr;Zmq^U1Rc!$D.> +!2oeq!:'C9!<=Ii9`Z7ToD\s^Ih2nSXoAHP!!(pV!/:CP!86c>!'L5\"52@;-2[`D +4PB`6!/:@O![V@=o)A`E-2mlK;?-YB!!">CrrAhn!!8qqL&M&P^]"04L&M&Vbl@\h +!!#.VrrY@`!%%@=!/:@O![V@=o)A`E-2mlE;<.ZX!!%N@rri(W(]`0mrrRZM+Og>k +jsBd&!-IW."!mpI4T59_fd-UuFI)q,Pl:X_Z-rXShZ*YkK)`ag!?EH/?NCrCq7m!Y +rVllDXoJIJrVllYq:u&O-Hf*a*?F\M!q1W:XoAHP!!(pV"0hh+-1(X34T5<abl@_* +@jV'R"=:>Qs.fPn!'L,X!l'HBq#:TC,ldoks8ODE!!'e4rrtRc!%$e-Pl:X_L&M#O +L&M&Vbl@\h!!#.Vrr@0?!!&ekrrgR!s8Skn!!#.XrrTrhg%bRMbU!5h-0,",!!%N> +rrVqUO0S]dIfLV?rrC::!!$NsrrXPI!'L5[!/:CP!%!s2!'L5\!)_2E"5a(Y^OlL' +rrF,cb?k8d!;XD2_YsH5!'mag!$M4>!9!\/!<=Ii9`Z7TRf<G=!!(mU!l'HOm/I&J +rVurBrVloO4T#0]^]4<[rW!I+^]4>rUJV!k4TGG'4ES@;rs-:b!!">Fs+UFP"=9he +^HDJq"&]*ubl.SG4MT+TKfo>7#0d,I,ldp-q#:?/rVusFPlC[fUHAMVZ2ahMrW!I+ +^]4>rUJV!k4TGG'4ES@;rrg(_!!">*rrN0#J"Q`BIfLV?rrC:B!!IDfbbI<!!!':m +rrXPI!'L5[!2KMn!)]'^!+Z!.!0kq3"5a(Y^OlL'rrF,cb?k8d!;O>0j8JuYh[$Lf +!>+/errD]dh#RL&b=r!X*Ld!0IfKJgrr>1\!!(7?rr?R-!!>@`s+U@Nr[%LC!^-M, +r;cgCr;Zgprr2sEp](=@g&D!O-2%<CPlLb0!!#.Urr>pp!<+;C!!@rTs+U@Nr[%LC +!^-M,r;cgCr;Zgpj8T/\!.UX@!e11me,KElrVuqPrVlk-rVup\n,EJ9!!#.ZrrSrX +A!HupKfk(:rr_-Y!5F-c_uB`X,g0Nq(BF6G!6kB@!S9<=!!3F.fDPXKj7qF2!%,l` +!?E2LrrRZM!65$=4T5<\bkh>>U](5n4T>?\FS>b<--ZDO-27H@-/&:t!P]rV!!&em +rr@07!!\/Ws!7XF4SJdT4SSmW-/&:t!-Ir8"=;:ljsBd&!@?FZrrN0#J"Q`BIfLV? +rrA;_!!%`NrrY@`!%%+6"!mpI4G*Ucrr_-Y!5F-c_uB`X,g0Nq(BF3F!9O+X!T-HH +!!@G[^UM1U!+c$.!I+#0rrDQ_h#RL&b=r!X*Ld!0IfKJgrr]MP!'L&V"0jsNbl.PC +^JQ<T!!4HgoD\aj^HDAn![U^sr;QfA4T#0[4L+e`!H]Xc!!">E!!\\fs!7XFFS5Y7 +F=$hb!@<HsrrTr4-2[`E-$8bXrrKksqZ$[D;;'t/!WW4MTDntB!$Kbj!/:CP!5JI3 +"$?P`-1Cj9,ldp-nG`R6bi[LV!TqW(rrLfsqYpTLbl.PCKfk(grr^r=UZVLS!jOjt +rr3)_UQjI'rrQ[mZ2Xb)b_<ggrr_-Y!5F-c_uB`X,g0Nq(BF3F!Q+O,rr?I*!!Akn +s7F:^!/CFP!2'/g!;-!@!<=Ii9`Z7TRf<G=!!("<!TqVmrrgQ@Ktl=:rrCaNK`Rt2 +q#:?/re1?ep\tN6KnZ;Ts)]Psrr3&7;0;C/"J^ZJKtm?]"O*Wp^Y/G_!87=)!Mef8 +rrN0#J"Q`BIfLVWrrZaW4Qc&2!/:CP!6kB@"!mpI-2dcIk&`^3,s7t"rrXPI!'L5[ +"2?-.A,?30@jM*T,pe9DrrQ%DFSYq=YpC]koD]EU4=-d&^JQ:'!%"E?s+LFQA,Q?2 +K`D*8s8Skn!!9pZ4T5<]-$9.d#Nd<4!/:#A-2mlE;>gFrKdA%?rr314!!">FUF#m> +!@=N:rrJm:r]C48k3r<PhZ*YkK)`ag!?EH/?NCrCp:p^Op&+gi@/U'-TE"r``Rb*E +r;Zhir;Qcdp"]WK-Hf*a*?CUK!e11MK)_GB!WW4MTDntB!$LY.!87>O!/9h?!/:CP +!6kEA!-J2?!)`^p!JMis!!#.ZrrXPI!'L5["?ZYa-0G.*!'L)X"!u1kA,ZH.Z24J& +,ldokoD\qj!!"<BqZ$gHs8OAF!%%RC#!;kc-3+"!rVus]-2RZEU]:A<rVusF-2RZB +A,ZE0,ldokrr2s\rVup\qZ$XCk5>5[KdHTr!@<Hhrr_-Y!5F-c_uB`X,g0Nq(BF*C +!:0U`!+>a*"/#VnoYoD^LA_)PTDecimI]38!%,l`!?E2LrrRZM!.t6BrrN0#J"Q`B +IfLVXrrC:B!!%`?rr@cP!!LOGs4Lo\!!'e5rr@09!!$O-rrXPI!'L5[!'L5\!6kEA +!'L#V!^-L)rVusFoDJUgL&M&P4S/RQ4SAaYbl8sh!%%RC"sj6L-3+"!p&G1Ws8U=: +!!">DrrXPI!%%XE!'KrT!-J2>!'KuU!'KfO"5a(Y^OlL'rrF,cb?k8d!;+&,kPbD\ +@/U'-TE"r``Rb*Er;ZhirVll_o\BNJ-Hf*a*?CUK!e11MK)_GB!WW4MTDntB!$LY. +!6kEB!/9h?!'L5\!^&Rkqu?_,rr2u'r;ZmF4=0q+!5JO5"!mpI4T59^49,@-rVlkO +rW!9OUWfJq!!#mrjsC!,!+Ys,!%%UE!2K/c!'L/Z![U]@rVuuCg&:sO-2dcI,ldok +s8RfM!!k]^49,@-s8U=?!!4I2A,ZH.bl7VE,ldp-rr2s\qZ$e0UEom?4T>?\4T,6^ +4GAJdrVupEnc&^K!!'ccs24j;*@/g8!>bb.^]<Qrrr?I*!!@G[^UM1U!+l*/!2'5i +!:'44!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UX@!e11mnG`Na4T6Z+!<"2D;=XYd4SJgU +A,ZE-4T5<`4Qc\DA,ZH.A,cK1,ldp-rVls^!!">Drr=AE!!'e4rrJ@Krr2tPr;Zi4 +rr2tPrVupEo)A\Pr;Zq0oDaOD!!1<frVup\r;QsI!!">Fs+U@N"$HV`L&M&Rg&K:o +!!=Oks31HB!0mK_"!mpI4T>?\4T#0cA,lQk!!">Fs-3K_!@>MZrrXPI!%%18"5a(Y +^OlL'rrF,cb?k8d!;+&,kPbD\@(61:TDecilL`m5!%,l`!?E2LrrRZM!.t6BrrN0# +J"Q`BIfLV\rr=A<!!%`Drr>1W!!+C1rVllNrVusFk5G;^,ldokrr3'H!!#.[rrXPI +!%%XE!/:CP!-Ir7!'L5\!)`aq!%%UE!/:"D!'L5\!+Z$."eu%t-0EGN!!#.ZrrsbL +!%%[FL&CuS-0G7-L&M&Rbl>ob!!BM+s31HB",6dTbl.SB4T>?\4T,6[4T>?b49,@- +s8ODE!!'e3rrXPI!%%18"5a(Y^OlL'rrF,cb?k8d!;+&,kPbD\@(61:TDecilL`m5 +!%,l`!?E2LrrRZM!.t6BrrN0#J"Q`BIfLV\rr@06!!'e)rr>1\!<,(]A#&r$!/:CP +!+Ys,"$?P`-3!oH,ldp-rVlsG!!">ErrXPI!%%=<!3uJ&!l+bhrVupEnc&_S!!">: +rVm"S4L+q1rVup\r;QsI!!#.]s+UCO!/:FP!+Z!.!mL\gr;Zgprr2tnrW!%Ss8U=B +!!#.\rr>1[!!'e5rrj\K!%%ZurVup\r;Qo^,ldp-nc&^K!!'ccs24j;*@/g8!>bb. +^]<Qrrr?I*!!Akns7F:^!/CFP!2'5i!:'44!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UX@ +!e11mn,ELCP_Fhj!!IDfb`om4rrY@`!%%@=!+Z!.!2KJl"$?P`-3!oH,ldp-rVm3N +!!">Fs5kU-!)`Cg!)`^q!^-K/rVuqPnc&\R!!">?rrC:B!!#.ZrrsbL!'L;]L&M&Q +-0G4,!'L5\!mL\gr;Zhmrr2tPrW!%Ss8U=B!!#.\rr>1\!!">Drrj\K!%%Z?rVuqP +r;Qc@xxxxxxx&^K!!'ccs24j;*@/g8!>bb.^]<Qrrr?I*!!Akns7F:^!/CFP!2'5i +!:'44!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UX@!e11mm/I(0rVuqPmJd87!!#.Trr>1\ +!!(7@rrY@`!%%XE"!mpI4T59a,ldoks8U=B!!%`FrrBh4!!#mq!!">7rrY@`!%%C> +"!mpI4T,3`,ldp-s8P4\!!#.[rr>1\!!:CEL&M&P-2miDL&M&SL&_1srVup\rr2sE +rVuq?rVm$I!!">FL&M&PL&CrNL&M&PL%50FhZ*YkK)`ag!?EH/?NCrCoY:IirVlk* +r;Zqls8V`1f)UR(!!&YirrD?Vh#RL&b=r!X*Ld!0IfKJ#s.95l!!%M@rrRZM+RK+. +bl.SBPjSJQ,ldp-pAY,HrVuqnr;QjF!!">ErrXPI!'L5["sj6L-3+"hrVuqPoD\f# +q>^MLnG`SQ!!">>rrXPI!'L2Z"sj6L4TGFDrVuq.rVlj[rW!#Ds+UFP!%%UD!/:CP +",6dTbl.SB4T>?\-2mlEU](2r,ldoks+UFP!/:@N!'L5\!2K)a"5a(Y^OlL'rrF,c +b?k8d!;+&,kPbD\@/U'-TE"r``Rb*Er;ZhirVll_o\BNJ-Hf*a*?CUK!e11MK)_GB +!WW4MTDntB!$LY."Qh!1!86c>"!mpI4SJdTU](5n;>pLpPl:X_A,cK1,ldp-rVlsG +!!">ErrXPI!'L/Y!TqW'rrM7.qu?^Cn,EJP!!">>rrXPI!%%RC"sj6L4TGFDrVuqP +rVlkOrW!"as+UFP!'L5[!6kEB"&]*ubl.SB4T>?\-2mlEbl.PA4T5<]ft[Ld!+Z!- +!0mE^!6k!5"5a(Y^OlL'rrF,cb?k8d!;+&,kPbD\@/U'-TE"r``Rb*Er;ZhirVll_ +o\BNJ-Hf*a*?CUK!e11MK)_GB!WW4MTDntB!$LV-!p53Om/I/6!!#.Srr=AE!!?`T +b_>uq!5JO5"!mpI4T59^,ldokrr2sqrW!4$g&M*7@jM+;qu6Y+qu?_Nn,EJP!!">> +rr>1\!!J#"b`m5K!!>@`s#g8\!/:CO!/:CP!d+HrrVup\rVllArW!$_s8U=B!!#.\ +rr=AE!!(7Arr>1\!"$F?,ldok^]4=uqu?`@nc&^K!!'ccs24j;*@/g8!>bb.^]<Qr +rr?I*!!Akns7F:^!/CFP!2'5i!:'44!<=Ii9`Z7TRf<G=!!(^P!P_M1,lqN<jo5>P +rr3"/;;M6Rjuh>orrg)64?S>jrrM8(r]C1Fo)Acr4I#aC"MZ89s7?)@!5I7f!WW4M +TDntB!$Kbj"!mpI4SA^SL%bQIA,ZE0,ldp-rVlsG!!">ErrBh3!<+;D!!">BrrM^; +rVusFk3r<P49,@-p\t58p&G1@s8P4\!!&8^rrC:B!!5:_L&M&P;>gFu,ldoks8U=B +!!#.\rr=AE!!(^Nrr@cP!!7lSFSu1?,piEg!86oB"5a(Y^OlL'rrF,cb?k8d!;+&, +kPbD\@/U'-:Odk?`G5H@r;ZhirVll_o\BNJ-Hf*a*?CUK!e11MgA_5L!!*!\"!mpn +^Zb\!o/qa+rrG5.h>[O=!6kB@#GV8F4?NU+oD&=jYpBB44='tio`#$b,liYrrrdEi +s8U=>!!%`,rrN0#J"Q`BIfLV?rrXPI!'KoR!)`Ol!'L2Z"!mpI4T59^,ldokrVlkm +pAb2'qYpOXrVuq.mf*AO!!">>rrM7.pAb:As8QU.!!(7ArrCaO!!5:_U](5nL&CrT +,ldoks8UdO!!#.\rrXPI!%%RC!0mH_",6dT4Sf$[,ldoknG`UJ!!'ccs24j;*@/g8 +!>bb.^]<Qrrr?H:!!&YirrD?Vh#RL&b=r!X*Ld!0IfKK'rr_C0-,9EY!gE[2kl1_. +!/:FP!SP]SrrhIH!!(7Ars7a54S/UQUB"g!rrOJm^]+67@fU$3rrZ*u!/:=M"smdZ +s+LHJr6,04gA_3S!.UX@!e11me,KNF,pfhfrrI3fr;ZjEA,H9.49,AVrVltR,pd[2 +rrKksqu?dE;8;u-!87>O!@?mrrrZ*u!'KuT!R*\(!!aer!!">Fs-3K_!87;M"XO-K +;?,>K!!&8]rrZ*u!%%XE"&T%EZ2Xb*;#gSBr;QcMrVuq_rr3"@-2dfH;02d<-1Lp: +hZ*YkK)`ag!?EH/?NCrCoY:IirVlk*\,ZN$rVll_o\BNJ-Hf*a*?CUK!e11Mg]%>> +!-J,<!`8s4l2Lh/!/92-"dC;5493V(rrR9BU](2o4=0.drrSqqFSu.>,pi9b"I&mK +!/:@N#Nd>-s8PqBk1'D4!!%M@rrRZM+Me!\k*1RRPihfA!R06orrM9Eq>UWOKlggh +k4nrVA,ZH.A*s9uk$qoSo`#6NP_Fh8s3*Sf^]+67F?Hi*rrTGfA,cK0PWXZsrr^qO +;;(pJ!87;M"6NHXg&(dNKfk(drs6AnL"ZJg!!">7rr_-Y!5F-c_uB`X,g0Nq(BF*C +!9a=\!+>a*"/#VnoYoD^LA_)PTDecilL`m5!%,l`!?E2LrrRZM!8IMTK`H5lrrTrh +^]"09UHBhbA(ge[&E[Ib,s7t&s'n.k,s7Fl@o<4)"m0;W,s7Fjrs+ccs._\&4I#U? +#0['0^P)[3rVlm\-2dcEK`InErrTrWPl1O^4=0b%"kb23K`Hi)rrJ?1rr3!F-.Dkq +!!%M@rrRZM+Hla*jsC!,!83M7"!mpI4Ri@QhZ*YkK)`ag!?EH/?NCrCoY:IirVlk* +r;Zqls8V`1f)UR(!!&YirrD?Vh#RL&b=r!X*Ld!0IfKK'rr^pS-):26#@d`[4?Oo9 +U]19*YpBB44='u;s'n.k,s7Fl4=1",#GWRF4?Oni4T>?dKdC4T4?OniFSPk?fq\TI +K`K?qrrFDlr;Qi5!/:%E!p1dTp\tCZ4TC*8L&CrO;*=jX"slCH@m"89f`)!Q!.UX@ +!dF\NP5bN9rVupqOoGEVrVuq.nG`U:!!'ccs24j;*@/g8!>bb/^]DaTrVlk*r;Zql +s8V`1f)UR(!!&YirrMiOp"]WK-Hf*a*?CUK!e11MgA_A!!!"<-L!9Go!egVarr38J +,ph^Rs!8u+rr31"!5JQX!/:FP#<X=4s5kUR^]+6B@fU$=s+LG!bl@^e,pi3`!egWu +rVlmE4T,3\bQ(N3rrQ[1L%tZPF9')UK`Hi)rsU3-s8U:C,lf5;!!%,orrN0#J"Q`C +QN.$KPQ(V/rVuqnR/[01r;Qf4-2mlE^[V7*[f?ESK)`ag!?EH/?NCrCp:p[\qu6Y( +r;Zqls8V`1f)UR(!!&YhrrN&[p>#`L-Hf*a*?CUK!e11Mg&D,g;'l2A!@;7SrrOJm +oDS[nUB$PYUB#E7rs$5#Z2`#JL&V)V4=1%-PQ6F8rrsbqk5U,8Pl:U`493UurrRlS +bl.PB,s;,*!mCX,o`"u&!'L&V#JU7ms8RcQL&M#]bQ->rs-*LG^]4>K,lj^orrN0# +J"Q`C[f?ESPlC`urVupERK!EC,lf5;r]L,Z!'K`M".oPnkCW`OrrF,cb?k8d!;F80 +b5M5;!+>a*"/#VnoYoD^LA_)PTDSWhrSdM,!<=Ii9`Z7TRf<G=!!(UM$GU[F,lg(! +s5kUir6,A?!'L:'!5J@0!mCXurr30b-3+!-!6kB@#%IYWs+LHsrVlqQ!6k-9!egWu +rVlmE4T,3\bQ'currQ[14SSjV4?WWC!egW.rVln?-3!oFo?@.4!l"^tgA_3S!.UX@ +"4$rIYE]%eFT)7?A"!>sL%bQJ--YiX!dF\FK)`^f!?EH/?NCrCpV6e%r;QiULEZTr +""6E"4iK8Y,5hKC18!b-rrMuQptYrN-Hf*a*?CUK!e11Me,KU649/mkbkM/@4T@MD +bk_8?bQ*@rrrkM2s8P2-qu6kS!/:H,!6kEA!egWup&>)I!6kEA!@9l+rrUCEFS>_9 +;#i`QrrQ[Vbl7VDK`Hi*rrG5ZpAY.>-//A#!!%M@rr_]i!+;&k!+Z!.!83e?!SJdp +!!,48mf*>:!%<I!_Z'WW,g0Nq(BF6G!7^rH!M9q1!!*@\r;Qc`ptYrN-Hf*a*?CUK +!e11Mg]%:aA,?30js;>RbQ'd%bQQW!;#ni9rrUCEL&V)V4=1%-4=0.frs"/WU]6#J +bl.PCK`K?irrRlSbl.PB,piKh!i#aLq#:HY49/mbrrFDGr$;RJ,pe9Fjs?errrFDl +gA_3S!.UU?"$chtpQY[Z;'g=MrrJm:r]C6ZL"Ykn"5a(YG_5t4rrF,cb?k8d!;O>0 +oDS[hVm$.$TDeciqY8kI!%,l`!?E2LrrRZM!8IMT,ph^Mrrj\ps8OAkqu6iQs8RcQ +U\t,q;3_+)!/:FP#!=43s'l&Dr;Qsu!6kIs!6kEA!egWup&>)I!6kEA!^%dkrVlq@ +!5J@0"7mf=FS5Y6;>`N^,lf5RPlIL)k5PA^@m&oOrrFDlgA_3S!.UU?".&uf[t=X: +rr\#V!5F-c_Z'WW,g0Nq(BF9H!6G-=!V[G8!!*AorVllWq:u&O-Hf*a*?CUK!e11M +g]%@c!'KlNrs+5XA,lQk!5JL4#)*%es1\P2rVm(s!-J7b!/:FP#!=43s.]R(rVm,b +,piTkK`K?qrrRlSbk:u;K`K?qrrSDbL&M#P,pi?d!^$IXmf*?B!/:FP!Fn7jrrQ[1 +L&M#QPQ54IrrN0#J"HZBk5YKYK)^`."8=JL(kVe(rrF,cb?k8d!;XD1f)>UKVlg"" +\,H=,kP<p7!%,l`!?E2LrrRZM!8@H&49-[L^W`HM!%$e-s1\O[U]:@Y!%$e-s%rc+ +k5V\4-0G6O!%#D5s#_V,rs_'jA*3g+491WGs+LHsrVlqQ!6k-9!egWur;R!J!0mNG +491*7rs+cNPlLcJ!%%Jqrr3!r;>L4nK`Hi+rrFEfrVm2d,lj20s-*L0k1]h:!!%M> +rr[3?!7-8sMuNm?!!&(3s2"^9*@/g8!>bb3^]<$crr?I*!!8Men@FPY2#RCSTDeci +lM96:!%,l`!?E2LrrRZM!87AQ;'l,?!E%PKrs,;F!$rok--Z>f##P@H,lf78rr30b +!!%-@4=0t+##P@H,lf6Urr3%R!6kEA!egWup&>)I!6kB@#0]10,p`P$rVm%T!/:IQ +4S\sW-3!oF,piBe#DE/3s8UaPbl%JG^Eik+,lg'Og&D*R!.UR>"6Tpi:kJ_+rri'5 +!#YH^s2"^9*@/g8!>bb3^]<$crr?I*!!8emn@FPY2#RCSTDecilM96:!%,l`!?E2L +rrRZM!8.;Tk+dWaPhGm4"2BPD^\[s4fnG-Tqu6i7PhH)ibl%JCfnG-Tr;Qfhbl%JA +o??k,!V=P2rr]$ML"ZD("nTt0s8UdIbl7VCbfon_#4p(1s8Tifq>UQ3Kn[:nrrN0# +J"6N@Du]m!K)^i1"(2*/YCceirrF,cb?k8d!;XD1f_tgM@/U',TE"DlMuY^5!!&Yi +rrD?[h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M=rrhL-!!'K[s,[0^NrT/FK)`Uc!?EH/ +?NCrCq7m!_rVlk*r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9`Z7TRf<G=!!%WNT)Sil +!.UL<"O@>R&C5t.OoGQf!!"/1K)`Uc!?EH/?NCrCq7m!_rVlk*r;Znks7!UY!&XWS +!2'5i!:'C9!<=Ii9`Z7TRf<G=!!%WNT)Sil!.UI;"Kqe*#cE:SPQ(c@!!!;VK)`Rb +!?EH/?NCrCq7m!_rVlk*r;Znks7!UY!&XWS!2'5i!:'C9!<=Ii9`Z7TRf<G=!!%WN +T)Sil!.UF:!13Zb!Isiqs-N`hmoTPi&@[8k^&J*R,g0Nq(BF9H!8.8M!+>a*!h]M^ +\r6VGr;ZhirVll_q:u&O-Hf*a*?CUK!e11MK)_GB!WW4MR/[?)&-)\IT7[*3rs&4I +&-)\Yf7O%8rrF,cb?k8d!;XD1f_tgM@/U',TE"DlMuY^5!!&YirrD?[h#RL&b=r!X +*Ld!0IfKJ#s.95l!!%M8rrM"*rW!!BE6j.9TDnu%BGg^K!D)[2s1A:3*@/g8!>bb3 +^]<$crr?I*!!8emn@FPY2#RCSTDecilM96:!%,l`!?E2LrrRZM!.t6BrrN0#J!L$7 +T-4(4"!D!$ItGG6^BBUIIo$^T!!+dgK)`C]!?EH/?NCrCq7m!_rVlk*r;Znks7!UY +!&XWS!2'5i!:'C9!<=Ii9`Z7TRf<G=!!%WNT)Sil!.U75!r%HuJcM8?!AL^/s0r"/ +*@/g8!>bb3^]<$crr?I*!!8emn@FPY2#RCSTDecilM96:!%,l`!?E2LrrRZM!.t6B +rrN0#J!'a5f7-%FJcMSH":.7`Qf!Dp[Jp7J,g0Nq(BF9H!8.8M!+>a*!h]M^\r6VG +r;ZhirVll_q:u&O-Hf*a*?CUK!e11MK)_GB!WW4MK)^H&K)^H&h>[Kr,g0Nq(BF9H +!8.8M!+>a*"/#VnV7VZd2#RCSTDecilM96:!%,l`!?E2LrrRZM!.t6BrrN0#ItI]P +s+:9&s5!\U*@/g8!>bb3^]<$crr?I*!!Jqos81$QW;o0]!!&YirrD?[h#RL&b=r!X +*Ld!0IfKJ#s.95l!!%M#s+:9&s+::,rrF,cb?k8d!;XD1f_tgM@/U'*T=Fn$@/U'* +TDecilM96:!%,l`!?E2LrrRZM!.t6BrrN0#ItI]Ps+:9&s5!\U*@/g8!>bb3^]<$c +rr?I*!!&(irr?I*!!&YirrD?[h#RL&b=r!X*Ld!0IfKJ#s.95l!!%M#s+:9&s+::, +rrF,cb?k8d!;XD1f)>UKVlg""\,H=,l1s-9!%,l`!?E2LrrRZM!.o]lIf]TMItI]P +s+:9&s5!\U*@/g8!>bb3^];ISrrMj2YQ+\0n,<7djS@U4!%,l`!?E2Lrr@h+!1Elf +ItI]Ps+:9&s5!\U*@/g8!>bb2^]=!)rrA[q!!&YirrDulh#RL&b=r!X*Ld!/f,0)> +S,`R,c[u1Ks+:9&s5!\U*@/g8!>bb2^];m^rrJ/dZiC+4L]%/PnG(f?!%,l`!?E24 +s+:9&s+:9&s+:90rrF,cb?k8d!;F8/p&+gkhg\2,5QXKKkPY>\r87;*!<=Ii9`Z7T +K)^H&K)^H&K)^H&N;io!,g0Nq(BF3F!QtA@rrN,^pY>iM-Hf*a*?Bb3K)^H&K)^H& +K)^f0!?EH/?NCrCp:p[\X8`5"kP!^4!%,l`!?E24s+:9&s+:9&s+:90rrF,cb?k8d +!;4,.deBpE!Vk[Ih#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>bb.^]MC0pTjf" +p?;,(!<=Ii9`Z7TK)^H&K)^H&K)^H&N;io!,g0Nq(BF!@!QrpJhu^uM^>A8Zl/pjm +h#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ^]KStI*:=H!%,l`!?E24s+:9& +s+:9&s+:90rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8 +!>baZ^]KStI*:=H!%,l`!?E24s+:9&s+:9&s+:90rrF,cb?k8d!6`.ZO8s[Oh#RL& +b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ^]KStI*:=H!%,l`!?E24s+:9&s+:9& +s+:90rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ +^]KStI*:=H!%,l`!?E24s+:9&s+:9&s+:90rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X +*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ^]KStI*:=H!%,l`!?E24s+:9&s+:9&s+:90 +rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ^]KSt +I*:=H!%,l`!?E24s+:9&s+:9&s+:90rrF,cb?k8d!6`.ZO8s[Oh#RL&b=r!X*J4<C +s+:9&s+:9&s,?sY*@/g8!>baZ^]KStI*:=H!%,l`!?E24s+:9&s+:9&s+:90rrF,c +b?k8d!6`.ZO8s[Oh#RL&b=r!X*J4<Cs+:9&s+:9&s,?sY*@/g8!>baZ^]KStI*:=H +!%,l`!?E24s+:9&s+:9&s+:90rr=Bt!1s5k*eOEDs+:9&s+:9&s,?sXYKD=qDbnQ+ +!ddFabC9OkB?G](YCce+s+:9&s+:9Grr +~> +grestore +currentdict /inputf undef +currentdict /pstr undef diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,109 @@ +D/audio//// +D/hw//// +D/linux-user//// +D/pc-bios//// +D/slirp//// +D/target-arm//// +D/target-i386//// +D/target-ppc//// +D/target-sparc//// +D/tests//// +D/fpu//// +D/keymaps//// +D/target-mips//// +/.cvsignore/1.13/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/COPYING/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/COPYING.LIB/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/Changelog/1.116/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/LICENSE/1.2/Sat Feb 12 14:45:23 2005//Trelease_0_8_1 +/Makefile/1.99/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/Makefile.target/1.107/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/README/1.12/Wed May 24 10:40:08 2006//Trelease_0_8_1 +/README.distrib/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/TODO/1.38/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/VERSION/1.28/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/a.out.h/1.2/Wed May 24 10:40:08 2006//Trelease_0_8_1 +/aes.c/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/aes.h/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/alpha-dis.c/1.3/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/alpha.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/arm-dis.c/1.3/Wed May 24 10:40:08 2006//Trelease_0_8_1 +/arm.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/block-bochs.c/1.1/Tue Apr 26 21:34:00 2005//Trelease_0_8_1 +/block-cloop.c/1.3/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/block-cow.c/1.5/Thu May 25 12:38:49 2006//Trelease_0_8_1 +/block-dmg.c/1.4/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/block-qcow.c/1.6/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/block-vmdk.c/1.7/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/block-vpc.c/1.2/Thu May 25 12:38:49 2006//Trelease_0_8_1 +/block-vvfat.c/1.5/Thu May 25 18:22:25 2006//Trelease_0_8_1 +/block.c/1.26/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/block_int.h/1.4/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/bswap.h/1.5/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/cocoa.m/1.8/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/configure/1.100/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/console.c/1.5/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/cpu-all.h/1.54/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/cpu-defs.h/1.15/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/cpu-exec.c/1.78/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/dis-asm.h/1.11/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/disas.c/1.30/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/disas.h/1.7/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/dyngen-exec.h/1.27/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/dyngen-op.h/1.1/Mon Jan 3 23:40:55 2005//Trelease_0_8_1 +/dyngen.c/1.42/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/dyngen.h/1.10/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/elf.h/1.6/Thu May 25 12:38:50 2006//Trelease_0_8_1 +/elf_ops.h/1.3/Tue May 2 20:54:12 2006//Trelease_0_8_1 +/exec-all.h/1.47/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/exec.c/1.79/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/gdbstub.c/1.36/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/gdbstub.h/1.2/Tue Apr 26 20:42:36 2005//Trelease_0_8_1 +/i386-dis.c/1.5/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/i386-vl.ld/1.3/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/i386.ld/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/ia64.ld/1.1/Thu Apr 7 22:20:28 2005//Trelease_0_8_1 +/keymaps.c/1.2/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/kqemu.c/1.10/Thu May 25 18:22:26 2006//Trelease_0_8_1 +/kqemu.h/1.1/Wed Feb 8 22:39:17 2006//Trelease_0_8_1 +/linux-2.6.9-qemu-fast.patch/1.1/Wed Dec 8 23:48:11 2004//Trelease_0_8_1 +/loader.c/1.2/Wed Apr 26 22:05:26 2006//Trelease_0_8_1 +/m68k-dis.c/1.1/Sun Nov 6 16:52:11 2005//Trelease_0_8_1 +/m68k.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/mips-dis.c/1.3/Thu May 25 18:22:28 2006//Trelease_0_8_1 +/monitor.c/1.48/Thu May 25 18:22:28 2006//Trelease_0_8_1 +/osdep.c/1.10/Wed May 24 10:40:10 2006//Trelease_0_8_1 +/osdep.h/1.5/Wed May 24 10:40:10 2006//Trelease_0_8_1 +/ppc-dis.c/1.7/Thu May 25 12:38:51 2006//Trelease_0_8_1 +/ppc.ld/1.2/Thu May 25 12:38:51 2006//Trelease_0_8_1 +/qemu-binfmt-conf.sh/1.4/Thu May 25 18:22:28 2006//Trelease_0_8_1 +/qemu-doc.texi/1.87/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/qemu-img.c/1.8/Thu May 25 12:38:51 2006//Trelease_0_8_1 +/qemu-img.texi/1.2/Thu May 25 12:38:51 2006//Trelease_0_8_1 +/qemu-tech.texi/1.9/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/qemu_socket.h/1.1/Sun Apr 30 22:53:25 2006//Trelease_0_8_1 +/readline.c/1.1/Tue May 23 19:16:56 2006//Trelease_0_8_1 +/s390.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/sdl.c/1.26/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/sdl_keysym.h/1.3/Tue Mar 1 21:43:41 2005//Trelease_0_8_1 +/sh4-dis.c/1.1/Thu Apr 27 21:05:14 2006//Trelease_0_8_1 +/softmmu_exec.h/1.1/Sun Oct 30 18:16:26 2005//Trelease_0_8_1 +/softmmu_header.h/1.13/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/softmmu_template.h/1.16/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/sparc-dis.c/1.2/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/sparc.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/tap-win32.c/1.2/Sun Feb 19 12:40:00 2006//Trelease_0_8_1 +/texi2pod.pl/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/thunk.c/1.6/Wed May 24 10:40:10 2006//Trelease_0_8_1 +/thunk.h/1.13/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/translate-all.c/1.14/Thu May 25 18:22:29 2006//Trelease_0_8_1 +/translate-op.c/1.1/Sun Mar 13 16:53:06 2005//Trelease_0_8_1 +/usb-linux.c/1.4/Sat Mar 11 18:03:38 2006//Trelease_0_8_1 +/vgafont.h/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/vl.c/1.184/Thu May 25 18:22:30 2006//Trelease_0_8_1 +/vl.h/1.116/Thu May 25 18:22:30 2006//Trelease_0_8_1 +/vnc.c/1.4/Mon May 1 21:44:22 2006//Trelease_0_8_1 +/vnc_keysym.h/1.1/Sun Apr 30 21:28:36 2006//Trelease_0_8_1 +/vnchextile.h/1.1/Sun Apr 30 21:28:36 2006//Trelease_0_8_1 +/x86_64.ld/1.1/Thu Jan 6 20:50:00 2005//Trelease_0_8_1 +D/target-sh4//// diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/audio/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/audio/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,19 @@ +/alsaaudio.c/1.5/Sun Nov 20 18:53:05 2005//Trelease_0_8_1 +/audio.c/1.9/Thu May 25 18:22:31 2006//Trelease_0_8_1 +/audio.h/1.5/Thu May 25 18:22:31 2006//Trelease_0_8_1 +/audio_int.h/1.7/Thu May 25 18:22:31 2006//Trelease_0_8_1 +/audio_template.h/1.4/Sun Nov 20 16:24:34 2005//Trelease_0_8_1 +/coreaudio.c/1.5/Sun Nov 20 18:53:42 2005//Trelease_0_8_1 +/dsound_template.h/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1 +/dsoundaudio.c/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1 +/fmodaudio.c/1.5/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/mixeng.c/1.4/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/mixeng.h/1.2/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/mixeng_template.h/1.2/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/noaudio.c/1.4/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/ossaudio.c/1.9/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/rate_template.h/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1 +/sdlaudio.c/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/sys-queue.h/1.1/Sun Oct 30 18:58:22 2005//Trelease_0_8_1 +/wavaudio.c/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/audio/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/audio/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/audio diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/audio/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/audio/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/audio/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/audio/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/fpu/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/fpu/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,7 @@ +/softfloat-macros.h/1.1/Sun Mar 13 16:54:06 2005//Trelease_0_8_1 +/softfloat-native.c/1.3/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/softfloat-native.h/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/softfloat-specialize.h/1.1/Sun Mar 13 16:54:06 2005//Trelease_0_8_1 +/softfloat.c/1.2/Sun Mar 13 18:52:28 2005//Trelease_0_8_1 +/softfloat.h/1.3/Thu May 25 18:22:32 2006//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/fpu/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/fpu/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/fpu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/fpu/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/fpu/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/fpu/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/fpu/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/hw/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,72 @@ +/adb.c/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/adlib.c/1.5/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/apic.c/1.8/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/arm_boot.c/1.1/Thu Apr 27 23:15:07 2006//Trelease_0_8_1 +/arm_pic.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/arm_pic.h/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/arm_timer.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/cirrus_vga.c/1.21/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/cirrus_vga_rop.h/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/cirrus_vga_rop2.h/1.7/Thu May 25 12:52:49 2006//Trelease_0_8_1 +/cuda.c/1.10/Thu May 25 12:38:51 2006//Trelease_0_8_1 +/dma.c/1.14/Thu May 25 18:22:32 2006//Trelease_0_8_1 +/es1370.c/1.4/Sun Nov 20 16:20:39 2005//Trelease_0_8_1 +/esp.c/1.6/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/fdc.c/1.18/Wed May 24 10:40:13 2006//Trelease_0_8_1 +/fmopl.c/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/fmopl.h/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/heathrow_pic.c/1.2/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/i8254.c/1.8/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/i8259.c/1.18/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/ide.c/1.42/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/integratorcp.c/1.9/Thu Apr 27 23:15:07 2006//Trelease_0_8_1 +/iommu.c/1.6/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/lance.c/1.7/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/m48t59.c/1.7/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/m48t59.h/1.5/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/mc146818rtc.c/1.6/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/mips_r4k.c/1.16/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/ne2000.c/1.19/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/openpic.c/1.9/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/parallel.c/1.4/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/pc.c/1.53/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/pci.c/1.24/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/pckbd.c/1.15/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/pcspk.c/1.1/Mon Apr 24 21:58:30 2006//Trelease_0_8_1 +/pl011.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/pl050.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/pl080.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/pl110.c/1.6/Tue Apr 18 19:02:59 2006//Trelease_0_8_1 +/pl110_template.h/1.2/Sun Feb 19 12:31:32 2006//Trelease_0_8_1 +/pl190.c/1.1/Sun Apr 9 01:32:52 2006//Trelease_0_8_1 +/ppc.c/1.9/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/ppc_chrp.c/1.21/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/ppc_prep.c/1.26/Thu May 25 18:22:33 2006//Trelease_0_8_1 +/ps2.c/1.4/Wed Apr 12 21:09:07 2006//Trelease_0_8_1 +/rtl8139.c/1.1/Sun Feb 5 04:14:41 2006//Trelease_0_8_1 +/sb16.c/1.19/Thu May 25 18:22:34 2006//Trelease_0_8_1 +/serial.c/1.12/Thu May 25 18:22:34 2006//Trelease_0_8_1 +/sh7750.c/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/sh7750_regnames.c/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/sh7750_regnames.h/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/sh7750_regs.h/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/shix.c/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/slavio_intctl.c/1.6/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/slavio_misc.c/1.3/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/slavio_serial.c/1.6/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/slavio_timer.c/1.3/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/smc91c111.c/1.3/Sat Feb 4 22:15:28 2006//Trelease_0_8_1 +/sun4m.c/1.16/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/sun4u.c/1.8/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/tc58128.c/1.1/Thu Apr 27 21:32:09 2006//Trelease_0_8_1 +/tcx.c/1.7/Thu May 25 18:22:35 2006//Trelease_0_8_1 +/usb-hid.c/1.2/Wed Apr 12 21:09:07 2006//Trelease_0_8_1 +/usb-hub.c/1.3/Sun Apr 30 21:53:59 2006//Trelease_0_8_1 +/usb-uhci.c/1.8/Tue Apr 25 21:01:19 2006//Trelease_0_8_1 +/usb.c/1.6/Mon Apr 24 21:18:20 2006//Trelease_0_8_1 +/usb.h/1.4/Wed Apr 12 21:09:07 2006//Trelease_0_8_1 +/versatilepb.c/1.2/Thu Apr 27 23:15:07 2006//Trelease_0_8_1 +/vga.c/1.42/Thu May 25 18:22:36 2006//Trelease_0_8_1 +/vga_int.h/1.6/Thu May 25 18:20:53 2006//Trelease_0_8_1 +/vga_template.h/1.11/Wed May 17 14:47:01 2006//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/hw/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/hw diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/hw/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/hw/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/keymaps/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/keymaps/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,36 @@ +/ar/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/common/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/da/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/de/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/de-ch/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/en-gb/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/en-us/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/es/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/et/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fi/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fo/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fr/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fr-be/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fr-ca/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/fr-ch/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/hr/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/hu/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/is/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/it/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/ja/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/lt/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/lv/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/mk/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/modifiers/1.2/Tue Mar 1 21:43:42 2005//Trelease_0_8_1 +/nl/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/nl-be/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/no/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/pl/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/pt/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/pt-br/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/ru/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/sl/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/sv/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/th/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +/tr/1.1/Sun Dec 12 16:56:30 2004//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/keymaps/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/keymaps/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/keymaps diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/keymaps/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/keymaps/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/keymaps/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/keymaps/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/pc-bios/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/pc-bios/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,15 @@ +/Makefile/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/README/1.7/Thu May 25 12:38:52 2006//Trelease_0_8_1 +/bios.bin/1.13/Thu May 25 18:22:37 2006/-kb/Trelease_0_8_1 +/bios.diff/1.11/Thu May 25 18:22:37 2006//Trelease_0_8_1 +/linux_boot.S/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1 +/linux_boot.bin/1.1/Wed May 17 14:47:01 2006/-kb/Trelease_0_8_1 +/ohw.diff/1.2/Thu Jul 7 22:38:00 2005//Trelease_0_8_1 +/ppc_rom.bin/1.6/Thu May 25 12:39:00 2006/-kb/Trelease_0_8_1 +/proll.elf/1.5/Thu May 25 18:22:38 2006/-kb/Trelease_0_8_1 +/proll.patch/1.6/Thu May 25 18:22:38 2006//Trelease_0_8_1 +/vgabios-cirrus.bin/1.6/Thu May 25 18:22:38 2006/-kb/Trelease_0_8_1 +/vgabios.bin/1.5/Thu May 25 18:22:39 2006/-kb/Trelease_0_8_1 +/vgabios.diff/1.2/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/video.x/1.1/Sun Jul 3 14:00:51 2005/-kb/Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/pc-bios/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/pc-bios/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/pc-bios diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/pc-bios/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/pc-bios/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/pc-bios/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/pc-bios/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/target-i386/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/target-i386/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,13 @@ +/cpu.h/1.36/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/exec.h/1.29/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/helper.c/1.65/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/helper2.c/1.41/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/op.c/1.44/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/opreg_template.h/1.3/Wed May 24 10:40:25 2006//Trelease_0_8_1 +/ops_mem.h/1.7/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/ops_sse.h/1.6/Tue Apr 26 20:38:17 2005//Trelease_0_8_1 +/ops_template.h/1.10/Wed May 24 10:40:25 2006//Trelease_0_8_1 +/ops_template_mem.h/1.6/Thu May 25 18:22:39 2006//Trelease_0_8_1 +/translate-copy.c/1.7/Wed May 24 10:40:25 2006//Trelease_0_8_1 +/translate.c/1.56/Thu May 25 18:22:39 2006//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/target-i386/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/target-i386/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/target-i386 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/target-i386/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/target-i386/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/target-i386/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/target-i386/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/tests/.CVS/Entries --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/tests/.CVS/Entries Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,18 @@ +/.cvsignore/1.4/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/Makefile/1.36/Thu May 25 18:22:40 2006//Trelease_0_8_1 +/hello-arm.c/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/hello-i386.c/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/linux-test.c/1.3/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/pi_10.com/1.1/Wed May 17 14:47:02 2006/-kb/Trelease_0_8_1 +/qruncom.c/1.4/Thu May 25 18:22:41 2006//Trelease_0_8_1 +/runcom.c/1.3/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/sha1.c/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/test-i386-code16.S/1.3/Wed May 24 10:40:26 2006//Trelease_0_8_1 +/test-i386-muldiv.h/1.2/Wed May 24 10:40:26 2006//Trelease_0_8_1 +/test-i386-shift.h/1.5/Thu May 25 18:22:41 2006//Trelease_0_8_1 +/test-i386-vm86.S/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/test-i386.c/1.49/Wed May 24 10:40:26 2006//Trelease_0_8_1 +/test-i386.h/1.2/Wed May 24 10:40:26 2006//Trelease_0_8_1 +/test_path.c/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1 +/testthread.c/1.2/Wed May 17 14:47:02 2006//Trelease_0_8_1 +D diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/tests/.CVS/Repository --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/tests/.CVS/Repository Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +qemu/tests diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/tests/.CVS/Root --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/tests/.CVS/Root Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu diff -r 4acc6d51f389 -r b76e86966e7e tools/ioemu/tests/.CVS/Tag --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/tests/.CVS/Tag Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1 @@ +Nrelease_0_8_1 diff -r 4acc6d51f389 -r b76e86966e7e tools/security/xensec_ezpolicy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/security/xensec_ezpolicy Wed Aug 02 13:39:47 2006 -0600 @@ -0,0 +1,1628 @@ +#!/usr/bin/env python +#=========================================================================== +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Reiner Sailer +#============================================================================ +# use 'yum install wxPython' to get wx or download from www.wxpython.org +import sys, time, string +import wx +import wx.lib.buttons as buttons +""" +This program creates a default policy based on names of organizations and departments. +The resulting policy can be refined using the policy generation tool (xensec_gen). +""" + +helpprovider = wx.SimpleHelpProvider() +wx.HelpProvider_Set(helpprovider) + +ID_CS_START=1000 + +realm_bmp = None +workload_bmp = None +conflict_bmp = None +realm_icon = None +workload_icon = None + +class orgTreeCtrl(wx.TreeCtrl): + + event = None + + def __init__(self, parent, id, pos, size, style, validator, name): + wx.TreeCtrl.__init__(self, parent, id, pos, size, style, + validator, name) + self.parent = parent + orgs_root = self.AddRoot(text="Organization / Department") + rootfont = wx.Font(pointSize=12, family=wx.FONTFAMILY_DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_LIGHT) + self.SetItemFont(orgs_root, rootfont) + self.SetItemBackgroundColour(orgs_root, wx.LIGHT_GREY) + + + def LabelExists(self, label, item): + for i in iterchildren(self.GetItemParent(item)): + if (self.GetItemText(i) == label) and (i != item): + return True + return False + + + def _OrgEdt(self, event): + item = self.event.GetItem() + self.OrgEdt(item) + + + def OrgEdt(self, item): + oldlabel= self.GetItemText(item) + #get new name + dlg = wx.TextEntryDialog(self, "Please enter org/dept name:", + "Naming a Workload", + style=wx.CANCEL | wx.OK | wx.CENTRE | wx.TE_NOHIDESEL) + dlg.SetValue(oldlabel) + ret = dlg.ShowModal() + newlabel = dlg.GetValue() + dlg.Destroy() + if (ret == wx.ID_CANCEL) or (newlabel == ''): + return False + + #now check if the new name is permissible + if self.LabelExists(newlabel, item): + dlg = wx.MessageDialog(self, 'Item with name ' + newlabel + ' already exists!', + 'Rename', style=wx.OK) + dlg.ShowModal() + dlg.Destroy() + return False + + #all checkspassed, change item and adapt runtime exclusion rules + self.SetItemText(item, newlabel) + app.win.LabelReplaceInConflictsets(item, oldlabel, newlabel) + return True + + + def _OrgRAdd(self, event): + self.OrgRAdd() + + + def OrgRAdd(self): + new = self.AppendItem(self.GetRootItem(), text="") + self.SetItemBold(new, True) + self.SetItemImage(new, realm_icon, wx.TreeItemIcon_Normal) + self.EnsureVisible(new) + if not self.OrgEdt(new): + self.Delete(new) + + + def _OrgWAdd(self, event): + item = self.event.GetItem() + self.OrgWAdd(item) + + + def OrgWAdd(self, item): + new = self.AppendItem(item, text="") + self.Expand(item) + self.SetItemImage(new, workload_icon, wx.TreeItemIcon_Normal) + self.EnsureVisible(new) + if not self.OrgEdt(new): + self.Delete(new) + + +class OrgsPanel(wx.Panel): + ID_CONSADDBTN = 145 + ID_REALMADDBTN = 144 + + def __init__(self, parent, ID): + global realm_icon, workload_icon + + wx.Panel.__init__(self, parent, -1) + + #create image list + imagelist = wx.ImageList(16, 17, True) + #define generic function and use it for all input + realm_icon = imagelist.Add(realm_bmp) + workload_icon = imagelist.Add(workload_bmp) + + #left tree control for organizations / workload definitions + orgshdrbox = wx.StaticBox(self, -1, "") + orgshdrboxsizer = wx.StaticBoxSizer(orgshdrbox, wx.HORIZONTAL) + orgshdr = wx.StaticText(self, -1, "Organization / Department Definition", + style=wx.ALIGN_CENTER) + orgshdr.SetHelpText(RealmWorkloadPanelHelp) + points = orgshdr.GetFont().GetPointSize() # get the current size + hdrfont = wx.Font(points + 2, family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD) + orgshdr.SetFont(hdrfont) + orgshdr.SetForegroundColour('MEDIUMBLUE') + orgshdr.SetBackgroundColour('SNOW') + orgshdrboxsizer.Add(orgshdr, proportion=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_LEFT, border=5) + addorgsbutton = wx.Button(self, self.ID_REALMADDBTN, "New Org", style=wx.BU_EXACTFIT) + addorgsbutton.SetToolTipString("Add A New Organization") + addorgsbutton.SetHelpText(NewRealmButtonHelp) + addorgsbutton.SetForegroundColour('MEDIUMBLUE') + addfont = wx.Font(points, family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD) + addorgsbutton.SetFont(addfont) + orgshdrboxsizer.Add(addorgsbutton, proportion=0, flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border=0) + + self.orgs = orgTreeCtrl(self, -1, + pos=wx.DefaultPosition, + size=wx.DefaultSize, + style=wx.TR_HAS_BUTTONS | wx.TR_HIDE_ROOT | wx.TR_NO_LINES + | wx.TR_MULTIPLE, + validator=wx.DefaultValidator, + name="orgs") + self.orgs.AssignImageList(imagelist) + self.orgs.SetHelpText(RealmWorkloadPanelHelp) + + self.addconsbutton = wx.Button(self, self.ID_CONSADDBTN, + "Create run-time exclusion rule from selection -->", + style=wx.BU_EXACTFIT) + self.addconsbutton.SetToolTipString("Create New Exclusion rule From Above Workload Selection") + self.addconsbutton.SetHelpText(CreateRunTimeButtonHelp) + self.addconsbutton.SetForegroundColour('MEDIUMBLUE') + addfont = wx.Font(points, family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD) + self.addconsbutton.SetFont(addfont) + self.addconsbutton.Bind(wx.EVT_BUTTON, self._AddConflict, id=self.ID_CONSADDBTN) + + orgsvbox = wx.BoxSizer(wx.VERTICAL) + orgsvbox.Add(orgshdrboxsizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) + orgsvbox.Add(self.orgs, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) + orgsvbox.Add(self.addconsbutton, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) + self.SetSizer(orgsvbox) + addorgsbutton.Bind(wx.EVT_BUTTON, self.orgs._OrgRAdd, id= self.ID_REALMADDBTN) + + + def _AddConflict(self, event): + app.win.conspanel._AddNewConflict(event) + + +class ConsPanel(wx.Panel): + ID_CONSSELECT = 151 + ID_CONSADD = 152 + ID_CONSRENAME = 153 + ID_CONSDEL = 154 + ID_CONSSELECTSUB= 155 + + conflictMAX = ID_CS_START + + def __init__(self, parent, ID): + self.conflictsets = [] + self.parent = parent + wx.Panel.__init__(self, parent, -1) + #header + conshdrbox = wx.StaticBox(self, -1, "") + conshdrboxsizer = wx.StaticBoxSizer(conshdrbox, wx.HORIZONTAL) + conshdr = wx.StaticText(self, -1, "Run-time Exclusion Rules", style=wx.ALIGN_CENTER) + conshdr.SetHelpText(RunTimeExclusionPanelHelp) + points = conshdr.GetFont().GetPointSize() # get the current size + hdrfont = wx.Font(points + 2, family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD) + conshdr.SetFont(hdrfont) + conshdr.SetForegroundColour('ORANGERED') + + #context help button + ctxHelp = wx.ContextHelpButton(self) + ctxHelp.SetHelpText("Context Help Button.") + ctxHelp.SetToolTipString("Context Help: Press this button, then press any other button or panel to get help.") + + + conshdrboxsizer.Add(conshdr, proportion=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_LEFT, border=5) + conshdrboxsizer.Add(ctxHelp, proportion=0, flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border=0) + #scrolledwindow for all the run-time exclusion rules + conflictspanel = wx.ScrolledWindow(self, -1, (0,0), + style = wx.FULL_REPAINT_ON_RESIZE | + wx.VSCROLL ) + conflictspanel.SetVirtualSize((1000, 1000)) + conflictspanel.SetScrollRate(5,5) + self.conflictsboxsizer = wx.BoxSizer(wx.VERTICAL) + + #self.conflictsboxsizer.Fit(self) + conflictspanel.SetSizer(self.conflictsboxsizer) + consvbox = wx.BoxSizer(wx.VERTICAL) + consvbox.Add(conshdrboxsizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) + consvbox.Add(conflictspanel, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) + self.SetSizer(consvbox) + self.consvbox = consvbox + self.conflictspanel=conflictspanel + + self.cmenu = wx.Menu() + self.cmenu.Append(self.ID_CONSRENAME, "Rename Run-time Exclusion Rule", "Rename Run-time Exclusion Rule") + self.cmenu.AppendSeparator() + self.cmenu.Append(self.ID_CONSDEL, "Delete Run-time Exclusion Rule", "Delete Run-time Exclusion Rule") + self.Bind(wx.EVT_MENU, self._CSRename, id=self.ID_CONSRENAME) + self.Bind(wx.EVT_MENU, self._CSDelete, id=self.ID_CONSDEL) + + + #Helper methods called from anywhere + def New(self): + #delete all run-time exclusion rules + for i in self.conflictsets: + i.Disable() + i.Destroy() + self.conflictsets = [] + self.conflictsboxsizer.Layout() + size=self.GetSize() + self.Fit() + self.SetSize(size) + + + def DelCSById(self, delid): + #delete CS representation + delpos, item = self.GetCSBox(delid) + if item: + self.DelCSByItem(item) + + + def DelCSByItem(self, item): + #delete CS representation + self.conflictsets.remove(item) + exists = self.conflictsboxsizer.Detach(item) + if exists: + item.Destroy() + self.RefreshMe() + + + def RefreshMe(self): + size=self.parent.GetSize() + self.parent.Fit() + self.parent.SetSize(size) + + + def GetOrgSelection(self): + (tree, selection) = GetOrgsSelection() + if not len(selection): + dlg = wx.MessageDialog(self, 'You must select first at least one Organization/Department workload!', + 'Creating A New Run-time Rule', wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return None,None + # now rewrite selection (realm.workload extension, check consistency) + alist = [] + for i in selection: + if isRealm(i): + alist.append(tree.GetItemText(i)) + else: + alist.append(tree.GetItemText(tree.GetItemParent(i)) + + "." + tree.GetItemText(i)) + + if isRealm(i): + for j in selection: + if tree.GetItemParent(j) == i: + violation = ("[ " + tree.GetItemText(i) + ", " + + tree.GetItemText(i) + "." + tree.GetItemText(j) + " ]") + dlg = wx.MessageDialog(self, + 'Invalid Selection ' + violation + '.\n\n' + + 'You can only select EITHER an Organization OR specific Department!', + 'Creating A New Run-time Exclusion Rule', wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return None,None + return (alist, selection) + + + def AddConflict(self, name, types): + csbox = myCSPanel(self, self.conflictMAX, name, types) + self.conflictsboxsizer.Add(csbox, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) + self.conflictsets.append(csbox) + self.conflictMAX = self.conflictMAX+3 + self.RefreshMe() + csbox.RefreshMe() + + + def GetCSBox(self, id): + pos = -1 + i = 0 + while self.conflictsboxsizer.GetItem(i): + item = self.conflictsboxsizer.GetItem(i).GetWindow() + if ((item.cbmp.GetId() == id) or + (item.add_selection.GetId() == id) or + (item.del_selection.GetId() == id)): + pos = i + box = item + break + i = i + 1 + if pos < 0: + print "Run-time Exclusion Rule Not Found ERROR!" + return (None, None) + else: + return (pos, box) + + + #bind methods + def _AddNewConflict(self, event): + # first get the conflicting workload types with current selection + types, items = self.GetOrgSelection() + if not types: + return + #get name for conflict set + dlg = wx.TextEntryDialog( + self, 'Please enter a name for the Run-time Exclusion Rule:', 'Creating A New Run-time Exclusion Rule') + dlg.SetValue("") + ret = dlg.ShowModal() + name = dlg.GetValue() + dlg.Destroy() + if ret != wx.ID_OK: + return + self.AddConflict(name, types) + + + def _OnClick(self, event): + self.event = event + app.win.SetStatusText("") + self.PopupMenu(self.cmenu) + + + def _CSRename(self, event): + delpos, item = self.GetCSBox(self.event.GetId()) + if not item: + return + #allow to name the conflict set + dlg = wx.TextEntryDialog( + self, 'Please enter a new name for the Conflict Set:', 'Renaming A Run-time Exclusion Rule') + dlg.SetValue(item.box.GetLabel()) + ret = dlg.ShowModal() + name = dlg.GetValue() + dlg.Destroy() + if ret != wx.ID_OK: + return + item.box.SetLabel(name) + item.box.SetFont(wx.Font(item.GetFont().GetPointSize(), family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD)) + + + def _CSDelete(self, event): + delid = self.event.GetId() + self.DelCSById(delid) + + + def _AddOrgSelection(self, event): + addid = event.GetId() + addpos, item = self.GetCSBox(addid) + alist, items = self.GetOrgSelection() + if not alist: + return + existing = [] + for i in range(0, item.clb.GetCount()): + existing.append(item.clb.GetString(i)) + + #now make sure that we don't get realm + workload into the same CS + for i in items: + if isRealm(i): + #ensure no workload of this realm is already in CS + realm = app.win.orgs.GetItemText(i) + for j in iterchildren(i): + workload = app.win.orgs.GetItemText(j) + try: + idx = existing.index (realm + "." + workload) + except: + #ok, does not exist + continue + #nok, exists already + violation = ("[ " + realm + ", " + + realm + "." + workload + " ]") + dlg = wx.MessageDialog(self, + 'Invalid Selection ' + violation + '.\n\n' + + 'You can only have EITHER an Organization OR a specific Department workload\n' + + 'in a single Run-time Exclusion Rule', + 'Adding Orgs/Depts workloads to a Run-time Exclusion Rule', + wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return + + else: + #ensure realm of this workload is not in CS + realm = app.win.orgs.GetItemText(app.win.orgs.GetItemParent(i)) + try: + idx = existing.index(realm) + except: + #ok, does not exist + continue + #nok, exists already + violation = ("[ " + realm + "." + app.win.orgs.GetItemText(i) + + ", " + realm + " ]") + dlg = wx.MessageDialog(self, + 'Invalid Selection ' + violation + '.\n\n' + + 'You can only have EITHER an Organization OR a specific Department workload\n' + + 'in a single Run-time Exclusion Rule', + 'Adding Orgs/Depts workloads to a Run-time Exclusion Rule', + wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return + #check if any of the selections are already in the conflict set + overlap=[] + for l in alist: + for e in existing: + if l == e: + overlap.append(str(l)) + if len(overlap): + if len(overlap) == 1: + message = "Selected item " + str(overlap) +\ + " is already in the Run-time Exclusion rule and will be ignored.\n\n Continue?" + else: + message = "Selected items " + str(overlap) +\ + " are already in the Run-time Exclusion rule and will be ignored.\n\n Continue?" + dlg = wx.MessageDialog(self, + message, 'Adding Orgs/Depts workloads to a Run-time Exclusion rule', + wx.YES | wx.NO | wx.ICON_EXCLAMATION) + ret = dlg.ShowModal() + dlg.Destroy() + if ret != wx.ID_YES: + return + + for s in alist: + try: + existing.index(s) + except Exception: + # s not yet in list box, add it + item.AddTypes([s]) + self.RefreshMe() + + + def _DelConSelection(self, event): + eventid = event.GetId() + pos, item = self.GetCSBox(eventid) + idtuple = item.clb.GetSelections() + idlist = [] + for i in idtuple: + idlist.append(i) + #delete reverse, otherwise item mubers get messed up while deleting + idlist.reverse() + for i in idlist: + item.clb.Delete(i) + item.RefreshMe() + if item.clb.GetCount() < 2: + dlg = wx.MessageDialog(self, + """Run-time exclusion set has less than two types.\n\n + Do you want to delete this rule?""", + 'Deleting Orgs/Depts workloads from a Run-time Exclusion rule', + wx.YES| wx.NO | wx.ICON_QUESTION) + ret = dlg.ShowModal() + dlg.Destroy() + if ret == wx.ID_YES: + self.DelCSById(eventid) + return + else: + for i in item.clb.GetSelections(): + item.clb.Deselect(i) + self.RefreshMe() + + +class myCSPanel(wx.Panel): + def __init__(self, parent, ID, title, list=[]): + wx.Panel.__init__(self, parent.conflictspanel, -1) + self.parent = parent + cspansizer = wx.BoxSizer(wx.VERTICAL) + self.box = wx.StaticBox(self, -1, title) + csboxsizer = wx.StaticBoxSizer(self.box, wx.HORIZONTAL) + #left: type add/del + typesizer = wx.BoxSizer(wx.VERTICAL) + self.add_selection = wx.Button(self, ID+1, "--> Add", style=wx.BU_EXACTFIT) + self.add_selection.SetToolTipString("Add Workload Selection To Run-time Exclusion rule") + self.add_selection.SetHelpText(AddToExclusionButtonHelp) + self.add_selection.SetForegroundColour('MEDIUMBLUE') + points = self.add_selection.GetFont().GetPointSize() + addfont = wx.Font(points, family=wx.DEFAULT, + style=wx.FONTSTYLE_NORMAL, weight=wx.BOLD) + self.add_selection.SetFont(addfont) + self.box.SetFont(addfont) + typesizer.Add(self.add_selection, proportion = 0, flag = wx.EXPAND | wx.ALL,border=0) + typesizer.Add((5,5)) + self.del_selection = wx.Button(self, ID+2, "<-- Del", style=wx.BU_EXACTFIT) + self.del_selection.SetToolTipString("Delete Workload Selection From Run-time Exclusion Rule") + self.del_selection.SetHelpText(DelFromExclusionButtonHelp) + self.del_selection.SetForegroundColour('ORANGERED') + self.del_selection.SetFont(addfont) + typesizer.Add(self.del_selection, proportion = 0, flag = wx.EXPAND | wx.ALL, border=0) + csboxsizer.Add(typesizer, proportion = 0, border=0) + csboxsizer.Add((5,5)) + #middle: types + self.clb = wx.ListBox(self, id=-1, choices=list, + style= wx.LB_MULTIPLE | wx.LB_SORT ) + self.clb.SetHelpText(ExclusionSetHelp) + csboxsizer.Add(self.clb, proportion=1, flag=wx.EXPAND | wx.ALL, border=0) + csboxsizer.Add((5,5)) + #right: Conflictset-global ops button + bmpsizer = wx.BoxSizer(wx.VERTICAL) + self.cbmp = buttons.GenBitmapButton(self, ID, conflict_bmp, style=wx.BU_EXACTFIT) + self.cbmp.SetHelpText(ManageExclusionButtonHelp) + self.cbmp.SetToolTipString("Rename/Delete\nAssociated Run-time Exclusion Rule") + bmpsizer.Add(self.cbmp, proportion = 0, flag = wx.EXPAND | wx.ALL, border=0) + csboxsizer.Add(bmpsizer, proportion=0, border=5) + cspansizer.Add(csboxsizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=0) + self.csboxsizer=csboxsizer + self.cspansizer=cspansizer + self.SetSizer(cspansizer) + self.cbmp.Bind(wx.EVT_LEFT_DOWN, parent._OnClick, id=ID) + self.add_selection.Bind(wx.EVT_BUTTON, parent._AddOrgSelection, id=ID + 1) + self.del_selection.Bind(wx.EVT_BUTTON, parent._DelConSelection, id=ID + 2) + + # append and delete an item to get rid of + # the ugly vertical scroll bar on the Listbox on Linux + def RefreshMe(self): + x = self.clb.Append(" ") + app.win.conspanel.RefreshMe() + self.clb.Delete(x) + self.Layout() + app.win.conspanel.Layout() + + + def AddTypes(self, list): + for i in list: + self.clb.Append(i) + self.RefreshMe() + + + def GetTypes(self): + alist = [] + for i in range(0, self.clb.GetCount()): + alist.append(self.clb.GetString(i)) + return alist + + + def GetBoxName(self): + return self.box.GetLabel() + + + def Replace(self, oldlabel, newlabel): + index = self.clb.FindString(oldlabel) + if index != wx.NOT_FOUND: + self.clb.SetString(index, newlabel) + + + def Delete(self, label): + index = self.clb.FindString(label) + if index != wx.NOT_FOUND: + self.clb.Delete(index) + + +class myHelpPanel(wx.Panel): + def __init__(self, parent, ID): + wx.Panel.__init__(self, parent, -1) + + +class ezFrame(wx.Frame): + + ID_ABOUT = 101 + ID_NEW = 102 + ID_OPEN = 103 + ID_SAVE = 104 + ID_SAVEAS = 105 + ID_EXIT = 106 + ID_HELP = 107 + + ID_ITRENAME = 111 + ID_ITADD = 112 + ID_ITDEL = 113 + + ID_COLLAPSEALL = 121 + ID_EXPANDALL = 122 + ID_SORTALL = 123 + + ID_TRANSLATE = 131 + + ID_ORGEDT = 141 + ID_ORGADD = 142 + ID_ORGDEL = 143 + + def __init__(self, parent, ID, title): + global realm_bmp, workload_bmp, conflict_bmp + + wx.Frame.__init__(self, parent, ID, title, + wx.DefaultPosition, + wx.Size(700,450) + ) + + realm_bmp = GetIconBitmap('Organization') + workload_bmp = GetIconBitmap('Department') + conflict_bmp = GetIconBitmap('Conflict') + self.SetHelpText(GetHelp) + self.orgfilename = None + self.CreateStatusBar() + self.SetStatusText("") + self.bkg = wx.Panel(self) + + self.orgswin = wx.SashLayoutWindow( + self.bkg, -1, wx.DefaultPosition, (300, 150),wx.SW_3DSASH | wx.SW_BORDER) + + self.orgswin.SetDefaultSize((300,150)) + self.orgswin.SetOrientation(wx.LAYOUT_VERTICAL) + self.orgswin.SetAlignment(wx.LAYOUT_LEFT) + self.orgspanel = OrgsPanel(self.orgswin, -1) + self.orgs = self.orgspanel.orgs + + self.realm_menu = wx.Menu() + self.realm_menu.Append(self.ID_ORGADD, "Add Department\tctrl-a", "Add Department Workload") + self.realm_menu.AppendSeparator() + self.realm_menu.AppendSeparator() _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |