Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel' of ssh://palacios@newskysaw.cs.northwestern.edu/home/palacios...
Jack Lange [Tue, 2 Feb 2010 00:20:52 +0000 (18:20 -0600)]
92 files changed:
Kconfig
bios/rombios/BIOS-bochs-latest
manual/guest_build/Palacios_Guest_Build.tex
manual/manual.pdf
manual/manual.tex
palacios/include/devices/icc_bus.h [new file with mode: 0644]
palacios/include/devices/pci.h
palacios/include/palacios/svm_io.h
palacios/include/palacios/svm_msr.h
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_config.h
palacios/include/palacios/vmm_cpuid.h
palacios/include/palacios/vmm_ctrl_regs.h
palacios/include/palacios/vmm_dev_mgr.h
palacios/include/palacios/vmm_emulator.h
palacios/include/palacios/vmm_host_events.h
palacios/include/palacios/vmm_hypercall.h
palacios/include/palacios/vmm_intr.h
palacios/include/palacios/vmm_io.h
palacios/include/palacios/vmm_lowlevel.h
palacios/include/palacios/vmm_mem.h
palacios/include/palacios/vmm_msr.h
palacios/include/palacios/vmm_sym_iface.h
palacios/include/palacios/vmm_sym_swap.h
palacios/include/palacios/vmm_telemetry.h
palacios/include/palacios/vmm_time.h
palacios/include/palacios/vmx_io.h
palacios/include/palacios/vmx_lowlevel.h
palacios/include/palacios/vmx_msr.h
palacios/src/devices/8254.c
palacios/src/devices/8259a.c
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/apic.c
palacios/src/devices/atapi.h
palacios/src/devices/bochs_debug.c
palacios/src/devices/disk_model.c
palacios/src/devices/generic.c
palacios/src/devices/i440fx.c
palacios/src/devices/icc_bus.c [new file with mode: 0644]
palacios/src/devices/ide.c
palacios/src/devices/io_apic.c
palacios/src/devices/keyboard.c
palacios/src/devices/lnx_virtio_balloon.c
palacios/src/devices/lnx_virtio_blk.c
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/lnx_virtio_sym.c
palacios/src/devices/nvram.c
palacios/src/devices/os_debug.c
palacios/src/devices/pci.c
palacios/src/devices/pci_passthrough.c
palacios/src/devices/piix3.c
palacios/src/devices/ramdisk.c
palacios/src/devices/sym_swap2.c
palacios/src/devices/tmpdisk.c
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/svm_io.c
palacios/src/palacios/svm_msr.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vm_guest_mem.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_config_class.h
palacios/src/palacios/vmm_cpuid.c
palacios/src/palacios/vmm_ctrl_regs.c
palacios/src/palacios/vmm_dev_mgr.c
palacios/src/palacios/vmm_direct_paging_32.h
palacios/src/palacios/vmm_direct_paging_32pae.h
palacios/src/palacios/vmm_direct_paging_64.h
palacios/src/palacios/vmm_emulator.c
palacios/src/palacios/vmm_halt.c
palacios/src/palacios/vmm_host_events.c
palacios/src/palacios/vmm_hypercall.c
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmm_io.c
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_msr.c
palacios/src/palacios/vmm_shadow_paging.c
palacios/src/palacios/vmm_shadow_paging_32.h
palacios/src/palacios/vmm_shadow_paging_64.h
palacios/src/palacios/vmm_sym_iface.c
palacios/src/palacios/vmm_sym_swap.c
palacios/src/palacios/vmm_telemetry.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmm_xml.c
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_handler.c
palacios/src/palacios/vmx_io.c
palacios/src/palacios/vmx_msr.c
utils/guest_creator/default.xml

diff --git a/Kconfig b/Kconfig
index 4f43d7d..b9a53a2 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -3,6 +3,13 @@ mainmenu "Palacios VMM Configuration"
 menu "Target Configuration"
 
 
+config KITTEN
+       bool "Set defaults needed for the Kitten OS"
+       default y
+       help
+         This enables the necesary options to compile Palacios with Kitten
+
+
 config CRAY_XT
         bool "Red Storm (Cray XT3/XT4)"
         help
@@ -110,7 +117,7 @@ config VNET
 
 config BUILT_IN_STDLIB
        bool "Enable Built in versions of stdlib functions"
-       default n
+       default y if KITTEN
        help 
          Not all host OSes provide link targets for stdlib functions
          Palacios provides internal implementations of these functions, that you can select from this list
@@ -169,7 +176,7 @@ config BUILT_IN_STRCMP
 
 config BUILT_IN_STRCASECMP
        bool "strcasecmp()"
-       default n
+       default y if KITTEN
        depends on BUILT_IN_STDLIB
        help
          This enables Palacios' internal implementation of strcasecmp
@@ -234,7 +241,7 @@ config BUILT_IN_STRSTR
 
 config BUILT_IN_ATOI
        bool "atoi()"
-       default n
+       default y if KITTEN
        depends on BUILT_IN_STDLIB
        help 
          This enables Palacios' internal implementation of atoi
index ea9a1ec..4bbf52a 100644 (file)
Binary files a/bios/rombios/BIOS-bochs-latest and b/bios/rombios/BIOS-bochs-latest differ
index d772496..700f7a5 100644 (file)
@@ -206,67 +206,15 @@ option
 Additionally, if you are using the ``\verb|root_files|" file to create devices
 files, add the ``\verb|root_files|" file path, separated by a space, after the
 initial ramdisk filesystem directory. When you are finished configuring the
-kernel, save your configuration, and type the following:
+kernel, save your configuration, and build a bootable ISO image:
 
 \begin{verbatim}
-[jdoe@newskysaw linux-2.6.30.y]$ make ARCH=i386
+[jdoe@newskysaw linux-2.6.30.y]$ make ARCH=i386 isoimage
 \end{verbatim}
 
 \noindent
-The Linux kernel can be found here: ``\verb|arch/x86/boot/bzImage|". The initial
-ramdisk filesystem can be found here: ``\verb|usr/initramfs_data.cpio|". The
-Linux kernel and initial ramdisk filesystem are used to build the Linux ISO
-image in the section Building the Linux ISO image.
-
-
-\section{Building the Linux ISO image}
-
-The Linux ISO image is a bootable image containing the Linux kernel, initial
-ramdisk filesystem, a boot loader, and a boot loader configuration file. For
-this procedure, we'll use the ``\verb|test/iso/|" directory as the Linux ISO
-build directory:
-
-\begin{verbatim}
-[jdoe@newskysaw test]$ mkdir iso
-\end{verbatim}
-
-\noindent
-Change to the ``\verb|iso/|" directory and copy the required files:
-
-\begin{verbatim}
-[jdoe@newskysaw iso]$ cp ../linux-2.6.30.y/arch/x86/boot/bzImage vmlinuz
-[jdoe@newskysaw iso]$ cp ../linux-2.6.30.y/usr/initramfs_data.cpio initramfs
-[jdoe@newskysaw iso]$ cp /usr/lib/syslinux/isolinux.bin .
-\end{verbatim}
-
-\noindent
-Create a file called ``\verb|isolinux.cfg|" and add the following lines:
-
-\begin{verbatim}
-default linux
-prompt 0
-
-label linux
-  kernel vmlinuz
-  append initrd=initrd
-\end{verbatim}
-
-\noindent
-Change back to the ``\verb|test/|" directory and build the Linux ISO image:
-
-\begin{verbatim}
-[jdoe@newskysaw test]$ mkisofs -o linux.iso -b isolinux.bin -no-emul-boot \
--boot-load-size 4 -boot-info-table -iso-level 2 -input-charset UTF-8 iso/
-\end{verbatim}
-
-\noindent
-The ``\verb|linux.iso|'' file is the Linux ISO image and is used to build the
-guest image in the section Configuring and building the guest image:
-
-\begin{verbatim}
-[jdoe@newskysaw test]$ file linux.iso
-linux.iso: ISO 9660 CD-ROM filesystem data 'CDROM                          ' (bootable)
-\end{verbatim}
+The ISO image can be found here: ``\verb|arch/x86/boot/image.iso|", and will be
+used in the section Configuring and building the guest image.
 
 
 \section{Configuring and building the guest image}
@@ -306,7 +254,7 @@ out this attribute:
 Add an attribute that specifies the location of the Linux ISO image:
 
 \begin{verbatim}
-<file id="boot-cd" filename="../../../linux.iso" />
+<file id="boot-cd" filename="../../../linux-2.6.30.y/arch/x86/boot/image.iso" />
 \end{verbatim}
 
 \noindent
index 0f4132a..80d81c1 100644 (file)
Binary files a/manual/manual.pdf and b/manual/manual.pdf differ
index ab70a55..41f69b8 100755 (executable)
 \includegraphics[height=1.5in]{v3vee.pdf}
 \includegraphics[height=1.5in]{logo6.png} \\
 \vspace{0.5in} 
-Palacios Internal Developer Manual
+Palacios Internal and External Developer Manual
 }
 
 
 \maketitle
 
 
-This manual is written for internal Palacios developers. It contains
-information on how to obtain the Palacios code base, how to go about
-the development process, and how to commit those changes to the
-mainline source tree.  This assumes that the reader has read {\em An
-Introduction to the Palacios Virtual Machine Monitor -- Release 1.0}
-and also has a slight working knowledge of {\em git}.  You will also
-want to read the document {\em Building a bootable guest image for
-Palacios and Kitten} in order to understand how to build an extremely
-lightweight guest environment, suitable for testing.
+This manual is written for internal and external Palacios
+developers. It contains information on how to obtain the Palacios code
+base, how to go about the development process, and how to commit those
+changes to the mainline source tree.  This assumes that the reader has
+read the technical report {\em An Introduction to the Palacios Virtual
+Machine Monitor -- Release 1.0}\footnote{It's important to note that
+there have been substantial changes in the build process from 1.0 to
+1.2 and beyond.  Hence, the technical report is primarily useful as an
+explanation of the theory of operation of Palacios.  This document is
+the one to consult for the build process.}  and also has a slight
+working knowledge of {\em git}.  You will also want to read the
+document {\em Building a bootable guest image for Palacios and Kitten}
+in order to understand how to build an extremely lightweight guest
+environment, suitable for testing.  If you want to configure network 
+booting for testing on real hardware, you'll want to read the document
+{\em Booting Palacios/Kitten Over the Network Using PXE}.
 
 Please note that Palacios and Kitten are under rapid development,
 hence this manual may very well be out of date!
@@ -64,7 +71,7 @@ uses both the centralized repository and distributed development
 models. A central repository exists that holds the master version of
 the code base. This central repository is cloned by multiple people
 and in multiple places to support various development efforts. A
-feature of \texttt{git} is that every developer actually has a fully copy of
+feature of \texttt{git} is that every developer actually has a full copy of
 the entire repository, and so can function independently until such
 time as they need to re-sync with the master version. 
 
@@ -114,7 +121,6 @@ On the machine {\em newbehemoth.cs.northwestern.edu} you will want to
 use the following command instead. The {\em newskysaw} home
 directories are NFS-mounted on /home-remote.
 
-
 \begin{verbatim}
 git clone /home-remote/palacios/palacios
 \end{verbatim}
@@ -124,10 +130,22 @@ On any other machine, you can clone the repository via ssh, provided
 you have a newskysaw account:
  
 \begin{verbatim}
-git clone ssh://you@newskysaw.cs.northwestern.edu//home/palaicos/palacios
+git clone ssh://you@newskysaw.cs.northwestern.edu//home/palacios/palacios
 \end{verbatim}
 
-This creates a local copy of the repository at {\em ./palacios/}.
+External developers can clone the public repository via the web.  The
+public repository tracks the release and main development branch
+(e.g., devel) of the internal repository with a 30 minute delay.  The
+access information is available on the web site (http://v3vee.org).
+The web site also includes a publically accessible gitweb interface to
+allow browsing of the public repository.  The clone command looks like
+
+\begin{verbatim}
+git clone http://v3vee.org/palacios/palacios.web/palacios.git
+\end{verbatim}
+
+No matter how you clone, the clone command creates a local copy of the
+repository at {\em ./palacios/}.  
 
 Note that both {\em newskysaw} and {\em newbehemoth} have all the
 tools installed that are needed to build and test Palacios and Kitten.
@@ -150,11 +168,27 @@ or
 /opt/vmm-tools/bin/checkout_branch devel
 \end{verbatim}
 
-{\em Important:}
-Note that Palacios is very actively developed so the contents of the
-{\em devel} branch are frequently changing. In order to keep up to
-date with the latest version, it is necessary to periodically pull the
-latest changes from the master repository by running \verb.git pull..
+
+{\em Important:} Note that Palacios is very actively developed so the
+contents of the {\em devel} branch are frequently changing (and
+broken!). In order to keep up to date with the latest version, it is
+necessary to periodically pull the latest changes from the master
+repository by running \verb.git pull..
+
+
+The released versions of Palacios are, currently, 1.0, 1.1, and 1.2.
+To switch to the current release branch, execute
+
+\begin{verbatim}
+git checkout --track -b Release-1.2 origin/Release-1.2
+\end{verbatim}
+
+or 
+
+\begin{verbatim}
+/opt/vmm-tools/bin/checkout_branch Release-1.2
+\end{verbatim}
+
 
 
 
@@ -164,13 +198,14 @@ Kitten is available from Sandia National Labs, and is the main host OS
 we are targeting with Palacios. Loosely speaking, core Palacios
 developers are internal Kitten developers, and internal Palacios
 developers are external Kitten developers. The public repository for
-Kitten is at {\em http://code.google.com/kitten}.  To simplify things,
-we are maintaining a local mirror copy in {\em /home/palacios/kitten}
-that tracks the public repository.
+Kitten is at {\em http://code.google.com/p/kitten}.  To simplify
+things, we are maintaining a local mirror copy on newskysaw in {\em
+/home/palacios/kitten} that tracks the public repository.   
 
-Kitten uses Mercurial for their source management, so you will have to
-make sure the local mercurial version is configured correctly.
-Specifically you should add the following Python path to your shell environment.
+Kitten uses Mercurial for source management, so you will have to make
+sure the local Mercurial version is configured correctly.
+Specifically you will probably need to add something like the
+following Python path to your shell environment.
 
 \begin{verbatim}
 export PYTHONPATH=/usr/local/lib64/python2.4/site-packages/
@@ -189,7 +224,10 @@ On other machines, run
 \begin{verbatim}
 hg clone ssh://you@newskysaw.cs.northwestern.edu//home/palacios/kitten
 \end{verbatim}
-
+External developers, run
+\begin{verbatim}
+hg clone https://kitten.googlecode.com/hg/ kitten
+\end{verbatim}
 
 Both the Kitten and Palacios clone commands should be run from the
 same directory. This means that both repositories should be located at
@@ -197,9 +235,17 @@ the same directory level. The Kitten build process depends on this.
 
 {\em Important:} Like Palacios, Kitten is under active development,
 and its source tree is frequently changing. In order to keep up to
-date with the latest version, it is necessary to periodically pull the
-latest changes from the mirror repository by running \verb.hg.
-pull. followed by \verb.hg update..
+date with the latest version, it is necessary to periodically pull the  
+latest changes from the mirror repository by running \verb.hg pull.
+followed by \verb.hg update..
+
+The current release of Kitten, which will work correctly with the current 1.2 release of Palacios is 1.2.0. 
+To switch to the current release branch, execute
+
+\begin{verbatim}
+hg checkout release-1.2.0
+\end{verbatim}
+
 
 \section{Compiling Palacios}
 
@@ -237,7 +283,8 @@ Palacios has far fewer options, however.   If you don't have X or
 don't want the graphical configuration system, you can also use the
 \verb.menuconfig. or \verb.config. targets.  The available options
 change over time, so we do not cover all of them here, but here are a
-few that are usually important, with their recommended values noted:
+few that are usually important.  We note how to set these options to
+configure a minimal VMM in the following.  
 \begin{itemize}
 \item Target Configuration:   
 \begin{itemize}
@@ -254,14 +301,14 @@ data collection (on)
 \item Enable VMM instrumentation --- this is heavyweight logging and
 data collection (off)
 \item Enable passthrough video --- this lets a guest write directly to
-the video card (on)
+the video card (off)  (this is outdated and handled in a different way now)
 \item Enable experimental options --- this makes it possible to select
-features that are under current development (on).  You probably want
-to leave VNET turned off.  VNET is an experimental VMM-embedded
+features that are under current development (off).  You probably want
+to leave leave this all off.  The VNET suboption is for an experimental VMM-embedded
 overlay network under development by Lei Xia and Yuan Tang.
 \item Enable built-in versions of stdlib functions --- this adds
 needed stdlib functions that the host OS may not supply.  For use with
-Kitten turn on and enable strncasecmp() and atoi().
+Kitten turn on and enable strcasecmp() and atoi().
 \item Enable built-in versions of stdio functions (off)
 \end{itemize}
 \item Symbiotic Functions (these are experimental options for Jack
@@ -270,9 +317,9 @@ Lange's thesis).
 \item Enable Symbiotic Functionality --- This adds symbiotic features
 to Palacios, specifically support for discovery and configuration by
 symbiotic guests, the SymSpy passive information interface for
-asynchronous symtiotic guest $\leftrightarrow$ symbiotic VMM
+asynchronous symbiotic guest $\leftrightarrow$ symbiotic VMM
 information flow, and the SymCall functional interface for synchronous
-symbiotic VMM $\rightarrow$ symbiotic guest upcalls.  (on)
+symbiotic VMM $\rightarrow$ symbiotic guest upcalls.  (off)
 \item Symbiotic Swap --- Enables the SwapBypass symbiotic service for
 symbiotic Linux guests.  (off)
 \end{itemize}
@@ -305,6 +352,7 @@ for bootstrap of most guests (on)
 for interrupt delivery on almost all guests (on)
 \item IOAPIC - Off-chip APIC  --- used for interrupt deliver for almost
 all guests (on)
+\item PIT - legacy 8254 timer (on)
 \item i440fx Northbridge --- emulation of a typical PC North Bridge
 chip, used on almost all guests (on)
 \item PIIX3 Southbridge --- emulation of a typical PC South Bridge
@@ -313,8 +361,9 @@ chip, used on almost all guests (on)
 devices (on)   
 \begin{itemize}
 \item Passthrough PCI --- allows us to make a hardware PCI device visible and
-directly accessible by the guest (on)
+directly accessible by the guest (off)
 \end{itemize}
+\item Generic --- this is a run-time configurable device that can intercept I/O port read/writes and memory region reads/writes.   Intercepted reads and writes can either be ignored or forwarded to actual hardware, and the data flow can optionally be printed.   This is a useful tool with at least three purposes.  First, it makes it possible to ``stub out'' hardware that isn't currently implemented and for which we don't want to allow passthrough access. Second, it makes it possible to provide low-level passthrough access to physical hardware.   Third, it can be used to spy on guest/device interactions, which is very helpful when trying to understand the interface of a device.
 \item NVRAM - motherboard configuration memory --- needed by BIOS bootstrap (on)
 \item Keyboard - Generic PS/2 keyboard, including mostly broken mouse
 implementation (on)
@@ -332,15 +381,16 @@ access.
 \item RAMDISK storage backend --- used to create RAM disk
 implementations of block devices (on)
 \item NETDISK storage backend --- used to create network-attached disk
-implementations of block devices, e.g., network block devices (on)
+implementations of block devices, e.g., network block devices (off)
 \item TMPDISK storage backend --- used to create temporary storage
 implementations of block devices (on)
 \item Linux Virtio Balloon Device --- used for memory ballooning by
-Linux virtio-compatible guests (on)
+Linux virtio-compatible guests (off)
 \item Linux Virtio Block Device --- used for fast block device support
-by Linux virtio-compatible guests (on)
+by Linux virtio-compatible guests (off)
 \item Linux Virtio Network Device --- used for fast network device support
-by Linux virtio-compatible guests (on) 
+by Linux virtio-compatible guests (off) 
+\item Linux Virtio Symbiotic Device (off)
 \item Symbiotic Swap Disk (multiple versions) --- used for the
 SwapBypass service (off)
 \item Disk Performance Model --- used for the
@@ -355,7 +405,7 @@ compile it by executing
 \begin{verbatim}
 make 
 \end{verbatim}
-This will produce the file {\em libv3vee.a} in the current directory.
+This will produce the file {\em libv3vee.a} in the current directory
 This static library contains the Palacios VMM and is ready for
 embedding into an OS, such as Kitten.  The library provides the
 ability to instantiate and run virtual machines.  By default, on a 64
@@ -367,6 +417,12 @@ version is what you need for use with Kitten.  A 64 bit Palacios can
 run both 64 and 32 bit guests.  Both {\em newskysaw} and {\em
 newbehemoth} are 64 bit machines. 
 
+The compilation process will also create the utility {\em build\_vm}
+(which builds guest images from XML description files), and a very
+simple guest image called {\em guest\_os.img} that essentially contains
+a Linux kernel and BusyBox.  The default Kitten configuration will use
+this guest image.
+
 
 \section{Compiling Kitten}
 Kitten requires a 64-bit version of Palacios, so make sure that
@@ -385,7 +441,8 @@ accessed via any of these make targets.
 \end{itemize}
 
 Of course, there are a range of configuration options.  In the
-following, we note only the most important:
+following, we note only the most important.  The indicated values are
+defaults for the simplest interaction between Kitten and Palacios.
 \begin{itemize}
 \item Target Configuration
 \begin{itemize}
@@ -405,24 +462,25 @@ can be found.
 image that will be embedded.  We will say more about this later.
 Essentially, however, a guest image consists of a blob that begins
 with an XML description of the desired guest environment and the
-contents of the remainder of the blob.   The remainder of the blob
-usually contains disk or cd images.
+contents of the remainder of the blob.  The remainder of the blob
+usually contains disk or cd images.  The default path is
+../palacios/guest\_os.img, where it will find the simple guest created
+during the Palacios build process.
 \end{itemize}
 \item Networking 
 \begin{itemize}
 \item Enable LWIP TCP/IP stack.  This activates a simple TCP/IP stack
-that things like NETDISK can use. (on)
+that things like NETDISK can use. (off)
 \end{itemize}
 \item Device Drivers
 \begin{itemize}
-\item VGA Console --- driver for basic video.  If you turn on
-passthrough video in Palacios, you should turn this off.
+\item VGA Console --- driver for basic video. (on)
 \item Serial Console --- driver for serial port console.  (on)
 \item VM Console --- driver for Kitten console on top of Palacios.  If
 Kitten is run {\em as a guest}, and it has VM Console on, then it can output
-cleanly via the Palacios OS Console device (off).
+cleanly via the Palacios OS Console device (on).
 \item NE2K Device Driver --- driver for NE2K and RTL8139 network cards
-(on)
+(off)
 \item VM Network Driver --- driver for Kitten network output using
 Palacios.  If Kitten is run {\em as a guest}, and it has VM Network
 Driver, then it can send and receive packets using the Palacios Linux
@@ -449,7 +507,7 @@ using KGDB, be sure to turn on debugging in Palacios as well.
 \item Include Linux compatability layer --- if this is on, you can 
 selectively add Linux system calls and other functionality to Kitten.
 Kitten is able to run Linux ELF executables as user processes with
-this layer.   
+this layer. (off)  
 \end{itemize}
 
 The guest OS that is to be booted as a VM is included as a blob
@@ -475,7 +533,7 @@ make isoimage
 \end{verbatim}
 This command will compile Kitten (with Palacios embedded in it) and
 the init task (which will contain the guest OS blob), and then
-assemble an ISO image file which can used to boot a machine.  The ISO
+assemble an ISO image file which can be used to boot a machine.  The ISO
 image is located at {\em ./arch/x86\_64/boot/image.iso}.  
 
 This image file can be used for booting a QEMU emulation environment,
@@ -486,22 +544,24 @@ booting a machine physically.
 \section{Basic Guest Configuration}
 \label{sec:guestconfig}
 
-To configure a guest, you write an XML configuration file, which
-contains references to other files that contain data needed to
-instantiate stateful devices such as virtual hard drives and CD ROMs.
-You supply this information to a guest builder utility that assembles
-a guest image suitable for reference in the Kitten configuration, as
-described above.  
+A simple guest is created when you build Palacios.  To configure your
+own guest, you write an XML configuration file, which contains
+references to other files that contain data needed to instantiate
+stateful devices such as virtual hard drives and CD ROMs.  You supply
+this information to a guest builder utility that assembles a guest
+image suitable for reference in the Kitten configuration, as described
+above.
 
 The guest builder utility is located in {\em
-palacios/utils/guest\_creator}.  You will need to run \verb.make. in that
-directory to compile it, resulting in the executable named {\em
-build\_vm}.  Also located in that directory is an example configuration
-file, named {\em default.xml}.   We typically use this file as a
-template.  It is carefully commented.  In summary, a configuration
-consists of
+palacios/utils/guest\_creator}.  You will need to run \verb.make. in
+that directory to compile it, resulting in the executable named {\em
+build\_vm}\footnote{This executable will also be copied into the top-level
+Palacios directory}.  Also located in that directory is an example
+configuration file, named {\em default.xml}.  We typically use this
+file as a template.  It is carefully commented.  In summary, a
+configuration consists of
 \begin{itemize}
-\item Physical memory size of the gust
+\item Physical memory size of the guest
 \item Basic VMM settings, such as what form of virtual paging is to be
 used, the scheduler rate, whether services like telemetry are on, etc.
 \item A memory map that maps regions of the host physical address
@@ -512,8 +572,8 @@ For example, the contents of a boot CD.
 \item A list of the devices that the guest will have, including
 configuration data for each device.
 \end{itemize}
-There are a few subtlies involved with devices.  One is that some
-devices form attachement points for other devices.  The PCI device is
+There are a few subtleties involved with devices.  One is that some
+devices form attachment points for other devices.  The PCI device is
 an example of this.  Another is that each device needs to define how
 it is attached (e.g. direct (implicit), via a PCI bus, etc.)
 Finally, there may be multiple instances of devices.   For example, a
@@ -585,11 +645,13 @@ to burn the Kitten ISO image onto a CD ROM and then boot the test
 machine with it.  The much faster way is to set the test machine up to
 use the PXE network boot system (most modern BIOSes support this), and
 boot your Kitten image over the network.  The debugging output will
-then appear on the actual serial port of the physical machine.  For
-the Northwestern environment, please talk to Jack Lange or Peter Dinda
-if you need to be able to do this.  Northwestern has a range of AMD
-and Intel boxes for testing, as do UNM and Sandia.    A different form
-of network boot is used for Red Storm. 
+then appear on the actual serial port of the physical machine.  The
+separate document {\em Booting Palacios/Kitten Over the Network Using
+PXE} explains how to set up PXE boot and serial.  For the Northwestern
+environment, please talk to Jack, Peter, Lei, or Yuan if you need to
+be able to do this.  Northwestern has a range of AMD and Intel boxes
+for testing, as do UNM and Sandia.  A different form of network boot
+is used for Red Storm.
 
 
 \section{Development Guidelines}
@@ -708,16 +770,17 @@ with patches easier.
 Git includes support for directly exporting local repository commits
 as a patch set. The basic operation is for a developer to commit a
 change to a local repository, and then export that change as a patch
-that can be applied to another git repository. While this is
-functionally possible, there are a number of issues. The main problem
-is that it is difficult to fully encapsulate a new feature in a single
-commit, and dealing with multiple patches that often overwrite each
-other is not a viable option either. Furthermore, once a patch is
-applied to the mainline, it will generate a conflicting commit that
-will become present when the developer next pulls from the central
+that can be applied to another git repository.  Patch generation is
+done with {\em git format-patch}.  While this is functionally
+possible, there are a number of issues. The main problem is that it is
+difficult to fully encapsulate a new feature in a single commit, and
+dealing with multiple patches that often overwrite each other is not a
+viable option either. Furthermore, once a patch is applied to the
+mainline, it will generate a conflicting commit that will become
+present when the developer next pulls from the central
 repository. This can result in both repositories getting out of
 sync. It is possible to deal with this by manually re-basing the local
-repository, but it is difficult and error-prone. 
+repository, but it is difficult and error-prone.
 
 This approach also does not map well when patches are being revised. A
 normal patch will go through multiple revisions as it is reviewed and
@@ -729,26 +792,27 @@ mainline.
 For this reason most internal developers should seriously consider
 {\em stacked git}. Stacked git is designed to make patch development
 easier and less of a headache. The basic mode of operation is for a
-developer to initialize a patch for a new feature and then continuously
-apply changes to the patch. Stacked Git allows a developer to layer a
-series of patches on top of a local git repository, without causing
-the repository to unsync due to local commits. Basically, the
-developer never commits changes to the repository itself but instead
-commits the changes to a specific patch. The local patches are managed
-using stack operations (push/pop) which allows a developer to apply
-and unapply patches as needed. Stacked git also manages new changes to
-the underlying git repository as a result of a pull operation and
-prevents collisions as changes are propagated upstream. For instance
-if you have a local patch that is applied to the mainline as a commit,
-when the commit is pulled down the patch becomes empty because it is
-effectively identical to the mainline. It also makes incorporating
-external revisions to a patch easier. Stacked git is installed on {\em
-newskysaw} in \verb./opt/vmm-tools/bin/. 
+developer to initialize a patch for a new feature and then
+continuously apply changes to the patch. Stacked Git allows a
+developer to layer a series of patches on top of a local git
+repository, without causing the repository to unsync due to local
+commits. Basically, the developer never commits changes to the
+repository itself but instead commits the changes to a specific
+patch. The local patches are managed using stack operations (push/pop)
+which allows a developer to apply and unapply patches as
+needed. Stacked git also manages new changes to the underlying git
+repository as a result of a pull operation and prevents collisions as
+changes are propagated upstream. For instance if you have a local
+patch that is applied to the mainline as a commit, when the commit is
+pulled down the patch becomes empty because it is effectively
+identical to the mainline. It also makes incorporating external
+revisions to a patch easier. Stacked git is installed on {\em
+newskysaw} and {\em newbehemoth} in \verb./opt/vmm-tools/bin/.
 
 Brief command overview:
 \begin{itemize}
-\item \verb.stg init. -- Initialize stacked git in a given branch
-\item \verb.stg new. -- create a new patch set, an editor will open
+\item \verb.stg init. -- initialize stacked git in a given branch
+\item \verb.stg new. -- create a new patch set; an editor will open
 asking for a commit message that will be used when the patch is
 ultimately committed.
 \item \verb.stg pop. -- pops a patch off of the source tree.
@@ -757,14 +821,14 @@ ultimately committed.
 that can then be emailed.
 \item \verb.stg refresh. -- commits local changes to the patch set at
 the top of the applied stack.
-\item \verb.stg fold. -- Apply a patch file to the current
-pat1ch. (This is how you can manage revisions that are made by other developers).
+\item \verb.stg fold. -- apply a patch file to the current
+patch. (This is how you can manage revisions that are made by other developers).
 \end{itemize}
 
 You should definitely look at the online documentation to better
 understand how stacked git works. It is not required of course, but if
-you want your changes to be applied its up to you to generate a patch
-that is acceptable to a core developer. Ultimately using Stacked git
+you want your changes to be applied it's up to you to generate a patch
+that is acceptable to a core developer. Ultimately, using Stacked git
 should be easier than going it alone.
 
 
@@ -815,26 +879,17 @@ hg qpush -a
 \end{verbatim}
 
 
-%Also, remember that Kitten is not a Northwestern project and is being
-%developed by professional developers at Sandia National Labs. So keep
-%in mind that you are representing Northwestern and the rest of the
-%Palacios development group. We are collaborating with them because
-%Kitten and the resources they have are very important for our research
-%efforts. They are collaborating with us because they believe that
-%Palacios might be able to help them. Therefore it is important that we
-%continue to ensure that they see value in our collaboration. In plain
-%terms, we need to make sure they think we're smart and know what we're
-%doing. So please keep that in mind when dealing with the Kitten group.
-
 
 \section{Networking}
 
 Both the Kitten and GeekOS substrates on which Palacios can run
 currently include drivers for two simple network cards, the NE2000,
-and the RTL8139.  The Kitten substrate is acquiring an ever increasing
-set of drivers for specialized network systems.   A lightweight
-networking stack is included so that TCP/IP networking is possible
-from within the host OS kernel and in Palacios.  
+and the RTL8139.  Palacios also supports passthrough I/O for PCI
+devices, meaning we can make NICs directly accessible by guests. The
+Kitten substrate is acquiring an ever increasing set of drivers for
+specialized network systems.  A lightweight networking stack is
+included so that TCP/IP networking is possible from within the host OS
+kernel and in Palacios.
 
 When debugging Palacios on QEMU, it is very convenient to add an
 RTL8139 card to your QEMU configuration, and then drive it from within
@@ -856,8 +911,7 @@ In order to get QEMU networking to function, it is necessary to create
 TAP interfaces, and, optionally, to bridge them to real networks.  A
 development machine typically will have several TAP interfaces, and
 more can be created.  Generally, each developer should have a TAP
-interface of his or her own.  In the following, we will use our
-development machine, newskysaw, as an example.
+interface of his or her own.  Here we use newskysaw as an example.
 
 To set up a TAP interface on newskysaw, the following command is used:
 \begin{verbatim}
@@ -865,7 +919,7 @@ To set up a TAP interface on newskysaw, the following command is used:
 \end{verbatim}
 
 When QEMU runs with a tap interface, it will use /etc/qemu-ifup to
-bring up the interface.  On newskysaw, /etc/qemu-ifup looks like this:
+bring up the interface.  /etc/qemu-ifup looks like this:
 
 \begin{verbatim}
 #!/bin/bash
diff --git a/palacios/include/devices/icc_bus.h b/palacios/include/devices/icc_bus.h
new file mode 100644 (file)
index 0000000..c51f6f8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef ICC_BUS_H_
+#define ICC_BUS_H_
+
+
+struct v3_icc_ops {
+    int (*raise_intr)(struct guest_info * core, int intr_num, void * private_data);
+};
+
+
+/**
+ *
+ */
+int v3_icc_register_apic(struct guest_info * vm, struct vm_device * icc_bus, uint8_t apic_phys_id, struct v3_icc_ops * ops, void * priv_data);
+
+
+/**
+ * Send an inter-processor interrupt (IPI) from this local APIC to another local APIC.
+ *
+ * @param icc_bus - The ICC bus that routes IPIs.
+ * @param apic_num - The remote APIC number.
+ * @param intr_num - The interrupt number.
+ */
+int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num);
+
+
+
+
+#endif /* ICC_BUS_H_ */
index 1da7102..bfa9052 100644 (file)
@@ -59,19 +59,19 @@ struct v3_pci_bar {
        struct {
            int num_pages;
            addr_t default_base_addr;
-           int (*mem_read)(addr_t guest_addr, void * dst, uint_t length, void * private_data);
-           int (*mem_write)(addr_t guest_addr, void * src, uint_t length, void * private_data);
+           int (*mem_read)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * private_data);
+           int (*mem_write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * private_data);
        };
 
        struct {
            int num_ports;
            uint16_t default_base_port;
-           int (*io_read)(ushort_t port, void * dst, uint_t length, void * private_data);
-           int (*io_write)(ushort_t port, void * src, uint_t length, void * private_data);
+           int (*io_read)(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * private_data);
+           int (*io_write)(struct guest_info * core, ushort_t port, void * src, uint_t length, void * private_data);
        };
        
        struct {
-           int (*bar_init)(int bar_num, uint32_t * dst,void * private_data);
+           int (*bar_init)(int bar_num, uint32_t * dst, void * private_data);
            int (*bar_write)(int bar_num, uint32_t * src, void * private_data);
        };
     };
index f0c3463..f363a59 100644 (file)
@@ -43,7 +43,7 @@ struct svm_io_info {
 } __attribute__((packed));
 
 
-int v3_init_svm_io_map(struct guest_info * info);
+int v3_init_svm_io_map(struct v3_vm_info * vm);
 
 int v3_handle_svm_io_in(struct guest_info * info, struct svm_io_info * io_info);
 int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info);
index defb6fa..1ef8e75 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <palacios/vmm.h>
 
-int v3_init_svm_msr_map(struct guest_info * info);
+int v3_init_svm_msr_map(struct v3_vm_info * vm);
 
 
 #endif // ! __V3VEE__
index 7b849d3..24fe22d 100644 (file)
@@ -132,9 +132,6 @@ struct v3_segments {
 struct shadow_page_state;
 struct v3_intr_state;
 
-#ifdef CONFIG_TELEMETRY
-struct v3_telemetry;
-#endif
 
 #ifdef CONFIG_SYMBIOTIC_SWAP
 struct v3_sym_swap_state;
@@ -144,84 +141,108 @@ struct v3_sym_swap_state;
 struct v3_sym_state;
 #endif
 
+
 struct guest_info {
     uint64_t rip;
 
     uint_t cpl;
 
-    addr_t mem_size; // In bytes for now
-    v3_shdw_map_t mem_map;
-
-    struct v3_config * cfg_data;
-    v3_vm_class_t vm_class;
-
     struct vm_time time_state;
 
-  
     v3_paging_mode_t shdw_pg_mode;
     struct shadow_page_state shdw_pg_state;
     addr_t direct_map_pt;
 
 
     // This structure is how we get interrupts for the guest
-    struct v3_intr_state intr_state;
+    struct v3_intr_core_state intr_core_state;
 
     // This structure is how we get exceptions for the guest
     struct v3_excp_state excp_state;
 
-    struct v3_io_map io_map;
 
-    struct v3_msr_map msr_map;
+    v3_cpu_mode_t cpu_mode;
+    v3_mem_mode_t mem_mode;
+    uint_t addr_width;
 
-    struct v3_cpuid_map cpuid_map;
+    struct v3_gprs vm_regs;
+    struct v3_ctrl_regs ctrl_regs;
+    struct v3_dbg_regs dbg_regs;
+    struct v3_segments segments;
 
-#ifdef CONFIG_SYMBIOTIC
-    // Symbiotic state
-    struct v3_sym_state sym_state;
 
-#ifdef CONFIG_SYMBIOTIC_SWAP
-    struct v3_sym_swap_state swap_state;
-#endif
+    void * vmm_data;
+
+    uint64_t yield_start_cycle;
+    
+    uint64_t num_exits;
+
+#ifdef CONFIG_TELEMETRY
+    struct v3_core_telemetry core_telem;
 #endif
 
+
+    // struct v3_core_dev_mgr core_dev_mgr;
+
+    void * decoder_state;
+
+
+    struct v3_vm_info * vm_info;
+    // the logical cpu this guest context is executing on
+    int cpu_id;
+};
+
+
+
+
+struct v3_vm_info {
+    v3_vm_class_t vm_class;
+
+    addr_t mem_size; // In bytes for now
+    struct v3_mem_map mem_map;
+
+
+    struct v3_io_map io_map;
+    struct v3_msr_map msr_map;
+    struct v3_cpuid_map cpuid_map;
+
     v3_hypercall_map_t hcall_map;
 
+
+    struct v3_intr_routers intr_routers;
     // device_map
     struct vmm_dev_mgr  dev_mgr;
 
     struct v3_host_events host_event_hooks;
 
-    v3_cpu_mode_t cpu_mode;
-    v3_mem_mode_t mem_mode;
-    uint_t addr_width;
+    struct v3_config * cfg_data;
 
+    v3_vm_operating_mode_t run_state;
 
-    struct v3_gprs vm_regs;
-    struct v3_ctrl_regs ctrl_regs;
-    struct v3_dbg_regs dbg_regs;
-    struct v3_segments segments;
+#ifdef CONFIG_SYMBIOTIC
+    // Symbiotic state
+    struct v3_sym_state sym_state;
+#ifdef CONFIG_SYMBIOTIC_SWAP
+    struct v3_sym_swap_state swap_state;
+#endif
+#endif
 
-    v3_vm_operating_mode_t run_state;
-    void * vmm_data;
 
-    uint64_t yield_cycle_period;
-    uint64_t yield_start_cycle;
-    
-    uint64_t num_exits;
 
 #ifdef CONFIG_TELEMETRY
     uint_t enable_telemetry;
     struct v3_telemetry_state telemetry;
 #endif
 
+    uint64_t yield_cycle_period;  
+
+    int num_cores;
+    struct guest_info cores[0];
 
+};
 
 
-    void * decoder_state;
 
-    // the logical cpu this guest context is executing on
-    int cpu_id;
-};
 
 
 uint_t v3_get_addr_width(struct guest_info * info);
index b05871f..bbc4eba 100644 (file)
@@ -148,16 +148,34 @@ struct guest_info;
     } while (0)
 
 
-#define V3_Hook_Interrupt(irq, opaque) ({                              \
+#define V3_Hook_Interrupt(vm, irq) ({                                  \
            int ret = 0;                                                \
            extern struct v3_os_hooks * os_hooks;                       \
            if ((os_hooks) && (os_hooks)->hook_interrupt) {             \
-               ret = (os_hooks)->hook_interrupt(irq, opaque);          \
+               ret = (os_hooks)->hook_interrupt(vm, irq);              \
            }                                                           \
            ret;                                                        \
        })                                                              \
        
 
+#define V3_Get_CPU() ({                                                \
+            int ret = 0;                                                \
+            extern struct v3_os_hooks * os_hooks;                       \
+            if ((os_hooks) && (os_hooks)->get_cpu) {                    \
+                ret = (os_hooks)->get_cpu();                            \
+            }                                                           \
+            ret;                                                        \
+        })
+
+#define V3_Call_On_CPU(cpu, fn, arg)                   \
+    do {                                               \
+        extern struct v3_os_hooks * os_hooks;           \
+        if ((os_hooks) && (os_hooks)->call_on_cpu) {    \
+            (os_hooks)->call_on_cpu(cpu, fn, arg);      \
+        }                                               \
+    } while (0)
+
+
 #define V3_ACK_IRQ(irq)                                                \
     do {                                                       \
        extern struct v3_os_hooks * os_hooks;                   \
@@ -200,7 +218,7 @@ void v3_yield_cond(struct guest_info * info);
 void v3_print_cond(const char * fmt, ...);
 
 
-void v3_interrupt_cpu(struct guest_info * vm, int logical_cpu);
+void v3_interrupt_cpu(struct v3_vm_info * vm, int logical_cpu);
 
 unsigned int v3_get_cpu_id();
 
@@ -214,7 +232,7 @@ int v3_vm_enter(struct guest_info * info);
 
 
 
-struct guest_info;
+struct v3_vm_info;
 
 /* This will contain function pointers that provide OS services */
 struct v3_os_hooks {
@@ -230,7 +248,7 @@ struct v3_os_hooks {
     void *(*paddr_to_vaddr)(void *addr);
     void *(*vaddr_to_paddr)(void *addr);
 
-    int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
+    int (*hook_interrupt)(struct v3_vm_info * vm, unsigned int irq);
 
     int (*ack_irq)(int irq);
 
@@ -246,7 +264,7 @@ struct v3_os_hooks {
     void (*mutex_unlock)(void * mutex);
 
     unsigned int (*get_cpu)(void);
-    void (*interrupt_cpu)(struct guest_info * vm, int logical_cpu);
+    void (*interrupt_cpu)(struct v3_vm_info * vm, int logical_cpu);
     void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg);
     void (*start_thread_on_cpu)(int logical_cpu, int (*fn)(void * arg), void * arg, char * thread_name);
 };
@@ -275,10 +293,10 @@ struct v3_interrupt {
 void Init_V3(struct v3_os_hooks * hooks,  int num_cpus);
 
 
-int v3_start_vm(struct guest_info * info, unsigned int cpu_mask);
-struct guest_info * v3_create_vm(void * cfg);
+int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask);
+struct v3_vm_info * v3_create_vm(void * cfg);
 
-int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr);
+int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr);
 
 
 
index a719cf5..02b6d03 100644 (file)
@@ -32,9 +32,9 @@
 //#include <palacios/svm.h>
 
 
-struct guest_info;
+struct v3_vm_info;
 
-int v3_config_guest(struct guest_info * info, void * cfg_blob);
+struct v3_vm_info * v3_config_guest( void * cfg_blob);
 
 struct v3_cfg_file {
     void * data;
@@ -59,7 +59,7 @@ struct v3_config {
 };
 
 
-struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag);
+struct v3_cfg_file * v3_cfg_get_file(struct v3_vm_info * info, char * tag);
 
 char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag);
 v3_cfg_tree_t * v3_cfg_subtree(v3_cfg_tree_t * tree, char * tag);
index a5f45ee..82a4fd6 100644 (file)
@@ -31,7 +31,7 @@
 
 struct guest_info;
 
-void v3_init_cpuid_map(struct guest_info * info);
+void v3_init_cpuid_map(struct v3_vm_info * vm);
 
 
 struct v3_cpuid_hook {
@@ -52,16 +52,16 @@ struct v3_cpuid_map {
     struct rb_root map;
 };
 
-void v3_print_cpuid_map(struct guest_info * info);
+void v3_print_cpuid_map(struct v3_vm_info * vm);
 
-int v3_hook_cpuid(struct guest_info * info, uint32_t cpuid, 
+int v3_hook_cpuid(struct v3_vm_info * vm, uint32_t cpuid, 
                  int (*hook_fn)(struct guest_info * info, uint32_t cpuid, \
                                 uint32_t * eax, uint32_t * ebx, \
                                 uint32_t * ecx, uint32_t * edx, \
                                 void * private_data), 
                  void * private_data);
 
-int v3_unhook_cpuid(struct guest_info * info, uint32_t cpuid);
+int v3_unhook_cpuid(struct v3_vm_info * vm, uint32_t cpuid);
 
 int v3_handle_cpuid(struct guest_info * info);
 
index f23caad..0063473 100644 (file)
@@ -212,8 +212,8 @@ int v3_handle_cr4_write(struct guest_info * info);
 int v3_handle_cr4_read(struct guest_info * info);
 
 
-int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data);
-int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data);
+int v3_handle_efer_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
+int v3_handle_efer_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
 
 
 #endif // ! __V3VEE__
index 8c80ffa..7e4708f 100644 (file)
@@ -29,7 +29,7 @@
 #include <palacios/vmm_config.h>
 
 
-struct guest_info;
+struct v3_vm_info;
 
 struct v3_device_ops;
 
@@ -41,7 +41,7 @@ struct vm_device {
 
     struct v3_device_ops * ops;
 
-    struct guest_info * vm;
+    struct v3_vm_info * vm;
 
     struct list_head dev_link;
 
@@ -67,14 +67,13 @@ struct vmm_dev_mgr {
 
 };
 
+int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg);
 
 
-
-int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg);
 void v3_free_device(struct vm_device * dev);
 
 
-struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name);
+struct vm_device * v3_find_dev(struct v3_vm_info * info, const char * dev_name);
 
 
 // Registration of devices
@@ -86,8 +85,10 @@ struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name);
 
 
 
-int v3_init_dev_mgr(struct guest_info * info);
-int v3_dev_mgr_deinit(struct guest_info * info);
+int v3_init_dev_mgr(struct v3_vm_info * vm);
+int v3_dev_mgr_deinit(struct v3_vm_info * vm);
+
+
 
 
 
@@ -116,14 +117,14 @@ struct v3_device_ops {
 
 int v3_dev_hook_io(struct vm_device   *dev,
                   ushort_t            port,
-                  int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
-                  int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev));
+                  int (*read)(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev),
+                  int (*write)(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev));
 
 int v3_dev_unhook_io(struct vm_device   *dev,
                     ushort_t            port);
 
 
-int v3_attach_device(struct guest_info * vm, struct vm_device * dev);
+int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev);
 int v3_detach_device(struct vm_device * dev);
 
 struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, void * private_data);
@@ -131,7 +132,7 @@ struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, v
 
 struct v3_device_info {
     char * name;
-    int (*init)(struct guest_info * info, v3_cfg_tree_t * cfg);
+    int (*init)(struct v3_vm_info * info, v3_cfg_tree_t * cfg);
 };
 
 
@@ -146,7 +147,7 @@ struct v3_device_info {
 
 
 
-void v3_print_dev_mgr(struct guest_info * info);
+void v3_print_dev_mgr(struct v3_vm_info * vm);
 
 
 struct v3_dev_blk_ops {
@@ -166,30 +167,30 @@ struct v3_dev_console_ops {
 
 };
 
-int v3_dev_add_blk_frontend(struct guest_info * info, 
+int v3_dev_add_blk_frontend(struct v3_vm_info * vm, 
                            char * name, 
-                           int (*connect)(struct guest_info * info, 
+                           int (*connect)(struct v3_vm_info * vm, 
                                            void * frontend_data, 
                                            struct v3_dev_blk_ops * ops, 
                                            v3_cfg_tree_t * cfg, 
                                            void * private_data), 
                            void * priv_data);
-int v3_dev_connect_blk(struct guest_info * info, 
+int v3_dev_connect_blk(struct v3_vm_info * vm, 
                       char * frontend_name, 
                       struct v3_dev_blk_ops * ops, 
                       v3_cfg_tree_t * cfg, 
                       void * private_data);
 
-int v3_dev_add_net_frontend(struct guest_info * info, 
+int v3_dev_add_net_frontend(struct v3_vm_info * vm, 
                            char * name, 
-                           int (*connect)(struct guest_info * info, 
+                           int (*connect)(struct v3_vm_info * vm, 
                                            void * frontend_data, 
                                            struct v3_dev_net_ops * ops, 
                                            v3_cfg_tree_t * cfg, 
                                            void * private_data), 
                            void * priv_data);
 
-int v3_dev_connect_net(struct guest_info * info, 
+int v3_dev_connect_net(struct v3_vm_info * vm, 
                       char * frontend_name, 
                       struct v3_dev_net_ops * ops, 
                       v3_cfg_tree_t * cfg, 
index 46836cd..9d1b6be 100644 (file)
 
 
 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr, 
-                       int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
+                       int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data), 
                        void * priv_data);
 
 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
-                      int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
-                      int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
+                      int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
+                      int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data), 
                       void * priv_data);
 
 
index e115005..726fada 100644 (file)
@@ -38,6 +38,7 @@ struct v3_timer_event {
 
 #include <palacios/vmm_list.h>
 
+struct v3_vm_info;
 
 typedef enum {HOST_KEYBOARD_EVT, 
              HOST_MOUSE_EVT, 
@@ -45,9 +46,9 @@ typedef enum {HOST_KEYBOARD_EVT,
 
 
 union v3_host_event_handler {
-    int (*keyboard_handler)(struct guest_info * info, struct v3_keyboard_event * evt, void * priv_data);
-    int (*mouse_handler)(struct guest_info * info, struct v3_mouse_event * evt, void * priv_data);
-    int (*timer_handler)(struct guest_info * info, struct v3_timer_event * evt, void * priv_data);
+    int (*keyboard_handler)(struct v3_vm_info * vm, struct v3_keyboard_event * evt, void * priv_data);
+    int (*mouse_handler)(struct v3_vm_info * vm, struct v3_mouse_event * evt, void * priv_data);
+    int (*timer_handler)(struct v3_vm_info * vm, struct v3_timer_event * evt, void * priv_data);
 };
 
 
@@ -67,11 +68,11 @@ struct v3_host_events {
 
 
 
-int v3_init_host_events(struct guest_info * info);
+int v3_init_host_events(struct v3_vm_info * vm);
 
 #define V3_HOST_EVENT_HANDLER(cb) ((union v3_host_event_handler)cb)
 
-int v3_hook_host_event(struct guest_info * info, 
+int v3_hook_host_event(struct v3_vm_info * vm, 
                       v3_host_evt_type_t event_type, 
                       union v3_host_event_handler cb, 
                       void * private_data);
@@ -80,9 +81,9 @@ int v3_hook_host_event(struct guest_info * info,
 
 
 
-int v3_deliver_keyboard_event(struct guest_info * info, struct v3_keyboard_event * evt);
-int v3_deliver_mouse_event(struct guest_info * info, struct v3_mouse_event * evt);
-int v3_deliver_timer_event(struct guest_info * info, struct v3_timer_event * evt);
+int v3_deliver_keyboard_event(struct v3_vm_info * vm, struct v3_keyboard_event * evt);
+int v3_deliver_mouse_event(struct v3_vm_info * vm, struct v3_mouse_event * evt);
+int v3_deliver_timer_event(struct v3_vm_info * vm, struct v3_timer_event * evt);
 
 
 
index 6ec1462..26d14b4 100644 (file)
 typedef struct rb_root v3_hypercall_map_t;
 
 struct guest_info;
+struct v3_vm_info;
 
-void v3_init_hypercall_map(struct guest_info * info);
+void v3_init_hypercall_map(struct v3_vm_info * vm);
 
 
-int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id, 
-                         int (*hypercall)(struct guest_info * info, uint_t hcall_id, void * priv_data),
+int v3_register_hypercall(struct v3_vm_info * vm, uint_t hypercall_id, 
+                         int (*hypercall)(struct guest_info * info , uint_t hcall_id, void * priv_data),
                          void * priv_data);
 
 
index 0781844..2a7c294 100644 (file)
 typedef enum {V3_INVALID_INTR, V3_EXTERNAL_IRQ, V3_VIRTUAL_IRQ, V3_NMI, V3_SOFTWARE_INTR} v3_intr_type_t;
 
 struct guest_info;
+struct v3_vm_info;
 struct v3_interrupt;
 
 
 
 struct v3_irq_hook {
-    int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data);
+    int (*handler)(struct v3_vm_info * vm, struct v3_interrupt * intr, void * priv_data);
     void * priv_data;
 };
 
 #define MAX_IRQ 256
 
 
+struct v3_intr_routers {
+    struct list_head router_list;
 
+    v3_lock_t irq_lock;
 
-struct v3_intr_state {
-
-    struct list_head controller_list;
+    /* some way to get the [A]PIC intr */
+    struct v3_irq_hook * hooks[256];
+};
 
+struct v3_intr_core_state {
     uint_t irq_pending;
     uint_t irq_started;
     uint_t irq_vector;
@@ -57,42 +62,43 @@ struct v3_intr_state {
 
     v3_lock_t irq_lock;
 
-    /* some way to get the [A]PIC intr */
-    struct v3_irq_hook * hooks[256];
-  
+    struct list_head controller_list;
 };
 
 
 
-void v3_init_interrupt_state(struct guest_info * info);
-
+void v3_init_intr_controllers(struct guest_info * info);
+void v3_init_intr_routers(struct v3_vm_info * vm);
 
 int v3_raise_virq(struct guest_info * info, int irq);
 int v3_lower_virq(struct guest_info * info, int irq);
 
-int v3_raise_irq(struct guest_info * info, int irq);
-int v3_lower_irq(struct guest_info * info, int irq);
+int v3_raise_irq(struct v3_vm_info * vm, int irq);
+int v3_lower_irq(struct v3_vm_info * vm, int irq);
 
 
 
 struct intr_ctrl_ops {
     int (*intr_pending)(struct guest_info * info, void * private_data);
     int (*get_intr_number)(struct guest_info * info, void * private_data);
-    int (*raise_intr)(struct guest_info * info, void * private_data, int irq);
-    int (*lower_intr)(struct guest_info * info, void * private_data, int irq);
     int (*begin_irq)(struct guest_info * info, void * private_data, int irq);
 };
 
+struct intr_router_ops {
+    int (*raise_intr)(struct v3_vm_info * vm, void * private_data, int irq);
+    int (*lower_intr)(struct v3_vm_info * vm, void * private_data, int irq);
+};
 
 
-void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
+
+int v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * priv_data);
+int v3_register_intr_router(struct v3_vm_info * vm, struct intr_router_ops * ops, void * priv_data);
 
 v3_intr_type_t v3_intr_pending(struct guest_info * info);
 uint32_t v3_get_intr(struct guest_info * info);
+int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type);
 
-//intr_type_t v3_get_intr_type(struct guest_info * info);
 
-int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type);
 
 /*
   int start_irq(struct vm_intr * intr);
@@ -101,12 +107,12 @@ int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t
 
 
 
-int v3_hook_irq(struct guest_info * info, 
+int v3_hook_irq(struct v3_vm_info * vm, 
                uint_t irq,
-               int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data),
+               int (*handler)(struct v3_vm_info * vm, struct v3_interrupt * intr, void * priv_data),
                void  * priv_data);
 
-int v3_hook_passthrough_irq(struct guest_info *info, uint_t irq);
+int v3_hook_passthrough_irq(struct v3_vm_info * vm, uint_t irq);
 
 
 
index 4608eae..726f75a 100644 (file)
 
 
 
+struct v3_vm_info;
 struct guest_info;
 
-void v3_init_io_map(struct guest_info * info);
+void v3_init_io_map(struct v3_vm_info * vm);
 
 
 
 
 /* External API */
-int v3_hook_io_port(struct guest_info * info, uint16_t port, 
-                   int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data),
-                   int (*write)(uint16_t port, void * src, uint_t length, void * priv_data), 
+int v3_hook_io_port(struct v3_vm_info * vm, uint16_t port, 
+                   int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data),
+                   int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data), 
                    void * priv_data);
 
-int v3_unhook_io_port(struct guest_info * info, uint16_t port);
+int v3_unhook_io_port(struct v3_vm_info * vm, uint16_t port);
 
 
 
@@ -53,33 +54,30 @@ struct v3_io_hook {
     uint16_t port;
 
     // Reads data into the IO port (IN, INS)
-    int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data);
+    int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data);
 
     // Writes data from the IO port (OUT, OUTS)
-    int (*write)(uint16_t port, void * src, uint_t length, void * priv_data);
-
-
+    int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data);
 
     void * priv_data;
   
     struct rb_node tree_node;
-
 };
 
 struct v3_io_map {
     struct rb_root map;
 
-    int (*update_map)(struct guest_info * info, uint16_t port, int hook_read, int hook_write);
+    int (*update_map)(struct v3_vm_info * vm, uint16_t port, int hook_read, int hook_write);
 
     void * arch_data;
 };
 
-struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint16_t port);
+struct v3_io_hook * v3_get_io_hook(struct v3_vm_info * vm, uint16_t port);
 
 
-void v3_print_io_map(struct guest_info * info);
+void v3_print_io_map(struct v3_vm_info * vm);
 
-void v3_refresh_io_map(struct guest_info * info);
+void v3_refresh_io_map(struct v3_vm_info * vm);
 
 
 void v3_outb(uint16_t port, uint8_t value);
index 331a307..af1f820 100644 (file)
@@ -69,11 +69,24 @@ struct sys_segment64 {
 static void __inline__ v3_cpuid(uint32_t target, 
                                uint32_t * eax, uint32_t * ebx, 
                                uint32_t * ecx, uint32_t * edx) {
+#ifdef __V3_64BIT__
     __asm__ __volatile__ (
                          "cpuid\n\t"
                          : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
                          : "0" (target), "2" (*ecx)
                          );
+#elif __V3_32BIT__
+    // 32 bit code compiled with -fPIC, cannot use ebx as an ouput reg. Fantastic.
+    __asm__ __volatile__ (
+                         "pushl %%ebx\n\t"
+                         "movl %%edi, %%ebx\n\t"
+                         "cpuid\n\t"
+                         "movl %%ebx, %%edi\n\t"
+                         "popl %%ebx\n\t"
+                         : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx)
+                         : "0" (target), "2" (*ecx)
+                         );
+#endif
     return;
 }
 
index f6338df..14423fe 100644 (file)
 
 #include <palacios/vmm_paging.h>
 #include <palacios/vmm_rbtree.h>
-
+#include <palacios/vmm_list.h>
 
 struct guest_info;
+struct v3_vm_info;
 
 
 
@@ -43,7 +44,7 @@ typedef enum shdw_region_type {
     SHDW_REGION_ALLOCATED,                  // Region is a section of host memory
 } v3_shdw_region_type_t;
 
-
+#define V3_MEM_CORE_ANY ((uint16_t)-1)
 
 
 struct v3_shadow_region {
@@ -54,67 +55,68 @@ struct v3_shadow_region {
   
     addr_t                  host_addr; // This either points to a host address mapping
 
-
     // Called when data is read from a memory page
-    int (*read_hook)(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
+    int (*read_hook)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data);
     // Called when data is written to a memory page
-    int (*write_hook)(addr_t guest_addr, void * src, uint_t length, void * priv_data);
+    int (*write_hook)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data);
 
     void * priv_data;
 
-    struct rb_node tree_node;
+    int core_id;
+
+    struct rb_node tree_node; // This for memory regions mapped to the global map
 };
 
 
-typedef struct v3_shdw_map {
+struct v3_mem_map {
     struct v3_shadow_region base_region;
 
-
-    addr_t hook_hva;
-
     struct rb_root shdw_regions;
-} v3_shdw_map_t;
+
+    void * hook_hvas; // this is an array of pages, equal to the number of cores
+};
 
 
+int v3_init_mem_map(struct v3_vm_info * vm);
+void v3_delete_mem_map(struct v3_vm_info * vm);
 
 
-int v3_init_shadow_map(struct guest_info * info);
-void v3_delete_shadow_map(struct guest_info * info);
 
 
-int v3_add_shadow_mem(struct guest_info * guest_info, 
-                     addr_t guest_addr_start,
-                     addr_t guest_addr_end,
-                     addr_t host_addr);
+int v3_add_shadow_mem(struct v3_vm_info * vm, uint16_t core_id,
+                     addr_t guest_addr_start, addr_t guest_addr_end, addr_t host_addr);
 
-int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t guest_addr_end,
-                    int (*read)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
-                    int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+int v3_hook_full_mem(struct v3_vm_info * vm, uint16_t core_id,
+                    addr_t guest_addr_start, addr_t guest_addr_end,
+                    int (*read)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
+                    int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
                     void * priv_data);
 
-int v3_hook_write_mem(struct guest_info * info, addr_t guest_addr_start, addr_t guest_addr_end,
-                     addr_t host_addr,
-                     int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+int v3_hook_write_mem(struct v3_vm_info * vm, uint16_t core_id, 
+                     addr_t guest_addr_start, addr_t guest_addr_end, addr_t host_addr,
+                     int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
                      void * priv_data);
 
 
+int v3_unhook_mem(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr_start);
+
+
 
-int v3_unhook_mem(struct guest_info * info, addr_t guest_addr_start);
 
 
-void v3_delete_shadow_region(struct guest_info * info, struct v3_shadow_region * reg);
+void v3_delete_shadow_region(struct v3_vm_info * vm, struct v3_shadow_region * reg);
 
 
 
 
-struct v3_shadow_region * v3_get_shadow_region(struct guest_info * info, addr_t guest_addr);
-addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, addr_t guest_addr);
+struct v3_shadow_region * v3_get_shadow_region(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr);
+addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, uint16_t core_id, addr_t guest_addr);
 
 
 
 
 
-void v3_print_mem_map(struct guest_info * info);
+void v3_print_mem_map(struct v3_vm_info * vm);
 
 
 
index 717d2ba..f494772 100644 (file)
@@ -27,7 +27,7 @@
 #include <palacios/vmm_list.h>
 
 struct guest_info;
-
+struct v3_vm_info;
 
 struct v3_msr {
 
@@ -47,8 +47,8 @@ typedef struct v3_msr v3_msr_t;
 struct v3_msr_hook {
     uint_t msr;
   
-    int (*read)(uint_t msr, struct v3_msr * dst, void * priv_data);
-    int (*write)(uint_t msr, struct v3_msr src, void * priv_data);
+    int (*read)(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
+    int (*write)(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
 
     void * priv_data;
 
@@ -63,27 +63,27 @@ struct v3_msr_map {
     uint_t num_hooks;
     struct list_head hook_list;
 
-    int (*update_map)(struct guest_info * info, uint_t msr, int hook_read, int hook_write);
+    int (*update_map)(struct v3_vm_info * vm, uint_t msr, int hook_read, int hook_write);
     void * arch_data;
 
 };
 
 
-void v3_init_msr_map(struct guest_info * info);
+void v3_init_msr_map(struct v3_vm_info * vm);
 
-int v3_unhook_msr(struct guest_info * info, uint_t msr);
+int v3_unhook_msr(struct v3_vm_info * vm, uint_t msr);
 
-int v3_hook_msr(struct guest_info * info, uint_t msr,
-               int (*read)(uint_t msr, struct v3_msr * dst, void * priv_data),
-               int (*write)(uint_t msr, struct v3_msr src, void * priv_data), 
+int v3_hook_msr(struct v3_vm_info * vm, uint_t msr,
+               int (*read)(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data),
+               int (*write)(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data), 
                void * priv_data);
 
 
-struct v3_msr_hook * v3_get_msr_hook(struct guest_info * info, uint_t msr);
+struct v3_msr_hook * v3_get_msr_hook(struct v3_vm_info * vm, uint_t msr);
 
-void v3_refresh_msr_map(struct guest_info * info);
+void v3_refresh_msr_map(struct v3_vm_info * vm);
 
-void v3_print_msr_map(struct guest_info * info);
+void v3_print_msr_map(struct v3_vm_info * vm);
 
 int v3_handle_msr_write(struct guest_info * info);
 
index 5de9720..a37cc8e 100644 (file)
@@ -55,7 +55,7 @@ struct v3_sym_interface {
 #include <palacios/vm_guest.h>
 
 
-struct v3_sym_context {
+struct v3_sym_core_context {
     struct v3_gprs vm_regs;
     struct v3_segment cs;
     struct v3_segment ss;
@@ -66,14 +66,7 @@ struct v3_sym_context {
     uint8_t cpl;
 };
 
-
-struct v3_sym_state {
-    
-    struct v3_sym_interface * sym_page;
-    addr_t sym_page_pa;
-
-    uint64_t guest_pg_addr;
-
+struct v3_symcall_state{
     struct {
        uint_t active                  : 1; // activated when symbiotic page MSR is written
        uint_t sym_call_active         : 1;
@@ -81,7 +74,7 @@ struct v3_sym_state {
        uint_t sym_call_error          : 1;
     } __attribute__((packed));
 
-    struct v3_sym_context old_ctx;
+    struct v3_sym_core_context old_ctx;
 
     int sym_call_errno;    
 
@@ -92,13 +85,23 @@ struct v3_sym_state {
     uint64_t sym_call_fs;
 };
 
+struct v3_sym_state {
+    
+    struct v3_sym_interface * sym_page;
+    addr_t sym_page_pa;
+
+    uint64_t guest_pg_addr;
+
+    struct v3_symcall_state * symcalls;
+};
+
 
 
 
 
 
 
-int v3_init_sym_iface(struct guest_info * info);
+int v3_init_sym_iface(struct v3_vm_info * vm);
 
 
 typedef uint64_t sym_arg_t;
@@ -119,8 +122,8 @@ typedef uint64_t sym_arg_t;
 
 
 
-int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn);
-int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn);
+int v3_sym_map_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn);
+int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn);
 
 
 /* Symcall numbers */
index e104acc..00f053b 100644 (file)
@@ -65,19 +65,19 @@ static inline int is_swapped_pte32(pte32_t * pte) {
 
 
 
-int v3_init_sym_swap(struct guest_info * info);
+int v3_init_sym_swap(struct v3_vm_info * vm);
 
-int v3_register_swap_disk(struct guest_info * info, int dev_index, 
+int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, 
                          struct v3_swap_ops * ops, void * private_data);
 
-int v3_swap_in_notify(struct guest_info * info, int pg_index, int dev_index);
+int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index);
 
 
 int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms);
-addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * guest_pte);
-addr_t v3_map_swp_page(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr);
+addr_t v3_get_swapped_pg_addr(struct v3_vm_info * vm, pte32_t * guest_pte);
+addr_t v3_map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr);
 
-int v3_swap_flush(struct guest_info * info);
+int v3_swap_flush(struct v3_vm_info * vm);
 
 
 #endif
index 084d90b..88e3cce 100644 (file)
 #include <palacios/vmm_list.h>
 
 struct guest_info;
-
+struct v3_vm_info;
 
 struct v3_telemetry_state {
+    uint32_t invoke_cnt;
+    uint64_t granularity;
 
-    uint64_t vmm_start_tsc;
     uint64_t prev_tsc;
 
+    struct list_head cb_list;
+};
+
+
+struct v3_core_telemetry {
     uint_t exit_cnt;
     struct rb_root exit_root;
 
-    uint32_t invoke_cnt;
-    uint64_t granularity;
+    uint64_t vmm_start_tsc;
 
+    struct v3_telemetry_state * vm_telem;
 
-    struct list_head cb_list;
 };
 
 
-void v3_init_telemetry(struct guest_info * info);
+void v3_init_telemetry(struct v3_vm_info * vm);
+void v3_init_core_telemetry(struct guest_info * info);
 
 void v3_telemetry_start_exit(struct guest_info * info);
 void v3_telemetry_end_exit(struct guest_info * info, uint_t exit_code);
 
-void v3_print_telemetry(struct guest_info * info);
+void v3_print_telemetry(struct v3_vm_info * vm);
 
 
-void v3_add_telemetry_cb(struct guest_info * info, 
-                        void (*telemetry_fn)(struct guest_info * info, void * private_data, char * hdr),
+void v3_add_telemetry_cb(struct v3_vm_info * vm, 
+                        void (*telemetry_fn)(struct v3_vm_info * vm, void * private_data, char * hdr),
                         void * private_data);
 
 #endif
index d254a7f..ff4946a 100644 (file)
@@ -48,8 +48,8 @@ struct vm_time {
 
 
 struct vm_timer_ops {
-    void (*update_time)(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
-
+    void (*update_time)(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
+    void (*advance_timer)(struct guest_info * info, void * private_data);
 };
 
 struct vm_timer {
@@ -65,6 +65,7 @@ struct vm_timer {
 int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data);
 int v3_remove_timer(struct guest_info * info, struct vm_timer * timer);
 
+void v3_advance_time(struct guest_info * info);
 
 void v3_update_time(struct guest_info * info, ullong_t cycles);
 
index b0b105f..62cd3b5 100644 (file)
@@ -24,8 +24,9 @@
 
 struct vmx_exit_info;
 struct guest_info;
+struct v3_vm_info;
 
-int v3_init_vmx_io_map(struct guest_info * info);
+int v3_init_vmx_io_map(struct v3_vm_info * vm);
 
 int v3_handle_vmx_io_in(struct guest_info * info, struct vmx_exit_info * exit_info);
 int v3_handle_vmx_io_ins(struct guest_info * info, struct vmx_exit_info * exit_info);
index 81872e0..9ea6ffb 100644 (file)
@@ -136,9 +136,9 @@ static inline int vmcs_read(vmcs_field_t vmcs_field, void * dst) {
                 VMREAD_OPCODE
                 EAX_ECX_MODRM
                 "seteb %1;" // fail valid
-                "setnaeb %2;" // fail invalid
-                :  "=&c"(val), "=q"(ret_valid), "=q"(ret_invalid) // Use ECX
-                : "a" (vmcs_field), "1"(ret_valid), "2"(ret_invalid)
+                "setnaeb %1;" // fail invalid
+                :  "=c"(val), "=d"(ret_valid) //, "=r"(ret_invalid) // Use ECX
+                : "a" (vmcs_field), "0"(0), "1"(ret_valid)
                 : "memory"
                 );
 
@@ -170,8 +170,8 @@ static inline int vmcs_write(vmcs_field_t vmcs_field, addr_t value) {
                 EAX_ECX_MODRM
                 "seteb %0;" // fail valid (ZF=1)
                 "setnaeb %1;" // fail invalid (CF=1)
-                : "=q" (ret_valid), "=q" (ret_invalid)
-                : "a" (vmcs_field), "c"(value), "0"(ret_valid), "1"(ret_invalid)
+                : "=r" (ret_valid), "=r" (ret_invalid)
+                : "a" (vmcs_field), "c"(value)
                 : "memory");
 
     CHECK_VMXFAIL(ret_valid, ret_invalid);
index ad1d7a9..be30c7f 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <palacios/vm_guest.h>
 
-int v3_init_vmx_msr_map(struct guest_info * info);
+int v3_init_vmx_msr_map(struct v3_vm_info * vm);
 
 #endif
 #endif
index 4b2f4c0..291101e 100644 (file)
@@ -231,8 +231,9 @@ static int handle_crystal_tics(struct vm_device * dev, struct channel * ch, uint
 }
                                
 
+#include <palacios/vm_guest.h>
 
-static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * private_data) {
+static void pit_update_time(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct pit * state = (struct pit *)dev->private_data;
     //  ullong_t tmp_ctr = state->pit_counter;
@@ -296,7 +297,7 @@ static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priva
        if (handle_crystal_tics(dev, &(state->ch_0), oscillations) == 1) {
            // raise interrupt
            PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n");
-           v3_raise_irq(dev->vm, 0);
+           v3_raise_irq(info->vm_info, 0);
        }
 
        //handle_crystal_tics(dev, &(state->ch_1), oscillations);
@@ -310,6 +311,12 @@ static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priva
 }
 
 
+static void pit_advance_time(struct guest_info * core, void * private_data) {
+
+    v3_raise_irq(core->vm_info, 0);
+}
+
+
 
 /* This should call out to handle_SQR_WAVE_write, etc...
  */
@@ -462,7 +469,7 @@ static int handle_channel_cmd(struct channel * ch, struct pit_cmd_word cmd) {
 
 
 
-static int pit_read_channel(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int pit_read_channel(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pit * state = (struct pit *)dev->private_data;
     char * val = (char *)dst;
 
@@ -502,7 +509,7 @@ static int pit_read_channel(ushort_t port, void * dst, uint_t length, struct vm_
 
 
 
-static int pit_write_channel(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int pit_write_channel(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pit * state = (struct pit *)dev->private_data;
     char val = *(char *)src;
 
@@ -544,7 +551,7 @@ static int pit_write_channel(ushort_t port, void * src, uint_t length, struct vm
 
 
 
-static int pit_write_command(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int pit_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pit * state = (struct pit *)dev->private_data;
     struct pit_cmd_word * cmd = (struct pit_cmd_word *)src;
 
@@ -592,6 +599,7 @@ static int pit_write_command(ushort_t port, void * src, uint_t length, struct vm
 
 static struct vm_timer_ops timer_ops = {
     .update_time = pit_update_time,
+    .advance_timer = pit_advance_time,
 };
 
 
@@ -630,11 +638,16 @@ static struct v3_device_ops dev_ops = {
 
 };
 
+#include <palacios/vm_guest.h>
 
-static int pit_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
+static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pit * pit_state = NULL;
     struct vm_device * dev = NULL;
     char * name = v3_cfg_val(cfg, "name");
+    
+    // PIT is only usable in non-multicore environments
+    // just hardcode the core context
+    struct guest_info * info = &(vm->cores[0]);
 
     uint_t cpu_khz = V3_CPU_KHZ();
     ullong_t reload_val = (ullong_t)cpu_khz * 1000;
@@ -644,7 +657,7 @@ static int pit_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
 
     dev = v3_allocate_device(name, &dev_ops, pit_state);
 
-    if (v3_attach_device(info, dev) == -1) {
+    if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", name);
        return -1;
     }
@@ -660,6 +673,7 @@ static int pit_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
     PrintDebug("\n");
 #endif
 
+    
     v3_add_timer(info, &timer_ops, dev);
 
     // Get cpu frequency and calculate the global pit oscilattor counter/cycle
index 443fb0a..e7d59be 100644 (file)
@@ -190,7 +190,7 @@ static void DumpPICState(struct pic_internal *p)
 }
 
 
-static int pic_raise_intr(struct guest_info * info, void * private_data, int irq) {
+static int pic_raise_intr(struct v3_vm_info * vm, void * private_data, int irq) {
     struct pic_internal * state = (struct pic_internal*)private_data;
 
     if (irq == 2) {
@@ -209,13 +209,13 @@ static int pic_raise_intr(struct guest_info * info, void * private_data, int irq
        return -1;
     }
 
-    v3_interrupt_cpu(info, 0);
+    v3_interrupt_cpu(vm, 0);
 
     return 0;
 }
 
 
-static int pic_lower_intr(struct guest_info * info, void * private_data, int irq) {
+static int pic_lower_intr(struct v3_vm_info * vm, void * private_data, int irq) {
     struct pic_internal * state = (struct pic_internal*)private_data;
 
     PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq);
@@ -335,16 +335,16 @@ static int pic_begin_irq(struct guest_info * info, void * private_data, int irq)
 static struct intr_ctrl_ops intr_ops = {
     .intr_pending = pic_intr_pending,
     .get_intr_number = pic_get_intr_number,
-    .raise_intr = pic_raise_intr,
-    .begin_irq = pic_begin_irq,
-    .lower_intr = pic_lower_intr, 
-
+    .begin_irq = pic_begin_irq
 };
 
+static struct intr_router_ops router_ops = {
+    .raise_intr = pic_raise_intr,
+    .lower_intr = pic_lower_intr
+};
 
 
-
-static int read_master_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_master_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
 
     if (length != 1) {
@@ -363,7 +363,7 @@ static int read_master_port1(ushort_t port, void * dst, uint_t length, struct vm
     return 1;
 }
 
-static int read_master_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_master_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
 
     if (length != 1) {
@@ -377,7 +377,7 @@ static int read_master_port2(ushort_t port, void * dst, uint_t length, struct vm
   
 }
 
-static int read_slave_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_slave_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
 
     if (length != 1) {
@@ -396,7 +396,7 @@ static int read_slave_port1(ushort_t port, void * dst, uint_t length, struct vm_
     return 1;
 }
 
-static int read_slave_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
 
     if (length != 1) {
@@ -410,7 +410,7 @@ static int read_slave_port2(ushort_t port, void * dst, uint_t length, struct vm_
 }
 
 
-static int write_master_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_master_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     uchar_t cw = *(uchar_t *)src;
 
@@ -472,7 +472,7 @@ static int write_master_port1(ushort_t port, void * src, uint_t length, struct v
     return 1;
 }
 
-static int write_master_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_master_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     uchar_t cw = *(uchar_t *)src;    
 
@@ -527,7 +527,7 @@ static int write_master_port2(ushort_t port, void * src, uint_t length, struct v
     return 1;
 }
 
-static int write_slave_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_slave_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     uchar_t cw = *(uchar_t *)src;
 
@@ -586,7 +586,7 @@ static int write_slave_port1(ushort_t port, void * src, uint_t length, struct vm
     return 1;
 }
 
-static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_slave_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     uchar_t cw = *(uchar_t *)src;    
 
@@ -643,7 +643,7 @@ static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm
 
 
 
-static int read_elcr_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_elcr_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     
     if (length != 1) {
@@ -665,7 +665,7 @@ static int read_elcr_port(ushort_t port, void * dst, uint_t length, struct vm_de
 }
 
 
-static int write_elcr_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_elcr_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pic_internal * state = (struct pic_internal*)dev->private_data;
     
     if (length != 1) {
@@ -715,11 +715,17 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int pic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+#include <palacios/vm_guest.h>
+
+static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pic_internal * state = NULL;
     state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
     char * name = v3_cfg_val(cfg, "name");
 
+    // PIC is only usable in non-multicore environments
+    // just hardcode the core context
+    struct guest_info * core = &(vm->cores[0]);
+
     V3_ASSERT(state != NULL);
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
@@ -730,7 +736,8 @@ static int pic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     }
 
 
-    v3_register_intr_controller(vm, &intr_ops, state);
+    v3_register_intr_controller(core, &intr_ops, state);
+    v3_register_intr_router(vm, &router_ops, state);
 
     state->master_irr = 0;
     state->master_isr = 0;
index dbce08b..a5847ef 100644 (file)
@@ -1,8 +1,9 @@
 menu "Virtual Devices"
 
 config APIC
-       bool "APIC"
+       bool "APIC" 
        default y
+       depends on ICC_BUS
        help 
          Includes the Virtual APIC device
 
@@ -15,6 +16,29 @@ config DEBUG_APIC
          Enable debugging for the APIC
 
 
+
+config IO_APIC
+       bool "IOAPIC"
+       depends on ICC_BUS
+       default y
+       help 
+         Includes the Virtual IO APIC
+
+config DEBUG_IO_APIC
+       bool "IO APIC Debugging"
+       default n
+       depends on IO_APIC && DEBUG_ON 
+       help 
+         Enable debugging for the IO APIC
+
+
+config ICC_BUS
+       bool "ICC BUS"
+       default y
+       help 
+         The ICC Bus for APIC/IOAPIC communication
+
+
 config BOCHS_DEBUG
        bool "Bochs Debug Console Device"
        default y
@@ -60,20 +84,6 @@ config DEBUG_IDE
          Enable debugging for the IDE Layer
 
 
-config IO_APIC
-       bool "IOAPIC"
-       depends on APIC
-       default y
-       help 
-         Includes the Virtual IO APIC
-
-config DEBUG_IO_APIC
-       bool "IO APIC Debugging"
-       default n
-       depends on IO_APIC && DEBUG_ON 
-       help 
-         Enable debugging for the IO APIC
-
 
 
 
@@ -203,7 +213,7 @@ config PCI
 config PASSTHROUGH_PCI
        bool "Passthrough PCI"
        default y 
-       depends on PCI && EXPERIMENTAL
+       depends on PCI && EXPERIMENTAL && SYMBIOTIC
        help 
          Enables hardware devices to be passed through to the VM
 
index a9b7f54..88c5706 100644 (file)
@@ -1,11 +1,13 @@
 obj-$(CONFIG_APIC) += apic.o
+obj-$(CONFIG_IO_APIC) += io_apic.o
+obj-$(CONFIG_ICC_BUS) += icc_bus.o
 obj-$(CONFIG_PIT) += 8254.o
 obj-$(CONFIG_PIC) += 8259a.o
 obj-$(CONFIG_BOCHS_DEBUG) += bochs_debug.o
 obj-$(CONFIG_GENERIC) += generic.o
 obj-$(CONFIG_I440FX) += i440fx.o
 obj-$(CONFIG_IDE) += ide.o
-obj-$(CONFIG_IO_APIC) += io_apic.o
+
 obj-$(CONFIG_KEYBOARD) += keyboard.o
 obj-$(CONFIG_LINUX_VIRTIO_BALLOON) += lnx_virtio_balloon.o
 obj-$(CONFIG_LINUX_VIRTIO_BLOCK) += lnx_virtio_blk.o
index ccb89e3..7aea038 100644 (file)
 
 #include <devices/apic.h>
 #include <devices/apic_regs.h>
+#include <devices/icc_bus.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_msr.h>
+#include <palacios/vmm_sprintf.h>
 #include <palacios/vm_guest.h>
 
+
 #ifndef CONFIG_DEBUG_APIC
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
@@ -180,11 +183,13 @@ struct apic_state {
   
     uint32_t eoi;
 
+    struct vm_device * icc_bus;
 
+    v3_lock_t  lock;
 };
 
-static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
-static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data);
+static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data);
+static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data);
 
 static void init_apic_state(struct apic_state * apic) {
     apic->base_addr = DEFAULT_BASE_ADDR;
@@ -230,23 +235,31 @@ static void init_apic_state(struct apic_state * apic) {
     apic->ext_apic_feature.val = 0x00040007;
     apic->ext_apic_ctrl.val = 0x00000000;
     apic->spec_eoi.val = 0x00000000;
+
+    v3_lock_init(&(apic->lock));
 }
 
 
 
 
-static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
+static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apics = (struct apic_state *)(dev->private_data);
+    struct apic_state * apic = &(apics[core->cpu_id]);
+
+    v3_lock(apic->lock);
     dst->value = apic->base_addr;
+    v3_unlock(apic->lock);
     return 0;
 }
 
 
-static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
+static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
-    struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, apic->base_addr);
+    struct apic_state * apics = (struct apic_state *)(dev->private_data);
+    struct apic_state * apic = &(apics[core->cpu_id]);
+    struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, core->cpu_id, apic->base_addr);
+
 
     if (old_reg == NULL) {
        // uh oh...
@@ -254,15 +267,19 @@ static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
        return -1;
     }
     
+    v3_lock(apic->lock);
+
     v3_delete_shadow_region(dev->vm, old_reg);
 
     apic->base_addr = src.value;
 
-    if (v3_hook_full_mem(dev->vm, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev) == -1) {
+    if (v3_hook_full_mem(dev->vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev) == -1) {
        PrintError("Could not hook new APIC Base address\n");
+       v3_unlock(apic->lock);
        return -1;
     }
 
+    v3_unlock(apic->lock);
     return 0;
 }
 
@@ -283,7 +300,7 @@ static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) {
     PrintDebug("Raising APIC IRQ %d\n", irq_num);
 
     if (*req_location & flag) {
-       V3_Print("Interrupts coallescing\n");
+       //V3_Print("Interrupts coallescing\n");
     }
 
     if (*en_location & flag) {
@@ -368,7 +385,7 @@ static int apic_do_eoi(struct apic_state * apic) {
        }
 #endif
     } else {
-       PrintError("Spurious EOI...\n");
+       //PrintError("Spurious EOI...\n");
     }
        
     return 0;
@@ -433,9 +450,8 @@ static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_t
 }
 
 
-static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+    struct apic_state * apic = (struct apic_state *)priv_data;
     addr_t reg_addr  = guest_addr - apic->base_addr;
     struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value);
     uint32_t val = 0;
@@ -689,9 +705,11 @@ static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_d
 }
 
 
-static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+/**
+ *
+ */
+static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) {
+    struct apic_state * apic = (struct apic_state *)priv_data;
     addr_t reg_addr  = guest_addr - apic->base_addr;
     struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value);
     uint32_t op_val = *(uint32_t *)src;
@@ -844,7 +862,13 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
            break;
 
        case INT_CMD_LO_OFFSET:
+           apic->int_cmd.lo = op_val;
+           // ICC???
+           v3_icc_send_irq(apic->icc_bus, apic->int_cmd.dst, apic->int_cmd.val);
+           break;
        case INT_CMD_HI_OFFSET:
+           apic->int_cmd.hi = op_val;
+           break;
            // Unhandled Registers
 
        case EXT_APIC_CMD_OFFSET:
@@ -865,8 +889,7 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
 
 // returns 1 if an interrupt is pending, 0 otherwise
 static int apic_intr_pending(struct guest_info * info, void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -879,8 +902,7 @@ static int apic_intr_pending(struct guest_info * info, void * private_data) {
 }
 
 static int apic_get_intr_number(struct guest_info * info, void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -893,28 +915,17 @@ static int apic_get_intr_number(struct guest_info * info, void * private_data) {
     return -1;
 }
 
-static int apic_raise_intr(struct guest_info * info, void * private_data, int irq) {
-#ifdef CONFIG_CRAY_XT
-    // The Seastar is connected directly to the LAPIC via LINT0 on the ICC bus
-
-    if (irq == 238) {
-       struct vm_device * dev = (struct vm_device *)private_data;
-       struct apic_state * apic = (struct apic_state *)dev->private_data;
 
-       return activate_apic_irq(apic, irq);
-    }
-#endif
+static int apic_raise_intr(struct guest_info * info, int irq, void * private_data) {
+  struct apic_state * apic = (struct apic_state *)private_data;
 
-    return 0;
+  return activate_apic_irq(apic, irq);
 }
 
-static int apic_lower_intr(struct guest_info * info, void * private_data, int irq) {
-    return 0;
-}
+
 
 static int apic_begin_irq(struct guest_info * info, void * private_data, int irq) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int major_offset = (irq & ~0x00000007) >> 3;
     int minor_offset = irq & 0x00000007;
     uchar_t * req_location = apic->int_req_reg + major_offset;
@@ -924,36 +935,17 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
     *svc_location |= flag;
     *req_location &= ~flag;
 
-#ifdef CONFIG_CRAY_XT
-    if ((irq == 238) || (irq == 239)) {
-       PrintError("APIC: Begin IRQ %d (ISR=%x), (IRR=%x)\n", irq, *svc_location, *req_location);
-    }
-#endif
-
-    return 0;
-}
-
-
-
-int v3_apic_raise_intr(struct guest_info * info, struct vm_device * apic_dev, int intr_num) {
-    struct apic_state * apic = (struct apic_state *)apic_dev->private_data;
-
-    if (activate_apic_irq(apic, intr_num) == -1) {
-       PrintError("Error: Could not activate apic_irq\n");
-       return -1;
-    } 
 
-    v3_interrupt_cpu(info, 0);
 
     return 0;
 }
 
 
 
+
 /* Timer Functions */
-static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data) {
+    struct apic_state * apic = (struct apic_state *)priv_data;
     // The 32 bit GCC runtime is a pile of shit
 #ifdef __V3_64BIT__
     uint64_t tmr_ticks = 0;
@@ -1019,8 +1011,8 @@ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv
        PrintDebug("Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", 
                   apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
 
-       if (apic_intr_pending(dev->vm, priv_data)) {
-           PrintDebug("Overriding pending IRQ %d\n", apic_get_intr_number(dev->vm, priv_data));
+       if (apic_intr_pending(info, priv_data)) {
+           PrintDebug("Overriding pending IRQ %d\n", apic_get_intr_number(info, priv_data));
        }
 
        if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
@@ -1037,13 +1029,10 @@ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv
 }
 
 
-
 static struct intr_ctrl_ops intr_ops = {
     .intr_pending = apic_intr_pending,
     .get_intr_number = apic_get_intr_number,
-    .raise_intr = apic_raise_intr,
     .begin_irq = apic_begin_irq,
-    .lower_intr = apic_lower_intr, 
 };
 
 
@@ -1055,9 +1044,9 @@ static struct vm_timer_ops timer_ops = {
 
 
 static int apic_free(struct vm_device * dev) {
-    struct guest_info * info = dev->vm;
+    //   struct apic_state * apic = (struct apic_state *)dev->private_data;
 
-    v3_unhook_msr(info, BASE_ADDR_MSR);
+    v3_unhook_msr(dev->vm, BASE_ADDR_MSR);
 
     return 0;
 }
@@ -1072,11 +1061,27 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int apic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static struct v3_icc_ops icc_ops = {
+    .raise_intr = apic_raise_intr,
+};
+
+
+
+static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("Creating APIC\n");
     char * name = v3_cfg_val(cfg, "name");
+    char * icc_name = v3_cfg_val(cfg,"irq_bus");
+    struct vm_device * icc = v3_find_dev(vm, icc_name);
+    int i;
 
-    struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state));
+    if (!icc) {
+        PrintError("Cannot find ICC Bus (%s)\n", icc_name);
+        return -1;
+    }
+
+    // We allocate one apic per core
+    // APICs are accessed via index which correlates with the core's cpu_id 
+    struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state) * vm->num_cores);
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, apic);
 
@@ -1085,15 +1090,23 @@ static int apic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
        return -1;
     }
 
-    v3_register_intr_controller(vm, &intr_ops, dev);
-    v3_add_timer(vm, &timer_ops, dev);
+    
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * core = &(vm->cores[i]);
+
+       v3_register_intr_controller(core, &intr_ops, &(apic[i]));
+       v3_add_timer(core, &timer_ops, &(apic[i]));
+       v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, &(apic[i]));
+
+       v3_icc_register_apic(core, icc, i, &icc_ops, &(apic[i]));
+
+       init_apic_state(&(apic[i]));
+    }
+
 
-    init_apic_state(apic);
 
     v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
 
-    v3_hook_full_mem(vm, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev);
-
     return 0;
 }
 
index ac6ecf0..15e8eec 100644 (file)
@@ -161,7 +161,9 @@ static int atapi_update_data_buf(struct vm_device * dev, struct ide_channel * ch
     return 0;
 }
 
-static int atapi_read10(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_read10(struct guest_info * core, 
+                       struct vm_device * dev, 
+                       struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
     struct atapi_read10_cmd * cmd = (struct atapi_read10_cmd *)(drive->data_buf);
     uint32_t lba =  be_to_le_32(cmd->lba);
@@ -198,7 +200,7 @@ static int atapi_read10(struct vm_device * dev, struct ide_channel * channel) {
     if (channel->features.dma) {
 
        if (channel->dma_status.active == 1) {
-           if (dma_read(dev, channel) == -1) {
+           if (dma_read(core, dev, channel) == -1) {
                PrintError("Error in DMA read for CD Read10 command\n");
                return -1;
            }
@@ -450,7 +452,7 @@ static int atapi_cmd_is_data_op(uint8_t cmd) {
 }
 
 
-static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_handle_packet(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
    struct ide_drive * drive = get_selected_drive(channel);
    uint8_t cmd = drive->data_buf[0];
 
@@ -475,7 +477,7 @@ static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * chan
           break;
 
        case 0x28: // read(10)
-          if (atapi_read10(dev, channel) == -1) {
+          if (atapi_read10(core, dev, channel) == -1) {
               PrintError("IDE: Error in ATAPI read (%x)\n", cmd);
               return -1;
           }
index 4c1ab08..cced2eb 100644 (file)
@@ -43,7 +43,7 @@ struct debug_state {
     uint_t cons_offset;
 };
 
-static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct debug_state * state = (struct debug_state *)dev->private_data;
 
     state->info_buf[state->info_offset++] = *(char*)src;
@@ -58,7 +58,7 @@ static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm
 }
 
 
-static int handle_debug_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct debug_state * state = (struct debug_state *)dev->private_data;
 
     state->debug_buf[state->debug_offset++] = *(char*)src;
@@ -73,7 +73,7 @@ static int handle_debug_write(ushort_t port, void * src, uint_t length, struct v
 }
 
 
-static int handle_console_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct debug_state * state = (struct debug_state *)dev->private_data;
 
     state->cons_buf[state->cons_offset++] = *(char*)src;
@@ -88,7 +88,7 @@ static int handle_console_write(ushort_t port, void * src, uint_t length, struct
 }
 
 
-static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
 
     switch (length) {
        case 1:
@@ -134,7 +134,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct debug_state * state = NULL;
     char * name = v3_cfg_val(cfg, "name");
 
index 75f4526..4ef62b9 100644 (file)
@@ -81,7 +81,7 @@ static struct v3_device_ops dev_ops = {
 };
 
 
-static int connect_fn(struct guest_info * info, 
+static int connect_fn(struct v3_vm_info * vm, 
                      void * frontend_data, 
                      struct v3_dev_blk_ops * ops, 
                      v3_cfg_tree_t * cfg, 
@@ -96,7 +96,7 @@ static int connect_fn(struct guest_info * info,
   model->seek_usecs = seek_time;
   model->private_data = private_data;
 
-  if (v3_dev_connect_blk(info, v3_cfg_val(frontend_cfg, "tag"), 
+  if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
                         &blk_ops, frontend_cfg, model) == -1) {
       PrintError("Could not connect  to frontend %s\n", 
                  v3_cfg_val(frontend_cfg, "tag"));
@@ -106,7 +106,7 @@ static int connect_fn(struct guest_info * info,
   return 0;
 }
 
-static int model_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int model_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     char * name = v3_cfg_val(cfg, "name");
 
index e4a00ff..b30098f 100644 (file)
@@ -76,7 +76,7 @@ static int generic_stop_device(struct vm_device * dev) {
 
 
 
-static int generic_write_port_passthrough(uint16_t port, void * src, 
+static int generic_write_port_passthrough(struct guest_info * core, uint16_t port, void * src, 
                                          uint_t length, struct vm_device * dev) {
     uint_t i;
 
@@ -109,7 +109,7 @@ static int generic_write_port_passthrough(uint16_t port, void * src,
     return length;
 }
 
-static int generic_read_port_passthrough(uint16_t port, void * src, 
+static int generic_read_port_passthrough(struct guest_info * core, uint16_t port, void * src, 
                                         uint_t length, struct vm_device * dev) {
     uint_t i;
 
@@ -143,7 +143,7 @@ static int generic_read_port_passthrough(uint16_t port, void * src,
     return length;
 }
 
-static int generic_write_port_ignore(uint16_t port, void * src, 
+static int generic_write_port_ignore(struct guest_info * core, uint16_t port, void * src, 
                                     uint_t length, struct vm_device * dev) {
     uint_t i;
 
@@ -158,7 +158,7 @@ static int generic_write_port_ignore(uint16_t port, void * src,
     return length;
 }
 
-static int generic_read_port_ignore(uint16_t port, void * src, 
+static int generic_read_port_ignore(struct guest_info * core, uint16_t port, void * src, 
                                    uint_t length, struct vm_device * dev) {
 
     PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
@@ -252,7 +252,7 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene
 
 
 
-static int generic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
     char * name = v3_cfg_val(cfg, "name");
 
index ee4dc80..618a8ca 100644 (file)
@@ -29,12 +29,12 @@ struct i440_state {
 };
 
 
-static int io_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     PrintError("Unhandled read on port %x\n", port);
     return -1;
 }
 
-static int io_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     PrintError("Unhandled write on port %x\n", port);
     return -1;
 }
@@ -57,7 +57,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int i440_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pci_device * pci_dev = NULL;
     struct v3_pci_bar bars[6];
     int i;
diff --git a/palacios/src/devices/icc_bus.c b/palacios/src/devices/icc_bus.c
new file mode 100644 (file)
index 0000000..f5de549
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm_dev_mgr.h>
+#include <palacios/vmm_sprintf.h>
+#include <palacios/vm_guest.h>
+#include <devices/icc_bus.h>
+
+#define MAX_APICS 256
+
+
+struct ipi_thunk_data {
+    struct vm_device * target;
+    uint64_t val;
+};
+
+struct int_cmd_reg {
+    union {
+        uint64_t val;
+
+        struct {
+            uint32_t lo;
+            uint32_t hi;
+        } __attribute__((packed));
+
+        struct {
+            uint_t vec           : 8;
+            uint_t msg_type      : 3;
+            uint_t dst_mode      : 1;
+            uint_t del_status    : 1;
+            uint_t rsvd1         : 1;
+            uint_t lvl           : 1;
+            uint_t trig_mode     : 1;
+            uint_t rem_rd_status : 2;
+            uint_t dst_shorthand : 2;
+            uint64_t rsvd2       : 36;
+            uint32_t dst         : 8;
+        } __attribute__((packed));
+    } __attribute__((packed));
+} __attribute__((packed));
+
+
+
+
+struct apic_data {
+    struct guest_info * core;
+    struct v3_icc_ops * ops;
+    
+    void * priv_data;
+    int present;
+};
+
+
+struct icc_bus_state {
+    struct apic_data apics[MAX_APICS];
+};
+
+static struct v3_device_ops dev_ops = {
+    .free = NULL,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+
+int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num) {
+    struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data;
+    struct apic_data * apic = &(state->apics[apic_num]);    
+
+
+    struct int_cmd_reg icr;
+    icr.lo = irq_num;
+
+
+    char * type = NULL;
+    char * dest = NULL;
+    char foo[8];
+
+    switch (icr.dst_shorthand) {
+       case 0x0:
+           sprintf(foo, "%d", icr.dst);
+           dest = foo;
+           break;
+       case 0x1:
+           dest = "(self)";
+           break;
+       case 0x2:
+           dest = "(broadcast inclusive)";
+           break;
+       case 0x3:
+           dest = "(broadcast)";
+           break;
+    }
+
+    switch (icr.msg_type) {
+       case 0x0:
+           type = "";
+           break;
+       case 0x4:
+           type = "(NMI)";
+           break;
+       case 0x5:
+           type = "(INIT)";
+           break;
+       case 0x6:
+           type = "(Startup)";
+           break;
+    }
+
+
+    PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n", 
+              type, dest, V3_Get_CPU(), apic_num);
+
+    apic->ops->raise_intr(apic->core, irq_num & 0xff, apic->priv_data);
+
+    //V3_Call_On_CPU(apic_num,  icc_force_exit, (void *)(uint64_t)(val & 0xff));
+
+    return 0;
+}
+
+
+
+/* THIS IS A BIG ASSUMPTION: APIC PHYSID == LOGID == CORENUM */
+
+int v3_icc_register_apic(struct guest_info  * core, struct vm_device * icc_bus, 
+                        uint8_t apic_num, struct v3_icc_ops * ops, void * priv_data) {
+    struct icc_bus_state * icc = (struct icc_bus_state *)icc_bus->private_data;
+    struct apic_data * apic = &(icc->apics[apic_num]);
+
+    if (apic->present == 1) {
+       PrintError("Attempt to re-register apic %u\n", apic_num);
+       return -1;
+    }
+    
+    apic->present = 1;
+    apic->priv_data = priv_data;
+    apic->core = core;
+    apic->ops = ops;
+   
+    PrintDebug("Registered apic%u\n", apic_num);
+
+    return 0;
+}
+
+
+
+
+static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    PrintDebug("Creating ICC_BUS\n");
+
+    char * name = v3_cfg_val(cfg, "name");
+
+    struct icc_bus_state * icc_bus = (struct icc_bus_state *)V3_Malloc(sizeof(struct icc_bus_state));
+    memset(icc_bus, 0, sizeof(struct icc_bus_state));
+
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, icc_bus);
+
+    if (v3_attach_device(vm, dev) == -1) {
+        PrintError("Could not attach device %s\n", name);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+
+device_register("ICC_BUS", icc_bus_init)
index 246b1d4..30ff174 100644 (file)
@@ -343,8 +343,8 @@ static void ide_abort_command(struct vm_device * dev, struct ide_channel * chann
 }
 
 
-static int dma_read(struct vm_device * dev, struct ide_channel * channel);
-static int dma_write(struct vm_device * dev, struct ide_channel * channel);
+static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
+static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
 
 
 /* ATAPI functions */
@@ -387,7 +387,7 @@ static void print_prd_table(struct vm_device * dev, struct ide_channel * channel
 #endif
 
 /* IO Operations */
-static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
+static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
     // This is at top level scope to do the EOT test at the end
     struct ide_dma_prd prd_entry;
@@ -411,7 +411,7 @@ static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
 
        PrintDebug("PRD table address = %x\n", channel->dma_prd_addr);
 
-       ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
+       ret = read_guest_pa_memory(core, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
 
        if (ret != sizeof(struct ide_dma_prd)) {
            PrintError("Could not read PRD\n");
@@ -459,7 +459,7 @@ static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
 
            drive->current_lba++;
 
-           ret = write_guest_pa_memory(dev->vm, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf); 
+           ret = write_guest_pa_memory(core, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf); 
 
            if (ret != bytes_to_write) {
                PrintError("Failed to copy data into guest memory... (ret=%d)\n", ret);
@@ -527,7 +527,7 @@ static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
 }
 
 
-static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
+static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
     // This is at top level scope to do the EOT test at the end
     struct ide_dma_prd prd_entry;
@@ -545,7 +545,7 @@ static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
        
        PrintDebug("PRD Table address = %x\n", channel->dma_prd_addr);
 
-       ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
+       ret = read_guest_pa_memory(core, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
 
        if (ret != sizeof(struct ide_dma_prd)) {
            PrintError("Could not read PRD\n");
@@ -564,7 +564,7 @@ static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
            bytes_to_write = (prd_bytes_left > HD_SECTOR_SIZE) ? HD_SECTOR_SIZE : prd_bytes_left;
 
 
-           ret = read_guest_pa_memory(dev->vm, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf);
+           ret = read_guest_pa_memory(core, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf);
 
            if (ret != bytes_to_write) {
                PrintError("Faild to copy data from guest memory... (ret=%d)\n", ret);
@@ -627,7 +627,7 @@ static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
 
 #define DMA_CHANNEL_FLAG  0x08
 
-static int write_dma_port(ushort_t port, void * src, uint_t length, void * private_data) {
+static int write_dma_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
@@ -648,13 +648,13 @@ static int write_dma_port(ushort_t port, void * src, uint_t length, void * priva
 
                if (channel->dma_cmd.read == 1) {
                    // DMA Read
-                   if (dma_read(dev, channel) == -1) {
+                   if (dma_read(core, dev, channel) == -1) {
                        PrintError("Failed DMA Read\n");
                        return -1;
                    }
                } else {
                    // DMA write
-                   if (dma_write(dev, channel) == -1) {
+                   if (dma_write(core, dev, channel) == -1) {
                        PrintError("Failed DMA Write\n");
                        return -1;
                    }
@@ -710,7 +710,7 @@ static int write_dma_port(ushort_t port, void * src, uint_t length, void * priva
 }
 
 
-static int read_dma_port(ushort_t port, void * dst, uint_t length, void * private_data) {
+static int read_dma_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
@@ -764,7 +764,7 @@ static int read_dma_port(ushort_t port, void * dst, uint_t length, void * privat
 
 
 
-static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     struct ide_channel * channel = get_selected_channel(ide, port);
     struct ide_drive * drive = get_selected_drive(channel);
@@ -865,7 +865,7 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
 
            if (channel->dma_status.active == 1) {
                // DMA Read
-               if (dma_read(dev, channel) == -1) {
+               if (dma_read(core, dev, channel) == -1) {
                    PrintError("Failed DMA Read\n");
                    return -1;
                }
@@ -888,7 +888,7 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
 
            if (channel->dma_status.active == 1) {
                // DMA Write
-               if (dma_write(dev, channel) == -1) {
+               if (dma_write(core, dev, channel) == -1) {
                    PrintError("Failed DMA Write\n");
                    return -1;
                }
@@ -967,7 +967,7 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
 }
 
 
-static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     struct ide_channel * channel = get_selected_channel(ide, port);
     struct ide_drive * drive = get_selected_drive(channel);
@@ -986,7 +986,7 @@ static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_d
                return -1;
                
            case 0xa0: // ATAPI packet command
-               if (atapi_handle_packet(dev, channel) == -1) {
+               if (atapi_handle_packet(core, dev, channel) == -1) {
                    PrintError("Error handling ATAPI packet\n");
                    return -1;
                }
@@ -1133,7 +1133,7 @@ static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, st
 }
 
 
-static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_drive_id( uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
 
     channel->status.busy = 0;
@@ -1155,7 +1155,7 @@ static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, s
 }
 
 
-static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     struct ide_channel * channel = get_selected_channel(ide, port);
     struct ide_drive * drive = get_selected_drive(channel);
@@ -1184,7 +1184,7 @@ static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct v
     return length;
 }
 
-static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     struct ide_channel * channel = get_selected_channel(ide, port);
     struct ide_drive * drive = get_selected_drive(channel);
@@ -1267,7 +1267,7 @@ static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_de
 }
 
 
-static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
     struct ide_channel * channel = get_selected_channel(ide, port);
     struct ide_drive * drive = get_selected_drive(channel);
@@ -1444,7 +1444,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int connect_fn(struct guest_info * info, 
+static int connect_fn(struct v3_vm_info * vm, 
                      void * frontend_data, 
                      struct v3_dev_blk_ops * ops, 
                      v3_cfg_tree_t * cfg, 
@@ -1500,7 +1500,6 @@ static int connect_fn(struct guest_info * info,
        return -1;
     }
  
-
     drive->ops = ops;
 
     if (ide->ide_pci) {
@@ -1516,7 +1515,7 @@ static int connect_fn(struct guest_info * info,
 
 
 
-static int ide_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
     char * name = v3_cfg_val(cfg, "name");
 
index 95392d0..be69bbc 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
-#include <devices/apic.h>
+#include <devices/icc_bus.h>
 #include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_IO_APIC
@@ -135,8 +135,7 @@ struct io_apic_state {
   
     struct redir_tbl_entry redir_tbl[24];
 
-    // This is a temporary method of communication between the IOAPIC and the LAPIC
-    struct vm_device * apic;
+    struct vm_device * icc_bus;
   
 };
 
@@ -158,7 +157,7 @@ static void init_ioapic_state(struct io_apic_state * ioapic) {
 }
 
 
-static int ioapic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+static int ioapic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
@@ -202,7 +201,7 @@ static int ioapic_read(addr_t guest_addr, void * dst, uint_t length, void * priv
 }
 
 
-static int ioapic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
+static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
@@ -253,21 +252,8 @@ static int ioapic_write(addr_t guest_addr, void * src, uint_t length, void * pri
     return length;
 }
 
-/* Interrupt controller functions */
-static int ioapic_intr_pending(struct guest_info * info, void * private_data) {
-    return 0;
-}
-
-
-static int ioapic_get_intr_number(struct guest_info * info, void * private_data) {
-    return 0;
-}
-
-static int ioapic_begin_irq(struct guest_info * info, void * private_data, int irq) {
-    return 0;
-}
 
-static int ioapic_raise_irq(struct guest_info * info, void * private_data, int irq) {
+static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);  
     struct redir_tbl_entry * irq_entry = NULL;
@@ -281,22 +267,19 @@ static int ioapic_raise_irq(struct guest_info * info, void * private_data, int i
 
     if (irq_entry->mask == 0) {
        PrintDebug("IOAPIC Signalling APIC to raise INTR %d\n", irq_entry->vec);
-       v3_apic_raise_intr(info, ioapic->apic, irq_entry->vec);
+       v3_icc_send_irq(ioapic->icc_bus, irq_entry->dst_field, irq_entry->vec);
     }
 
     return 0;
 }
 
 /* I don't know if we can do anything here.... */
-static int ioapic_lower_irq(struct guest_info * info, void * private_data, int irq) {
+static int ioapic_lower_irq(struct v3_vm_info * vm, void * private_data, int irq) {
     return 0;
 }
 
-static struct intr_ctrl_ops intr_ops = {
-    .intr_pending = ioapic_intr_pending,
-    .get_intr_number = ioapic_get_intr_number,
+static struct intr_router_ops router_ops = {
     .raise_intr = ioapic_raise_irq,
-    .begin_irq = ioapic_begin_irq,
     .lower_intr = ioapic_lower_irq, 
 };
 
@@ -319,12 +302,12 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
-    struct vm_device * apic = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus"));
+static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * icc_bus = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus"));
     char * name = v3_cfg_val(cfg, "name");
 
-    if (!apic) {
-       PrintError("Could not locate APIC device (%s)\n", v3_cfg_val(cfg, "irq_bus"));
+    if (!icc_bus) {
+       PrintError("Could not locate ICC BUS device (%s)\n", v3_cfg_val(cfg, "irq_bus"));
        return -1;
     }
 
@@ -332,7 +315,7 @@ static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
 
     struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state));
 
-    ioapic->apic = apic;
+    ioapic->icc_bus = icc_bus;
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, ioapic);
 
@@ -343,10 +326,10 @@ static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     }
 
 
-    v3_register_intr_controller(vm, &intr_ops, dev);
+    v3_register_intr_router(vm, &router_ops, dev);
     init_ioapic_state(ioapic);
 
-    v3_hook_full_mem(vm, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
+    v3_hook_full_mem(vm, V3_MEM_CORE_ANY, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
                     ioapic_read, ioapic_write, dev);
   
     return 0;
index eb76cc9..08844e2 100644 (file)
@@ -320,7 +320,7 @@ static int pull_from_output_queue(struct vm_device * dev, uint8_t * value) {
 #include <palacios/vmm_telemetry.h>
 
 
-static int key_event_handler(struct guest_info * info, 
+static int key_event_handler(struct v3_vm_info * vm, 
                             struct v3_keyboard_event * evt, 
                             void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
@@ -329,7 +329,10 @@ static int key_event_handler(struct guest_info * info,
     PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", evt->status, evt->scan_code);
 
     if (evt->scan_code == 0x44) { // F10 debug dump
-       v3_print_guest_state(info);
+       int i = 0;
+       for (i = 0; i < vm->num_cores; i++) {
+           v3_print_guest_state(&(vm->cores[i]));
+       }
        //      PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
     } 
 #ifdef CONFIG_SYMBIOTIC
@@ -340,8 +343,16 @@ static int key_event_handler(struct guest_info * info,
        sym_arg_t a2 = 0x3333;
        sym_arg_t a3 = 0x4444;
        sym_arg_t a4 = 0x5555;
+       uint64_t call_start = 0;
+       uint64_t call_end = 0;
+       
+       V3_Print("Exits before symcall: %d\n", (uint32_t)info->num_exits);
 
+       rdtscll(call_start);
        v3_sym_call5(info, SYMCALL_TEST, &a0, &a1, &a2, &a3, &a4);
+       rdtscll(call_end);
+       
+       V3_Print("Symcall latency = %d cycles (%d exits)\n", (uint32_t)(call_end - call_start), (uint32_t)info->num_exits);
 
        V3_Print("Symcall  Test Returned arg0=%x, arg1=%x, arg2=%x, arg3=%x, arg4=%x\n",
                 (uint32_t)a0, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4);
@@ -354,8 +365,9 @@ static int key_event_handler(struct guest_info * info,
        PrintDebug("Toggling Debugging\n");     
        v3_dbg_enable ^= 1;
     } else if (evt->scan_code == 0x41) { // F7 telemetry dump
-       v3_print_telemetry(info);
-       
+#ifdef CONFIG_TELEMETRY
+       v3_print_telemetry(vm);
+#endif
     }
 
 
@@ -374,7 +386,7 @@ static int key_event_handler(struct guest_info * info,
 }
 
 
-static int mouse_event_handler(struct guest_info * info, 
+static int mouse_event_handler(struct v3_vm_info * vm, 
                               struct v3_mouse_event * evt, 
                               void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
@@ -593,7 +605,7 @@ static int keyboard_write_delay(ushort_t port, void * src,  uint_t length, struc
     }
 }
 
-static int keyboard_read_delay(ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int keyboard_read_delay(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
 
     if (length == 1) { 
        *(uint8_t *)dest = v3_inb(port);
@@ -613,7 +625,7 @@ static int keyboard_read_delay(ushort_t port, void * dest, uint_t length, struct
 
 
 
-static int keyboard_write_command(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int keyboard_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
     uint8_t cmd = *(uint8_t *)src;
 
@@ -786,7 +798,7 @@ static int keyboard_write_command(ushort_t port, void * src, uint_t length, stru
     return length;
 }
 
-static int keyboard_read_status(ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int keyboard_read_status(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
     struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
 
     if (length != 1) { 
@@ -807,7 +819,7 @@ static int keyboard_read_status(ushort_t port, void * dest, uint_t length, struc
     return length;
 }
 
-static int keyboard_write_output(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int keyboard_write_output(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
     int ret = length;
 
@@ -942,7 +954,7 @@ static int keyboard_write_output(ushort_t port, void * src, uint_t length, struc
     return ret;
 }
 
-static int keyboard_read_input(ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int keyboard_read_input(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
     struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
 
     if (length != 1) {
@@ -991,7 +1003,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int keyboard_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct keyboard_internal * keyboard_state = NULL;
     char * name = v3_cfg_val(cfg, "name");
 
index 088cea4..c5b621e 100644 (file)
@@ -121,7 +121,7 @@ static int get_desc_count(struct virtio_queue * q, int index) {
 }
 
 
-static int handle_kick(struct vm_device * dev) {
+static int handle_kick(struct guest_info * core, struct vm_device * dev) {
     struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;    
     struct virtio_queue * q = virtio->cur_queue;
 
@@ -142,12 +142,13 @@ static int handle_kick(struct vm_device * dev) {
            addr_t page_addr;
            tmp_desc = &(q->desc[desc_idx]);
            
-           PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", tmp_desc, 
-                      (void *)(tmp_desc->addr_gpa), tmp_desc->length, 
+           PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", 
+                      tmp_desc, 
+                      (void *)(addr_t)(tmp_desc->addr_gpa), tmp_desc->length, 
                       tmp_desc->flags, tmp_desc->next);
        
 
-           if (guest_pa_to_host_va(dev->vm, tmp_desc->addr_gpa, (addr_t *)&(page_addr)) == -1) {
+           if (guest_pa_to_host_va(core, tmp_desc->addr_gpa, (addr_t *)&(page_addr)) == -1) {
                PrintError("Could not translate block header address\n");
                return -1;
            }
@@ -184,7 +185,7 @@ static int handle_kick(struct vm_device * dev) {
     return 0;
 }
 
-static int virtio_io_write(uint16_t port, void * src, uint_t length, void * private_data) {
+static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
     int port_idx = port % virtio->io_range_size;
@@ -222,19 +223,19 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
                // round up to next page boundary.
                virtio->cur_queue->ring_used_addr = (virtio->cur_queue->ring_used_addr + 0xfff) & ~0xfff;
 
-               if (guest_pa_to_host_va(dev->vm, virtio->cur_queue->ring_desc_addr, (addr_t *)&(virtio->cur_queue->desc)) == -1) {
+               if (guest_pa_to_host_va(core, virtio->cur_queue->ring_desc_addr, (addr_t *)&(virtio->cur_queue->desc)) == -1) {
                    PrintError("Could not translate ring descriptor address\n");
                    return -1;
                }
 
 
-               if (guest_pa_to_host_va(dev->vm, virtio->cur_queue->ring_avail_addr, (addr_t *)&(virtio->cur_queue->avail)) == -1) {
+               if (guest_pa_to_host_va(core, virtio->cur_queue->ring_avail_addr, (addr_t *)&(virtio->cur_queue->avail)) == -1) {
                    PrintError("Could not translate ring available address\n");
                    return -1;
                }
 
 
-               if (guest_pa_to_host_va(dev->vm, virtio->cur_queue->ring_used_addr, (addr_t *)&(virtio->cur_queue->used)) == -1) {
+               if (guest_pa_to_host_va(core, virtio->cur_queue->ring_used_addr, (addr_t *)&(virtio->cur_queue->used)) == -1) {
                    PrintError("Could not translate ring used address\n");
                    return -1;
                }
@@ -266,7 +267,7 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
            break;
        case VRING_Q_NOTIFY_PORT:
            PrintDebug("Handling Kick\n");
-           if (handle_kick(dev) == -1) {
+           if (handle_kick(core, dev) == -1) {
                PrintError("Could not handle Balloon Notification\n");
                return -1;
            }
@@ -293,7 +294,7 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
 }
 
 
-static int virtio_io_read(uint16_t port, void * dst, uint_t length, void * private_data) {
+static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
     int port_idx = port % virtio->io_range_size;
@@ -415,7 +416,7 @@ static int handle_query_hcall(struct guest_info * info, uint_t hcall_id, void *
 
 
 
-static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_balloon_state * virtio_state = NULL;
     struct pci_device * pci_dev = NULL;
index a129c7f..de77354 100644 (file)
@@ -81,7 +81,6 @@ struct blk_op_hdr {
 struct virtio_dev_state {
     struct vm_device * pci_bus;
     struct list_head dev_list;
-    struct guest_info * vm;
 };
 
 struct virtio_blk_state {
@@ -159,12 +158,12 @@ static int handle_write_op(struct virtio_blk_state * blk_state, uint8_t * buf, u
 
 // multiple block operations need to increment the sector 
 
-static int handle_block_op(struct virtio_blk_state * blk_state, struct blk_op_hdr * hdr, 
+static int handle_block_op(struct guest_info * core, struct virtio_blk_state * blk_state, struct blk_op_hdr * hdr, 
                           struct vring_desc * buf_desc, uint8_t * status) {
     uint8_t * buf = NULL;
 
     PrintDebug("Handling Block op\n");
-    if (guest_pa_to_host_va(blk_state->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
+    if (guest_pa_to_host_va(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
        PrintError("Could not translate buffer address\n");
        return -1;
     }
@@ -210,7 +209,7 @@ static int get_desc_count(struct virtio_queue * q, int index) {
 
 
 
-static int handle_kick(struct virtio_blk_state * blk_state) {  
+static int handle_kick(struct guest_info * core, struct virtio_blk_state * blk_state) {  
     struct virtio_queue * q = &(blk_state->queue);
 
     PrintDebug("VIRTIO KICK: cur_index=%d (mod=%d), avail_index=%d\n", 
@@ -242,7 +241,7 @@ static int handle_kick(struct virtio_blk_state * blk_state) {
        PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", hdr_desc, 
                   (void *)(hdr_desc->addr_gpa), hdr_desc->length, hdr_desc->flags, hdr_desc->next);    
 
-       if (guest_pa_to_host_va(blk_state->virtio_dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
+       if (guest_pa_to_host_va(core, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
            PrintError("Could not translate block header address\n");
            return -1;
        }
@@ -262,7 +261,7 @@ static int handle_kick(struct virtio_blk_state * blk_state) {
            PrintDebug("Buffer Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", buf_desc, 
                       (void *)(buf_desc->addr_gpa), buf_desc->length, buf_desc->flags, buf_desc->next);
 
-           if (handle_block_op(blk_state, &hdr, buf_desc, &tmp_status) == -1) {
+           if (handle_block_op(core, blk_state, &hdr, buf_desc, &tmp_status) == -1) {
                PrintError("Error handling block operation\n");
                return -1;
            }
@@ -280,7 +279,7 @@ static int handle_kick(struct virtio_blk_state * blk_state) {
        PrintDebug("Status Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", status_desc, 
                   (void *)(status_desc->addr_gpa), status_desc->length, status_desc->flags, status_desc->next);
 
-       if (guest_pa_to_host_va(blk_state->virtio_dev->vm, status_desc->addr_gpa, (addr_t *)&(status_ptr)) == -1) {
+       if (guest_pa_to_host_va(core, status_desc->addr_gpa, (addr_t *)&(status_ptr)) == -1) {
            PrintError("Could not translate status address\n");
            return -1;
        }
@@ -304,7 +303,7 @@ static int handle_kick(struct virtio_blk_state * blk_state) {
     return 0;
 }
 
-static int virtio_io_write(uint16_t port, void * src, uint_t length, void * private_data) {
+static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
     struct virtio_blk_state * blk_state = (struct virtio_blk_state *)private_data;
     int port_idx = port % blk_state->io_range_size;
 
@@ -342,19 +341,19 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
                // round up to next page boundary.
                blk_state->queue.ring_used_addr = (blk_state->queue.ring_used_addr + 0xfff) & ~0xfff;
 
-               if (guest_pa_to_host_va(blk_state->virtio_dev->vm, blk_state->queue.ring_desc_addr, (addr_t *)&(blk_state->queue.desc)) == -1) {
+               if (guest_pa_to_host_va(core, blk_state->queue.ring_desc_addr, (addr_t *)&(blk_state->queue.desc)) == -1) {
                    PrintError("Could not translate ring descriptor address\n");
                    return -1;
                }
 
 
-               if (guest_pa_to_host_va(blk_state->virtio_dev->vm, blk_state->queue.ring_avail_addr, (addr_t *)&(blk_state->queue.avail)) == -1) {
+               if (guest_pa_to_host_va(core, blk_state->queue.ring_avail_addr, (addr_t *)&(blk_state->queue.avail)) == -1) {
                    PrintError("Could not translate ring available address\n");
                    return -1;
                }
 
 
-               if (guest_pa_to_host_va(blk_state->virtio_dev->vm, blk_state->queue.ring_used_addr, (addr_t *)&(blk_state->queue.used)) == -1) {
+               if (guest_pa_to_host_va(core, blk_state->queue.ring_used_addr, (addr_t *)&(blk_state->queue.used)) == -1) {
                    PrintError("Could not translate ring used address\n");
                    return -1;
                }
@@ -384,7 +383,7 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
            break;
        case VRING_Q_NOTIFY_PORT:
            PrintDebug("Handling Kick\n");
-           if (handle_kick(blk_state) == -1) {
+           if (handle_kick(core, blk_state) == -1) {
                PrintError("Could not handle Block Notification\n");
                return -1;
            }
@@ -411,7 +410,7 @@ static int virtio_io_write(uint16_t port, void * src, uint_t length, void * priv
 }
 
 
-static int virtio_io_read(uint16_t port, void * dst, uint_t length, void * private_data) {
+static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
     struct virtio_blk_state * blk_state = (struct virtio_blk_state *)private_data;
     int port_idx = port % blk_state->io_range_size;
 
@@ -579,7 +578,7 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_blk_stat
 }
 
 
-static int connect_fn(struct guest_info * info, 
+static int connect_fn(struct v3_vm_info * vm, 
                      void * frontend_data, 
                      struct v3_dev_blk_ops * ops, 
                      v3_cfg_tree_t * cfg, 
@@ -604,7 +603,7 @@ static int connect_fn(struct guest_info * info,
 }
 
 
-static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_dev_state * virtio_state = NULL;
     char * name = v3_cfg_val(cfg, "name");
@@ -622,7 +621,7 @@ static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
 
     INIT_LIST_HEAD(&(virtio_state->dev_list));
     virtio_state->pci_bus = pci_bus;
-    virtio_state->vm = vm;
+
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
index 0f76641..a21bdb8 100644 (file)
@@ -108,7 +108,7 @@ struct virtio_net_state {
 #if 1
 //Temporarly for debug
 static void print_packet(uchar_t *pkt, int size) {
-    PrintDebug("Vnet: print_data_packet: size: %d\n", size);
+    PrintDebug("Virtio Nic: print_data_packet: size: %d\n", size);
     v3_hexdump(pkt, size, NULL, 0);
 }
 
@@ -124,7 +124,11 @@ static int send(uint8_t * buf, uint32_t count, void * private_data, struct vm_de
    struct virtio_net_state *virtio_state = (struct virtio_net_state *)private_data;
 
    if (virtio_state == temp_net_states[0])
-       __virtio_dev_send(buf, count, temp_net_states[1]);
+       __virtio_dev_send(buf, count, temp_net_states[1]);
+   if (virtio_state == temp_net_states[1]){ //return a RARP packet
+       __virtio_dev_send(buf, count, temp_net_states[0]);
+   }
    
    return count;
 }
@@ -179,7 +183,7 @@ static int pkt_write(struct virtio_net_state * virtio, struct vring_desc * buf_d
     uint8_t * buf = NULL;
     uint32_t len = buf_desc->length;
 
-    PrintDebug("Handling Virtio Net write, net_state: %p\n", virtio);
+    PrintDebug("Virtio NIC: Handling Virtio Write, net_state: %p\n", virtio);
 
     if (guest_pa_to_host_va(virtio->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
        PrintError("Could not translate buffer address\n");
@@ -247,7 +251,7 @@ static int send_pkt_to_guest(struct virtio_net_state * virtio, uchar_t * buf, ui
     PrintDebug("VIRTIO NIC:  sending packet to net_state %p, size:%d", virtio, size);
 
     if (!raw) {
-       data_len -= hdr_len;
+       data_len -= hdr_len;
     }
 
     build_receive_header(&hdr, buf, 1);
@@ -296,6 +300,10 @@ static int send_pkt_to_guest(struct virtio_net_state * virtio, uchar_t * buf, ui
            //       if there still is some data left
            //buf_desc->flags = VIRTIO_NEXT_FLAG;
         
+           
+           PrintError("JACK: copying packet to up desc (len = %d)\n", data_len - offset);
+           v3_hexdump(buf + offset, data_len - offset, NULL, 0);
+
            len = copy_data_to_desc(virtio, buf_desc, buf + offset, data_len - offset);
            
            offset += len;
@@ -306,10 +314,12 @@ static int send_pkt_to_guest(struct virtio_net_state * virtio, uchar_t * buf, ui
            }
 
            buf_desc->length = len;  // TODO: do we need this?
+           PrintError("JACK: setting buffer descriptor length to %d)\n", buf_desc->length);
        }
+
        
        q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
-       q->used->ring[q->used->index % q->queue_size].length = data_len; // What do we set this to????
+       q->used->ring[q->used->index % q->queue_size].length = data_len + hdr_len; // This should be the total length of data sent to guest (header+pkt_data)
 
        q->used->index++;
        q->cur_avail_idx++;
@@ -321,6 +331,8 @@ static int send_pkt_to_guest(struct virtio_net_state * virtio, uchar_t * buf, ui
        virtio->virtio_cfg.pci_isr = 0x1;
     }
 
+
+    PrintError("\n\n\n\n");
     return offset;
 }
 
index 852709e..2cd3745 100644 (file)
@@ -115,8 +115,9 @@ static int handle_kick(struct vm_device * dev) {
            addr_t page_addr;
            tmp_desc = &(q->desc[desc_idx]);
            
-           PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", tmp_desc, 
-                      (void *)(tmp_desc->addr_gpa), tmp_desc->length, 
+           PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", 
+                      tmp_desc, 
+                      (void *)(addr_t)(tmp_desc->addr_gpa), tmp_desc->length, 
                       tmp_desc->flags, tmp_desc->next);
        
 
index 565c183..fb9b319 100644 (file)
@@ -457,7 +457,7 @@ static void update_time( struct vm_device * dev, uint_t period_us) {
 }
 
 
-static int handle_timer_event(struct guest_info * info, 
+static int handle_timer_event(struct v3_vm_info * vm, 
                              struct v3_timer_event * evt, 
                              void * priv_data) {
 
@@ -592,8 +592,8 @@ static void init_harddrives(struct nvram_internal * nvram) {
     }
 }
 
-static int init_nvram_state(struct vm_device * dev) {
-    struct guest_info * info = dev->vm;
+static int init_nvram_state(struct v3_vm_info * vm, struct vm_device * dev) {
+
     struct nvram_internal * nvram = (struct nvram_internal *)dev->private_data;
   
     memset(nvram->mem_state, 0, NVRAM_REG_MAX);
@@ -672,7 +672,7 @@ static int init_nvram_state(struct vm_device * dev) {
     nvram->us = 0;
     nvram->pus = 0;
 
-    set_memory_size(nvram, info->mem_size);
+    set_memory_size(nvram, vm->mem_size);
     init_harddrives(nvram);
     
     nvram->dev_state = NVRAM_READY;
@@ -707,10 +707,8 @@ static int nvram_stop_device(struct vm_device * dev) {
 
 
 
-static int nvram_write_reg_port(ushort_t port,
-                               void * src, 
-                               uint_t length,
-                               struct vm_device * dev) {
+static int nvram_write_reg_port(struct guest_info * core, ushort_t port,
+                               void * src, uint_t length, struct vm_device * dev) {
 
     struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
     
@@ -720,10 +718,8 @@ static int nvram_write_reg_port(ushort_t port,
     return 1;
 }
 
-static int nvram_read_data_port(ushort_t port,
-                               void * dst, 
-                               uint_t length,
-                               struct vm_device * dev) {
+static int nvram_read_data_port(struct guest_info * core, ushort_t port,
+                               void * dst, uint_t length, struct vm_device * dev) {
 
     struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
 
@@ -750,10 +746,8 @@ static int nvram_read_data_port(ushort_t port,
 }
 
 
-static int nvram_write_data_port(ushort_t port,
-                                void * src, 
-                                uint_t length,
-                                struct vm_device * dev) {
+static int nvram_write_data_port(struct guest_info * core, ushort_t port,
+                                void * src, uint_t length, struct vm_device * dev) {
 
     struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
 
@@ -794,7 +788,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int nvram_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int nvram_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct nvram_internal * nvram_state = NULL;
     struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage"));
     char * name = v3_cfg_val(cfg, "name");
@@ -819,7 +813,7 @@ static int nvram_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
        return -1;
     }
 
-    init_nvram_state(dev);
+    init_nvram_state(vm, dev);
 
     // hook ports
     v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
index a51dc19..4d7e19a 100644 (file)
@@ -35,7 +35,7 @@ struct debug_state {
 };
 
 
-static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct debug_state * state = (struct debug_state *)dev->private_data;
 
     state->debug_buf[state->debug_offset++] = *(char*)src;
@@ -103,7 +103,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct debug_state * state = NULL;
     char * name = v3_cfg_val(cfg, "name");
 
index 06ccb6b..8266167 100644 (file)
@@ -33,6 +33,8 @@
 #include <devices/pci.h>
 #include <devices/pci_types.h>
 
+#include <palacios/vm_guest.h>
+
 
 
 #ifndef CONFIG_DEBUG_PCI
@@ -226,7 +228,7 @@ static struct pci_device * get_device(struct pci_bus * bus, uint8_t dev_num, uin
 
 
 
-static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int addr_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
     int reg_offset = port & 0x3;
     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
@@ -257,7 +259,7 @@ static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_de
 }
 
 
-static int addr_port_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int addr_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
     int reg_offset = port & 0x3; 
     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
@@ -295,7 +297,7 @@ static int addr_port_write(ushort_t port, void * src, uint_t length, struct vm_d
 }
 
 
-static int data_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * vmdev) {
+static int data_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * vmdev) {
     struct pci_internal * pci_state =  (struct pci_internal *)(vmdev->private_data);
     struct pci_device * pci_dev = NULL;
     uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
@@ -393,7 +395,6 @@ static inline int is_cfg_reg_writable(uchar_t header_type, int reg_num) {
     }
 }
 
-
 static int bar_update(struct guest_info * info, struct pci_device * pci, int bar_num, uint32_t new_val) {
     struct v3_pci_bar * bar = &(pci->bar[bar_num]);
 
@@ -418,15 +419,15 @@ static int bar_update(struct guest_info * info, struct pci_device * pci, int bar
                PrintDebug("Rehooking PCI IO port (old port=%u) (new port=%u)\n",  
                           PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
 
-               v3_unhook_io_port(info, PCI_IO_BASE(bar->val) + i);
+               v3_unhook_io_port(info->vm_info, PCI_IO_BASE(bar->val) + i);
 
-               if (v3_hook_io_port(info, PCI_IO_BASE(new_val) + i, 
+               if (v3_hook_io_port(info->vm_info, PCI_IO_BASE(new_val) + i, 
                                    bar->io_read, bar->io_write, 
                                    bar->private_data) == -1) {
 
                    PrintError("Could not hook PCI IO port (old port=%u) (new port=%u)\n",  
                               PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
-                   v3_print_io_map(info);
+                   v3_print_io_map(info->vm_info);
                    return -1;
                }
            }
@@ -436,10 +437,10 @@ static int bar_update(struct guest_info * info, struct pci_device * pci, int bar
            break;
        }
        case PCI_BAR_MEM32: {
-           v3_unhook_mem(info, (addr_t)(bar->val));
+           v3_unhook_mem(info->vm_info, V3_MEM_CORE_ANY, (addr_t)(bar->val));
            
            if (bar->mem_read) {
-               v3_hook_full_mem(info, PCI_MEM32_BASE(new_val), 
+               v3_hook_full_mem(info->vm_info, V3_MEM_CORE_ANY, PCI_MEM32_BASE(new_val), 
                                 PCI_MEM32_BASE(new_val) + (bar->num_pages * PAGE_SIZE_4KB),
                                 bar->mem_read, bar->mem_write, pci->priv_data);
            } else {
@@ -465,7 +466,7 @@ static int bar_update(struct guest_info * info, struct pci_device * pci, int bar
 }
 
 
-static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_device * vmdev) {
+static int data_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * vmdev) {
     struct pci_internal * pci_state = (struct pci_internal *)vmdev->private_data;
     struct pci_device * pci_dev = NULL;
     uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
@@ -573,7 +574,7 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d
                    // check special flags....
 
                    // bar_update
-                   if (bar_update(vmdev->vm, pci_dev, i, *(uint32_t *)(pci_dev->config_space + bar_offset)) == -1) {
+                   if (bar_update(core, pci_dev, i, *(uint32_t *)(pci_dev->config_space + bar_offset)) == -1) {
                        PrintError("PCI Device %s: Bar update Error Bar=%d\n", pci_dev->name, i);
                        return -1;
                    }
@@ -651,7 +652,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int pci_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
     int i = 0;
     char * name = v3_cfg_val(cfg, "name");
@@ -685,7 +686,7 @@ static int pci_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
 device_register("PCI", pci_init)
 
 
-static inline int init_bars(struct guest_info * info, struct pci_device * pci_dev) {
+static inline int init_bars(struct v3_vm_info * vm, struct pci_device * pci_dev) {
     int i = 0;
 
     for (i = 0; i < 6; i++) {
@@ -706,7 +707,7 @@ static inline int init_bars(struct guest_info * info, struct pci_device * pci_de
            for (j = 0; j < pci_dev->bar[i].num_ports; j++) {
                // hook IO
                if (pci_dev->bar[i].default_base_port != 0xffff) {
-                   if (v3_hook_io_port(info, pci_dev->bar[i].default_base_port + j,
+                   if (v3_hook_io_port(vm, pci_dev->bar[i].default_base_port + j,
                                        pci_dev->bar[i].io_read, pci_dev->bar[i].io_write, 
                                        pci_dev->bar[i].private_data) == -1) {
                        PrintError("Could not hook default io port %x\n", pci_dev->bar[i].default_base_port + j);
@@ -730,7 +731,7 @@ static inline int init_bars(struct guest_info * info, struct pci_device * pci_de
            // hook memory
            if (pci_dev->bar[i].mem_read) {
                // full hook
-               v3_hook_full_mem(info, pci_dev->bar[i].default_base_addr,
+               v3_hook_full_mem(vm, V3_MEM_CORE_ANY, pci_dev->bar[i].default_base_addr,
                                 pci_dev->bar[i].default_base_addr + (pci_dev->bar[i].num_pages * PAGE_SIZE_4KB),
                                 pci_dev->bar[i].mem_read, pci_dev->bar[i].mem_write, pci_dev->priv_data);
            } else if (pci_dev->bar[i].mem_write) {
index a799e1f..4ccbba3 100644 (file)
@@ -548,10 +548,10 @@ static int irq_handler(struct guest_info * info, struct v3_interrupt * intr, voi
 
 
 
-static int passthrough_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
+static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pt_dev_state * state = V3_Malloc(sizeof(struct pt_dev_state));
     struct vm_device * dev = NULL;
-    struct vm_device * pci = v3_find_dev(info, v3_cfg_val(cfg, "bus"));
+    struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     char * name = v3_cfg_val(cfg, "name");    
 
     memset(state, 0, sizeof(struct pt_dev_state));
@@ -567,7 +567,7 @@ static int passthrough_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
 
     dev = v3_allocate_device(name, &dev_ops, state);
 
-    if (v3_attach_device(info, dev) == -1) {
+    if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", name);
        return -1;
     }
@@ -582,9 +582,9 @@ static int passthrough_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
        return 0;
     }
 
-    setup_virt_pci_dev(info, dev);
+    setup_virt_pci_dev(vm, dev);
 
-    v3_hook_irq(info, atoi(v3_cfg_val(cfg, "irq")), irq_handler, dev);
+    v3_hook_irq(vm, atoi(v3_cfg_val(cfg, "irq")), irq_handler, dev);
     //    v3_hook_irq(info, 64, irq_handler, dev);
 
     return 0;
index 377c845..493e3c5 100644 (file)
@@ -445,7 +445,7 @@ static int setup_pci(struct vm_device * dev) {
     return 0;
 }
 
-static int piix3_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int piix3_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge));
     struct vm_device * dev = NULL;
     struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
index 9a2e716..8930620 100644 (file)
@@ -86,7 +86,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int disk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct disk_state * disk = NULL;
     struct v3_cfg_file * file = NULL;
     char * name = v3_cfg_val(cfg, "name");
index 3946636..f67ca85 100644 (file)
@@ -571,7 +571,7 @@ static int connect_fn(struct guest_info * info,
        swap->active = 0;
 
        swap->cache_base_addr = (addr_t)V3_AllocPages(swap->cache_size / 4096);
-       swap->cache = (uint8_t *)V3_VAddr((void *)(swap->cache_base_addr));
+       swap->cache = (uint8_t *)V3_VAddr((void *)(addr_t)(swap->cache_base_addr));
        memset(swap->cache, 0, swap->cache_size);
     }
 
index b573cf6..1a917ab 100644 (file)
@@ -96,7 +96,7 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int blk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int blk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct blk_state * blk = NULL;
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
     char * name = v3_cfg_val(cfg, "name");
index acb5353..1a1cf35 100644 (file)
@@ -67,7 +67,7 @@ static vmcb_t * Allocate_VMCB() {
 
 
 
-static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
+static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * core) {
     vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
     uint_t i;
@@ -125,37 +125,37 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
 
     /* Setup Guest Machine state */
 
-    vm_info->vm_regs.rsp = 0x00;
-    vm_info->rip = 0xfff0;
+    core->vm_regs.rsp = 0x00;
+    core->rip = 0xfff0;
 
-    vm_info->vm_regs.rdx = 0x00000f00;
+    core->vm_regs.rdx = 0x00000f00;
 
 
-    vm_info->cpl = 0;
+    core->cpl = 0;
 
-    vm_info->ctrl_regs.rflags = 0x00000002; // The reserved bit is always 1
-    vm_info->ctrl_regs.cr0 = 0x60010010; // Set the WP flag so the memory hooks work in real-mode
-    vm_info->ctrl_regs.efer |= EFER_MSR_svm_enable;
+    core->ctrl_regs.rflags = 0x00000002; // The reserved bit is always 1
+    core->ctrl_regs.cr0 = 0x60010010; // Set the WP flag so the memory hooks work in real-mode
+    core->ctrl_regs.efer |= EFER_MSR_svm_enable;
 
 
 
 
 
-    vm_info->segments.cs.selector = 0xf000;
-    vm_info->segments.cs.limit = 0xffff;
-    vm_info->segments.cs.base = 0x0000000f0000LL;
+    core->segments.cs.selector = 0xf000;
+    core->segments.cs.limit = 0xffff;
+    core->segments.cs.base = 0x0000000f0000LL;
 
     // (raw attributes = 0xf3)
-    vm_info->segments.cs.type = 0x3;
-    vm_info->segments.cs.system = 0x1;
-    vm_info->segments.cs.dpl = 0x3;
-    vm_info->segments.cs.present = 1;
+    core->segments.cs.type = 0x3;
+    core->segments.cs.system = 0x1;
+    core->segments.cs.dpl = 0x3;
+    core->segments.cs.present = 1;
 
 
 
-    struct v3_segment * segregs [] = {&(vm_info->segments.ss), &(vm_info->segments.ds), 
-                                     &(vm_info->segments.es), &(vm_info->segments.fs), 
-                                     &(vm_info->segments.gs), NULL};
+    struct v3_segment * segregs [] = {&(core->segments.ss), &(core->segments.ds), 
+                                     &(core->segments.es), &(core->segments.fs), 
+                                     &(core->segments.gs), NULL};
 
     for ( i = 0; segregs[i] != NULL; i++) {
        struct v3_segment * seg = segregs[i];
@@ -172,31 +172,28 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
        seg->present = 1;
     }
 
-    vm_info->segments.gdtr.limit = 0x0000ffff;
-    vm_info->segments.gdtr.base = 0x0000000000000000LL;
-    vm_info->segments.idtr.limit = 0x0000ffff;
-    vm_info->segments.idtr.base = 0x0000000000000000LL;
+    core->segments.gdtr.limit = 0x0000ffff;
+    core->segments.gdtr.base = 0x0000000000000000LL;
+    core->segments.idtr.limit = 0x0000ffff;
+    core->segments.idtr.base = 0x0000000000000000LL;
 
-    vm_info->segments.ldtr.selector = 0x0000;
-    vm_info->segments.ldtr.limit = 0x0000ffff;
-    vm_info->segments.ldtr.base = 0x0000000000000000LL;
-    vm_info->segments.tr.selector = 0x0000;
-    vm_info->segments.tr.limit = 0x0000ffff;
-    vm_info->segments.tr.base = 0x0000000000000000LL;
+    core->segments.ldtr.selector = 0x0000;
+    core->segments.ldtr.limit = 0x0000ffff;
+    core->segments.ldtr.base = 0x0000000000000000LL;
+    core->segments.tr.selector = 0x0000;
+    core->segments.tr.limit = 0x0000ffff;
+    core->segments.tr.base = 0x0000000000000000LL;
 
 
-    vm_info->dbg_regs.dr6 = 0x00000000ffff0ff0LL;
-    vm_info->dbg_regs.dr7 = 0x0000000000000400LL;
+    core->dbg_regs.dr6 = 0x00000000ffff0ff0LL;
+    core->dbg_regs.dr7 = 0x0000000000000400LL;
 
 
-    v3_init_svm_io_map(vm_info);
-    ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr(vm_info->io_map.arch_data);
+    ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr(core->vm_info->io_map.arch_data);
     ctrl_area->instrs.IOIO_PROT = 1;
-
-
-    v3_init_svm_msr_map(vm_info);
-    ctrl_area->MSRPM_BASE_PA = (addr_t)V3_PAddr(vm_info->msr_map.arch_data);
-    ctrl_area->instrs.MSR_PROT = 1;
+           
+    ctrl_area->MSRPM_BASE_PA = (addr_t)V3_PAddr(core->vm_info->msr_map.arch_data);
+    ctrl_area->instrs.MSR_PROT = 1;   
 
 
     PrintDebug("Exiting on interrupts\n");
@@ -204,7 +201,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
     ctrl_area->instrs.INTR = 1;
 
 
-    if (vm_info->shdw_pg_mode == SHADOW_PAGING) {
+    if (core->shdw_pg_mode == SHADOW_PAGING) {
        PrintDebug("Creating initial shadow page table\n");
        
        /* JRL: This is a performance killer, and a simplistic solution */
@@ -213,17 +210,17 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
        ctrl_area->guest_ASID = 1;
        
        
-       if (v3_init_passthrough_pts(vm_info) == -1) {
+       if (v3_init_passthrough_pts(core) == -1) {
            PrintError("Could not initialize passthrough page tables\n");
            return ;
        }
 
 
-       vm_info->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
+       core->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
        PrintDebug("Created\n");
        
-       vm_info->ctrl_regs.cr0 |= 0x80000000;
-       vm_info->ctrl_regs.cr3 = vm_info->direct_map_pt;
+       core->ctrl_regs.cr0 |= 0x80000000;
+       core->ctrl_regs.cr3 = core->direct_map_pt;
 
        ctrl_area->cr_reads.cr0 = 1;
        ctrl_area->cr_writes.cr0 = 1;
@@ -232,10 +229,10 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
        ctrl_area->cr_reads.cr3 = 1;
        ctrl_area->cr_writes.cr3 = 1;
 
-       v3_hook_msr(vm_info, EFER_MSR, 
+       v3_hook_msr(core->vm_info, EFER_MSR, 
                    &v3_handle_efer_read,
                    &v3_handle_efer_write, 
-                   vm_info);
+                   core);
 
        ctrl_area->instrs.INVLPG = 1;
 
@@ -245,7 +242,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
 
 
 
-    } else if (vm_info->shdw_pg_mode == NESTED_PAGING) {
+    } else if (core->shdw_pg_mode == NESTED_PAGING) {
        // Flush the TLB on entries/exits
        ctrl_area->TLB_CONTROL = 1;
        ctrl_area->guest_ASID = 1;
@@ -256,12 +253,12 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
        PrintDebug("NP_Enable at 0x%p\n", (void *)&(ctrl_area->NP_ENABLE));
 
        // Set the Nested Page Table pointer
-       if (v3_init_passthrough_pts(vm_info) == -1) {
+       if (v3_init_passthrough_pts(core) == -1) {
            PrintError("Could not initialize Nested page tables\n");
            return ;
        }
 
-       ctrl_area->N_CR3 = vm_info->direct_map_pt;
+       ctrl_area->N_CR3 = core->direct_map_pt;
 
        guest_state->g_pat = 0x7040600070406ULL;
     }
@@ -289,25 +286,25 @@ int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class) {
 static int update_irq_exit_state(struct guest_info * info) {
     vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
 
-    if ((info->intr_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) {
+    if ((info->intr_core_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) {
        
 #ifdef CONFIG_DEBUG_INTERRUPTS
-       PrintDebug("INTAK cycle completed for irq %d\n", info->intr_state.irq_vector);
+       PrintDebug("INTAK cycle completed for irq %d\n", info->intr_core_state.irq_vector);
 #endif
 
-       info->intr_state.irq_started = 1;
-       info->intr_state.irq_pending = 0;
+       info->intr_core_state.irq_started = 1;
+       info->intr_core_state.irq_pending = 0;
 
-       v3_injecting_intr(info, info->intr_state.irq_vector, V3_EXTERNAL_IRQ);
+       v3_injecting_intr(info, info->intr_core_state.irq_vector, V3_EXTERNAL_IRQ);
     }
 
-    if ((info->intr_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 0)) {
+    if ((info->intr_core_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 0)) {
 #ifdef CONFIG_DEBUG_INTERRUPTS
-       PrintDebug("Interrupt %d taken by guest\n", info->intr_state.irq_vector);
+       PrintDebug("Interrupt %d taken by guest\n", info->intr_core_state.irq_vector);
 #endif
 
        // Interrupt was taken fully vectored
-       info->intr_state.irq_started = 0;
+       info->intr_core_state.irq_started = 0;
 
     } else {
 #ifdef CONFIG_DEBUG_INTERRUPTS
@@ -348,12 +345,12 @@ static int update_irq_entry_state(struct guest_info * info) {
 #endif
 
        v3_injecting_excp(info, excp);
-    } else if (info->intr_state.irq_started == 1) {
+    } else if (info->intr_core_state.irq_started == 1) {
 #ifdef CONFIG_DEBUG_INTERRUPTS
        PrintDebug("IRQ pending from previous injection\n");
 #endif
        guest_ctrl->guest_ctrl.V_IRQ = 1;
-       guest_ctrl->guest_ctrl.V_INTR_VECTOR = info->intr_state.irq_vector;
+       guest_ctrl->guest_ctrl.V_INTR_VECTOR = info->intr_core_state.irq_vector;
        guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
        guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
 
@@ -373,8 +370,8 @@ static int update_irq_entry_state(struct guest_info * info) {
                           (void *)(addr_t)info->rip);
 #endif
 
-               info->intr_state.irq_pending = 1;
-               info->intr_state.irq_vector = irq;
+               info->intr_core_state.irq_pending = 1;
+               info->intr_core_state.irq_vector = irq;
                
                break;
            }
@@ -439,7 +436,7 @@ int v3_svm_enter(struct guest_info * info) {
     guest_state->rsp = info->vm_regs.rsp;
 
 #ifdef CONFIG_SYMBIOTIC
-    if (info->sym_state.sym_call_active == 0) {
+    if (info->vm_info->sym_state.symcalls[info->cpu_id].sym_call_active == 0) {
        update_irq_entry_state(info);
     }
 #else 
@@ -456,7 +453,7 @@ int v3_svm_enter(struct guest_info * info) {
     */
 
 #ifdef CONFIG_SYMBIOTIC
-    if (info->sym_state.sym_call_active == 1) {
+    if (info->vm_info->sym_state.symcalls[info->cpu_id].sym_call_active == 1) {
        if (guest_ctrl->guest_ctrl.V_IRQ == 1) {
            V3_Print("!!! Injecting Interrupt during Sym call !!!\n");
        }
@@ -466,13 +463,15 @@ int v3_svm_enter(struct guest_info * info) {
 
     rdtscll(info->time_state.cached_host_tsc);
     guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+
+    //V3_Print("Calling v3_svm_launch\n");
        
     v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]);
     
+    //V3_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip);
 
-    v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
 
-    //  v3_print_cond("SVM Returned: Exit Code: %x\n", (uint32_t)(guest_ctrl->exit_code));
+    v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
 
     rdtscll(tmp_tsc);
 
@@ -513,7 +512,7 @@ int v3_svm_enter(struct guest_info * info) {
 
 
 #ifdef CONFIG_SYMBIOTIC
-    if (info->sym_state.sym_call_active == 0) {
+    if (info->vm_info->sym_state.symcalls[info->cpu_id].sym_call_active == 0) {
        update_irq_exit_state(info);
     }
 #else
@@ -548,7 +547,7 @@ int v3_start_svm_guest(struct guest_info *info) {
     PrintDebug("Launching SVM VM (vmcb=%p)\n", (void *)info->vmm_data);
     //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
     
-    info->run_state = VM_RUNNING;
+    info->vm_info->run_state = VM_RUNNING;
     rdtscll(info->yield_start_cycle);
 
 
@@ -558,7 +557,7 @@ int v3_start_svm_guest(struct guest_info *info) {
            addr_t host_addr;
            addr_t linear_addr = 0;
            
-           info->run_state = VM_ERROR;
+           info->vm_info->run_state = VM_ERROR;
            
            V3_Print("SVM ERROR!!\n"); 
            
index dbca7a8..2c6034c 100644 (file)
@@ -43,7 +43,7 @@
 int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_info1, addr_t exit_info2) {
 
 #ifdef CONFIG_TELEMETRY
-    if (info->enable_telemetry) {
+    if (info->vm_info->enable_telemetry) {
        v3_telemetry_start_exit(info);
     }
 #endif
@@ -282,7 +282,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i
     // END OF SWITCH (EXIT_CODE)
 
 #ifdef CONFIG_TELEMETRY
-    if (info->enable_telemetry) {
+    if (info->vm_info->enable_telemetry) {
        v3_telemetry_end_exit(info, exit_code);
     }
 #endif
index 1ec4a60..d9ce73c 100644 (file)
@@ -17,6 +17,7 @@
  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
  */
 
+
 #include <palacios/svm_io.h>
 #include <palacios/vmm_io.h>
 #include <palacios/vmm_ctrl_regs.h>
@@ -29,8 +30,8 @@
 #endif
 
 
-static int update_map(struct guest_info * info, uint16_t port, int hook_read, int hook_write) {
-    uchar_t * bitmap = (uint8_t *)(info->io_map.arch_data);;
+static int update_map(struct v3_vm_info * vm, uint16_t port, int hook_read, int hook_write) {
+    uchar_t * bitmap = (uint8_t *)(vm->io_map.arch_data);;
     int major = port / 8;
     int minor = port % 8;
 
@@ -44,14 +45,14 @@ static int update_map(struct guest_info * info, uint16_t port, int hook_read, in
 }
 
 
-int v3_init_svm_io_map(struct guest_info * info) {
-    info->io_map.update_map = update_map;
+int v3_init_svm_io_map(struct v3_vm_info * vm) {
+    vm->io_map.update_map = update_map;
 
-    info->io_map.arch_data = V3_VAddr(V3_AllocPages(3));
-    memset(info->io_map.arch_data, 0, PAGE_SIZE_4KB * 3);
+    vm->io_map.arch_data = V3_VAddr(V3_AllocPages(3));
+    memset(vm->io_map.arch_data, 0, PAGE_SIZE_4KB * 3);
 
 
-    v3_refresh_io_map(info);
+    v3_refresh_io_map(vm);
 
     return 0;
 }
@@ -59,8 +60,8 @@ int v3_init_svm_io_map(struct guest_info * info) {
 
 
 // This should package up an IO request and call vmm_handle_io
-int v3_handle_svm_io_in(struct guest_info * info, struct svm_io_info * io_info) {
-    struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+int v3_handle_svm_io_in(struct guest_info * core, struct svm_io_info * io_info) {
+    struct v3_io_hook * hook = v3_get_io_hook(core->vm_info, io_info->port);
     int read_size = 0;
 
     if (hook == NULL) {
@@ -80,7 +81,7 @@ int v3_handle_svm_io_in(struct guest_info * info, struct svm_io_info * io_info)
 
     PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_info->port, io_info->port);
 
-    if (hook->read(io_info->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
+    if (hook->read(core, io_info->port, &(core->vm_regs.rax), read_size, hook->priv_data) != read_size) {
        // not sure how we handle errors.....
        PrintError("Read Failure for in on port 0x%x\n", io_info->port);
        return -1;
@@ -96,13 +97,13 @@ int v3_handle_svm_io_in(struct guest_info * info, struct svm_io_info * io_info)
 /* We might not handle wrap around of the RDI register correctly...
  * In that if we do wrap around the effect will manifest in the higher bits of the register
  */
-int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info) {
-    struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+int v3_handle_svm_io_ins(struct guest_info * core, struct svm_io_info * io_info) {
+    struct v3_io_hook * hook = v3_get_io_hook(core->vm_info, io_info->port);
     int read_size = 0;
     addr_t dst_addr = 0;
     uint_t rep_num = 1;
     ullong_t mask = 0;
-    struct v3_segment * theseg = &(info->segments.es); // default is ES
+    struct v3_segment * theseg = &(core->segments.es); // default is ES
     addr_t inst_ptr;
 
 
@@ -110,7 +111,7 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
     // direction can equal either 1 or -1
     // We will multiply the final added offset by this value to go the correct direction
     int direction = 1;
-    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);  
+    struct rflags * flags = (struct rflags *)&(core->ctrl_regs.rflags);  
 
     if (flags->df) {
        direction = -1;
@@ -125,7 +126,7 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
 
 
 
-    if (guest_va_to_host_va(info, get_addr_linear(info, info->rip, &(info->segments.cs)), &inst_ptr) == -1) {
+    if (guest_va_to_host_va(core, get_addr_linear(core, core->rip, &(core->segments.cs)), &inst_ptr) == -1) {
        PrintError("Can't access instruction\n");
        return -1;
     }
@@ -133,22 +134,22 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
     while (is_prefix_byte(*((char *)inst_ptr))) {
        switch (*((char *)inst_ptr)) {
            case PREFIX_CS_OVERRIDE:
-               theseg = &(info->segments.cs);
+               theseg = &(core->segments.cs);
                break;
            case PREFIX_SS_OVERRIDE:
-               theseg = &(info->segments.ss);
+               theseg = &(core->segments.ss);
                break;
            case PREFIX_DS_OVERRIDE:
-               theseg = &(info->segments.ds);
+               theseg = &(core->segments.ds);
                break;
            case PREFIX_ES_OVERRIDE:
-               theseg = &(info->segments.es);
+               theseg = &(core->segments.es);
                break;
            case PREFIX_FS_OVERRIDE:
-               theseg = &(info->segments.fs);
+               theseg = &(core->segments.fs);
                break;
            case PREFIX_GS_OVERRIDE:
-               theseg = &(info->segments.gs);
+               theseg = &(core->segments.gs);
                break;
            default:
                break;
@@ -179,7 +180,7 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
        mask = 0xffffffffffffffffLL;
     } else {
        // This value should be set depending on the host register size...
-       mask = get_gpr_mask(info);
+       mask = get_gpr_mask(core);
 
        PrintDebug("INS io_info invalid address size, mask=0x%p, io_info=0x%p\n",
                   (void *)(addr_t)mask, (void *)(addr_t)(io_info));
@@ -188,7 +189,7 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
     }
 
     if (io_info->rep) {
-       rep_num = info->vm_regs.rcx & mask;
+       rep_num = core->vm_regs.rcx & mask;
        //rep_num = info->vm_regs.rcx;
     }
 
@@ -197,26 +198,26 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
 
     while (rep_num > 0) {
        addr_t host_addr;
-       dst_addr = get_addr_linear(info, (info->vm_regs.rdi & mask), theseg);
+       dst_addr = get_addr_linear(core, (core->vm_regs.rdi & mask), theseg);
     
        //      PrintDebug("Writing 0x%p\n", (void *)dst_addr);
 
-       if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+       if (guest_va_to_host_va(core, dst_addr, &host_addr) == -1) {
            // either page fault or gpf...
            PrintError("Could not convert Guest VA to host VA\n");
            return -1;
        }
 
-       if (hook->read(io_info->port, (char *)host_addr, read_size, hook->priv_data) != read_size) {
+       if (hook->read(core, io_info->port, (char *)host_addr, read_size, hook->priv_data) != read_size) {
            // not sure how we handle errors.....
            PrintError("Read Failure for ins on port 0x%x\n", io_info->port);
            return -1;
        }
 
-       info->vm_regs.rdi += (read_size * direction);
+       core->vm_regs.rdi += (read_size * direction);
 
        if (io_info->rep) {
-           info->vm_regs.rcx--;
+           core->vm_regs.rcx--;
        }
 
        rep_num--;
@@ -225,8 +226,8 @@ int v3_handle_svm_io_ins(struct guest_info * info, struct svm_io_info * io_info)
     return 0;
 }
 
-int v3_handle_svm_io_out(struct guest_info * info, struct svm_io_info * io_info) {
-    struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+int v3_handle_svm_io_out(struct guest_info * core, struct svm_io_info * io_info) {
+    struct v3_io_hook * hook = v3_get_io_hook(core->vm_info, io_info->port);
     int write_size = 0;
 
     if (hook == NULL) {
@@ -246,7 +247,7 @@ int v3_handle_svm_io_out(struct guest_info * info, struct svm_io_info * io_info)
 
     PrintDebug("OUT of %d bytes on  port %d (0x%x)\n", write_size, io_info->port, io_info->port);
 
-    if (hook->write(io_info->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
+    if (hook->write(core, io_info->port, &(core->vm_regs.rax), write_size, hook->priv_data) != write_size) {
        // not sure how we handle errors.....
        PrintError("Write Failure for out on port 0x%x\n", io_info->port);
        return -1;
@@ -260,21 +261,21 @@ int v3_handle_svm_io_out(struct guest_info * info, struct svm_io_info * io_info)
  * In that if we do wrap around the effect will manifest in the higher bits of the register
  */
 
-int v3_handle_svm_io_outs(struct guest_info * info,  struct svm_io_info * io_info) {
+int v3_handle_svm_io_outs(struct guest_info * core, struct svm_io_info * io_info) {
  
-    struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+    struct v3_io_hook * hook = v3_get_io_hook(core->vm_info, io_info->port);
     int write_size = 0;
     addr_t dst_addr = 0;
     uint_t rep_num = 1;
     ullong_t mask = 0;
     addr_t inst_ptr;
-    struct v3_segment * theseg = &(info->segments.es); // default is ES
+    struct v3_segment * theseg = &(core->segments.es); // default is ES
 
     // This is kind of hacky...
     // direction can equal either 1 or -1
     // We will multiply the final added offset by this value to go the correct direction
     int direction = 1;
-    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);  
+    struct rflags * flags = (struct rflags *)&(core->ctrl_regs.rflags);  
 
     if (flags->df) {
        direction = -1;
@@ -306,7 +307,7 @@ int v3_handle_svm_io_outs(struct guest_info * info,  struct svm_io_info * io_inf
        mask = 0xffffffffffffffffLL;
     } else {
        // This value should be set depending on the host register size...
-       mask = get_gpr_mask(info);
+       mask = get_gpr_mask(core);
 
        PrintDebug("OUTS io_info invalid address size, mask=0%p, io_info=0x%p\n",
                   (void *)(addr_t)mask, (void *)(addr_t)io_info);
@@ -318,13 +319,13 @@ int v3_handle_svm_io_outs(struct guest_info * info,  struct svm_io_info * io_inf
     }
 
     if (io_info->rep) {
-       rep_num = info->vm_regs.rcx & mask;
+       rep_num = core->vm_regs.rcx & mask;
     }
 
   
 
 
-    if (guest_va_to_host_va(info, get_addr_linear(info, info->rip, &(info->segments.cs)), &inst_ptr) == -1) {
+    if (guest_va_to_host_va(core, get_addr_linear(core, core->rip, &(core->segments.cs)), &inst_ptr) == -1) {
        PrintError("Can't access instruction\n");
        return -1;
     }
@@ -332,22 +333,22 @@ int v3_handle_svm_io_outs(struct guest_info * info,  struct svm_io_info * io_inf
     while (is_prefix_byte(*((char *)inst_ptr))) {
        switch (*((char *)inst_ptr)) {
            case PREFIX_CS_OVERRIDE:
-               theseg = &(info->segments.cs);
+               theseg = &(core->segments.cs);
                break;
            case PREFIX_SS_OVERRIDE:
-               theseg = &(info->segments.ss);
+               theseg = &(core->segments.ss);
                break;
            case PREFIX_DS_OVERRIDE:
-               theseg = &(info->segments.ds);
+               theseg = &(core->segments.ds);
                break;
            case PREFIX_ES_OVERRIDE:
-               theseg = &(info->segments.es);
+               theseg = &(core->segments.es);
                break;
            case PREFIX_FS_OVERRIDE:
-               theseg = &(info->segments.fs);
+               theseg = &(core->segments.fs);
                break;
            case PREFIX_GS_OVERRIDE:
-               theseg = &(info->segments.gs);
+               theseg = &(core->segments.gs);
                break;
            default:
                break;
@@ -360,22 +361,22 @@ int v3_handle_svm_io_outs(struct guest_info * info,  struct svm_io_info * io_inf
     while (rep_num > 0) {
        addr_t host_addr;
 
-       dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), theseg);
+       dst_addr = get_addr_linear(core, (core->vm_regs.rsi & mask), theseg);
     
-       if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+       if (guest_va_to_host_va(core, dst_addr, &host_addr) == -1) {
            // either page fault or gpf...
        }
 
-       if (hook->write(io_info->port, (char*)host_addr, write_size, hook->priv_data) != write_size) {
+       if (hook->write(core, io_info->port, (char*)host_addr, write_size, hook->priv_data) != write_size) {
            // not sure how we handle errors.....
            PrintError("Write Failure for outs on port 0x%x\n", io_info->port);
            return -1;
        }
 
-       info->vm_regs.rsi += write_size * direction;
+       core->vm_regs.rsi += write_size * direction;
 
        if (io_info->rep) {
-           info->vm_regs.rcx--;
+           core->vm_regs.rcx--;
        }
 
        rep_num--;
index dabe82d..747ec89 100644 (file)
@@ -53,13 +53,13 @@ static int get_bitmap_index(uint_t msr) {
 }
 
 
-static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int hook_writes) {
+static int update_map(struct v3_vm_info * vm, uint_t msr, int hook_reads, int hook_writes) {
     int index = get_bitmap_index(msr);
     uint_t major = index / 4;
     uint_t minor = (index % 4) * 2;
     uchar_t val = 0;
     uchar_t mask = 0x3;
-    uint8_t * bitmap = (uint8_t *)(info->msr_map.arch_data);
+    uint8_t * bitmap = (uint8_t *)(vm->msr_map.arch_data);
 
     if (hook_reads) {
        val |= 0x1;
@@ -76,15 +76,15 @@ static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int
 }
 
 
-int v3_init_svm_msr_map(struct guest_info * info) {
-    struct v3_msr_map * msr_map = &(info->msr_map);
+int v3_init_svm_msr_map(struct v3_vm_info * vm) {
+    struct v3_msr_map * msr_map = &(vm->msr_map);
   
     msr_map->update_map = update_map;
 
     msr_map->arch_data = V3_VAddr(V3_AllocPages(2));  
     memset(msr_map->arch_data, 0, PAGE_SIZE_4KB * 2);
 
-    v3_refresh_msr_map(info);
+    v3_refresh_msr_map(vm);
 
     return 0;
 }
index de0cb21..c2bb07d 100644 (file)
@@ -310,7 +310,7 @@ void v3_print_stack(struct guest_info * info) {
     // We start i at one because the current stack pointer points to an unused stack element
     for (i = 0; i <= 24; i++) {
        if (cpu_mode == LONG) {
-           V3_Print("\t%p\n", (void *)*(uint64_t *)(host_addr + (i * 8)));
+           V3_Print("\t%p\n", (void *)*(addr_t *)(host_addr + (i * 8)));
        } else if (cpu_mode == REAL) {
            V3_Print("Don't currently handle 16 bit stacks... \n");
        } else {
index ca040f7..3f6be1e 100644 (file)
@@ -65,8 +65,8 @@ int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
 
 
 
-int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
-    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(guest_info, guest_pa);
+int guest_pa_to_host_pa(struct guest_info * info, addr_t guest_pa, addr_t * host_pa) {
+    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
 
     if (shdw_reg == NULL) {
        PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n", 
@@ -80,7 +80,7 @@ int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t
        return -1;
     }
     
-    *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+    *host_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
 
     return 0;
 }
index c56356d..3f5fa6c 100644 (file)
@@ -40,12 +40,6 @@ struct v3_os_hooks * os_hooks = NULL;
 int v3_dbg_enable = 0;
 
 
-static struct guest_info * allocate_guest() {
-    void * info = V3_Malloc(sizeof(struct guest_info));
-    memset(info, 0, sizeof(struct guest_info));
-    return info;
-}
-
 
 static void init_cpu(void * arg) {
     uint32_t cpu_id = (uint32_t)(addr_t)arg;
@@ -106,45 +100,46 @@ v3_cpu_arch_t v3_get_cpu_type(int cpu_id) {
 }
 
 
-struct guest_info * v3_create_vm(void * cfg) {
-    struct guest_info * info = allocate_guest();
-    
-    if (!info) {
-       PrintError("Could not allocate Guest\n");
-       return NULL;
-    }
+struct v3_vm_info * v3_create_vm(void * cfg) {
+    struct v3_vm_info * vm = v3_config_guest(cfg);
 
-    if (v3_config_guest(info, cfg) == -1) {
+    if (vm == NULL) {
        PrintError("Could not configure guest\n");
        return NULL;
     }
 
-    return info;
+    return vm;
 }
 
 
-int v3_start_vm(struct guest_info * info, unsigned int cpu_mask) {
-    
-    info->cpu_id = v3_get_cpu_id();
-
+int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) {
+    int i = 0;
     V3_Print("V3 --  Starting VM\n");
 
-    switch (v3_cpu_types[info->cpu_id]) {
+
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * info = &(vm->cores[i]);
+
+       /* GRUESOM HACK... */
+       //      vm->cpu_id = v3_get_cpu_id();
+
+       switch (v3_cpu_types[info->cpu_id]) {
 #ifdef CONFIG_SVM
-       case V3_SVM_CPU:
-       case V3_SVM_REV3_CPU:
-           return v3_start_svm_guest(info);
-           break;
+           case V3_SVM_CPU:
+           case V3_SVM_REV3_CPU:
+               return v3_start_svm_guest(info);
+               break;
 #endif
 #if CONFIG_VMX
-       case V3_VMX_CPU:
-       case V3_VMX_EPT_CPU:
-           return v3_start_vmx_guest(info);
-           break;
+           case V3_VMX_CPU:
+           case V3_VMX_EPT_CPU:
+               return v3_start_vmx_guest(info);
+               break;
 #endif
-       default:
-           PrintError("Attemping to enter a guest on an invalid CPU\n");
-           return -1;
+           default:
+               PrintError("Attemping to enter a guest on an invalid CPU\n");
+               return -1;
+       }
     }
 
     return 0;
@@ -195,7 +190,7 @@ void v3_yield_cond(struct guest_info * info) {
     uint64_t cur_cycle;
     rdtscll(cur_cycle);
 
-    if (cur_cycle > (info->yield_start_cycle + info->yield_cycle_period)) {
+    if (cur_cycle > (info->yield_start_cycle + info->vm_info->yield_cycle_period)) {
 
        /*
          PrintDebug("Conditional Yield (cur_cyle=%p, start_cycle=%p, period=%p)\n", 
@@ -239,11 +234,11 @@ void v3_print_cond(const char * fmt, ...) {
 
 
 
-void v3_interrupt_cpu(struct guest_info * info, int logical_cpu) {
+void v3_interrupt_cpu(struct v3_vm_info * vm, int logical_cpu) {
     extern struct v3_os_hooks * os_hooks;
 
     if ((os_hooks) && (os_hooks)->interrupt_cpu) {
-       (os_hooks)->interrupt_cpu(info, logical_cpu);
+       (os_hooks)->interrupt_cpu(vm, logical_cpu);
     }
 }
 
index 81a37d3..edc0710 100644 (file)
@@ -28,9 +28,9 @@
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_cpuid.h>
 #include <palacios/vmm_xml.h>
+#include <palacios/vmm_io.h>
+#include <palacios/vmm_msr.h>
 
-#include <palacios/svm.h>
-#include <palacios/vmx.h>
 
 #ifdef CONFIG_SYMBIOTIC
 #include <palacios/vmm_sym_iface.h>
 #endif
 
 
+#ifdef CONFIG_SVM
+#include <palacios/svm.h>
+#include <palacios/svm_io.h>
+#include <palacios/svm_msr.h>
+#endif
+
+#ifdef CONFIG_VMX
+#include <palacios/vmx.h>
+#include <palacios/vmx_io.h>
+#include <palacios/vmx_msr.h>
+#endif
+
+
 #include <palacios/vmm_host_events.h>
 #include <palacios/vmm_socket.h>
 
@@ -62,8 +75,9 @@ struct file_idx_table {
 
 
 
-static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr);
-static int setup_devices(struct guest_info * info, struct v3_config * config_ptr);
+static int setup_memory_map(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
+static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
+
 
 
 char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag) {
@@ -91,10 +105,10 @@ v3_cfg_tree_t * v3_cfg_next_branch(v3_cfg_tree_t * tree) {
 
 
 
-struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag) {
+struct v3_cfg_file * v3_cfg_get_file(struct v3_vm_info * vm, char * tag) {
     struct v3_cfg_file * file = NULL;
 
-    file = (struct v3_cfg_file *)v3_htable_search(info->cfg_data->file_table, (addr_t)tag);
+    file = (struct v3_cfg_file *)v3_htable_search(vm->cfg_data->file_table, (addr_t)tag);
 
     return file;
 }
@@ -187,13 +201,12 @@ static struct v3_config * parse_config(void * cfg_blob) {
     return cfg;
 }
 
+static int pre_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * vm_cfg) {
+    v3_cpu_arch_t cpu_type = v3_get_cpu_type(v3_get_cpu_id());
 
-static int pre_config_guest(struct guest_info * info, struct v3_config * config_ptr) {
-    extern v3_cpu_arch_t v3_cpu_types[];
-    char * memory_str = v3_cfg_val(config_ptr->cfg, "memory");
-    char * paging = v3_cfg_val(config_ptr->cfg, "paging");
-    char * schedule_hz_str = v3_cfg_val(config_ptr->cfg, "schedule_hz");
-    char * vm_class = v3_cfg_val(config_ptr->cfg, "class");
+    char * memory_str = v3_cfg_val(vm_cfg, "memory");
+    char * schedule_hz_str = v3_cfg_val(vm_cfg, "schedule_hz");
+    char * vm_class = v3_cfg_val(vm_cfg, "class");
     uint32_t sched_hz = 100;   // set the schedule frequency to 100 HZ
     
     if (!memory_str) {
@@ -204,44 +217,97 @@ static int pre_config_guest(struct guest_info * info, struct v3_config * config_
     PrintDebug("Memory=%s\n", memory_str);
 
     // Amount of ram the Guest will have, always in MB
-    info->mem_size = atoi(memory_str) * 1024 * 1024;
+    vm->mem_size = atoi(memory_str) * 1024 * 1024;
     
     if (strcasecmp(vm_class, "PC") == 0) {
-       info->vm_class = V3_PC_VM;
+       vm->vm_class = V3_PC_VM;
     } else {
        PrintError("Invalid VM class\n");
        return -1;
     }
 
-
-    /*
-     * Initialize the subsystem data strutures
-     */
 #ifdef CONFIG_TELEMETRY
+    v3_init_telemetry(vm);
+
     {
-       char * telemetry = v3_cfg_val(config_ptr->cfg, "telemetry");
+       char * telemetry = v3_cfg_val(vm_cfg, "telemetry");
 
        // This should go first, because other subsystems will depend on the guest_info flag    
        if ((telemetry) && (strcasecmp(telemetry, "enable") == 0)) {
-           info->enable_telemetry = 1;
-           v3_init_telemetry(info);
+           vm->enable_telemetry = 1;
        } else {
-           info->enable_telemetry = 0;
+           vm->enable_telemetry = 0;
        }
     }
 #endif
 
-    v3_init_hypercall_map(info);
-    v3_init_io_map(info);
-    v3_init_msr_map(info);
-    v3_init_cpuid_map(info);
-    v3_init_host_events(info);
+    v3_init_hypercall_map(vm);
+    v3_init_io_map(vm);
+    v3_init_msr_map(vm);
+    v3_init_cpuid_map(vm);
+    v3_init_host_events(vm);
+    v3_init_intr_routers(vm);
 
     // Initialize the memory map
-    if (v3_init_shadow_map(info) == -1) {
+    if (v3_init_mem_map(vm) == -1) {
        PrintError("Could not initialize shadow map\n");
        return -1;
     }
+
+#ifdef CONFIG_SYMBIOTIC
+    v3_init_sym_iface(vm);
+#endif
+
+    v3_init_dev_mgr(vm);
+
+
+#ifdef CONFIG_SYMBIOTIC_SWAP
+    PrintDebug("initializing symbiotic swap\n");
+    v3_init_sym_swap(vm);
+#endif
+
+
+       // init SVM/VMX
+#ifdef CONFIG_SVM
+       if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
+           v3_init_svm_io_map(vm);
+           v3_init_svm_msr_map(vm);
+       }
+#endif
+#ifdef CONFIG_VMX
+       else if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
+           v3_init_vmx_io_map(vm);
+           v3_init_vmx_msr_map(vm);
+       }
+#endif
+       else {
+           PrintError("Invalid CPU Type\n");
+           return -1;
+       }
+
+   if (schedule_hz_str) {
+       sched_hz = atoi(schedule_hz_str);
+    }
+
+    PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), 
+              (void *)(addr_t)sched_hz);
+
+    vm->yield_cycle_period = (V3_CPU_KHZ() * 1000) / sched_hz;
+    
+    return 0;
+}
+
+static int pre_config_core(struct guest_info * info, v3_cfg_tree_t * core_cfg) {
+    extern v3_cpu_arch_t v3_cpu_types[];
+    char * paging = v3_cfg_val(core_cfg, "paging");
+
+    /*
+     * Initialize the subsystem data strutures
+     */
+#ifdef CONFIG_TELEMETRY
+    v3_init_core_telemetry(info);
+#endif
+
     
     if ((v3_cpu_types[info->cpu_id] == V3_SVM_REV3_CPU) && 
        (paging) && (strcasecmp(paging, "nested") == 0)) {
@@ -253,32 +319,18 @@ static int pre_config_guest(struct guest_info * info, struct v3_config * config_
        info->shdw_pg_mode = SHADOW_PAGING;
     }
 
-#ifdef CONFIG_SYMBIOTIC
-    v3_init_sym_iface(info);
-#endif
+
 
     v3_init_time(info);
-    v3_init_interrupt_state(info);
+    v3_init_intr_controllers(info);
     v3_init_exception_state(info);
-    v3_init_dev_mgr(info);
+
     v3_init_decoder(info);
     
-#ifdef CONFIG_SYMBIOTIC_SWAP
-    PrintDebug("initializing symbiotic swap\n");
-    v3_init_sym_swap(info);
-#endif
 
-    if (schedule_hz_str) {
-       sched_hz = atoi(schedule_hz_str);
-    }
 
-    PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), 
-              (void *)(addr_t)sched_hz);
-
-    info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / sched_hz;
-    
-    if (info->vm_class == V3_PC_VM) {
-       if (pre_config_pc(info, config_ptr) == -1) {
+    if (info->vm_info->vm_class == V3_PC_VM) {
+       if (pre_config_pc_core(info, core_cfg) == -1) {
            PrintError("PC Post configuration failure\n");
            return -1;
        }
@@ -291,28 +343,50 @@ static int pre_config_guest(struct guest_info * info, struct v3_config * config_
 }
 
 
-static int post_config_guest(struct guest_info * info, struct v3_config * config_ptr) {
+
+static int post_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    
+    vm->run_state = VM_STOPPED;
 
     // Configure the memory map for the guest
-    if (setup_memory_map(info, config_ptr) == -1) {
+    if (setup_memory_map(vm, cfg) == -1) {
        PrintError("Setting up guest memory map failed...\n");
        return -1;
     }
     
     //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
   
-    if (setup_devices(info, config_ptr) == -1) {
+    if (setup_devices(vm, cfg) == -1) {
        PrintError("Failed to setup devices\n");
        return -1;
     }
 
+
     //    v3_print_io_map(info);
-    v3_print_msr_map(info);
+    v3_print_msr_map(vm);
 
-    info->run_state = VM_STOPPED;
 
-    if (info->vm_class == V3_PC_VM) {
-       if (post_config_pc(info, config_ptr) == -1) {
+    if (vm->vm_class == V3_PC_VM) {
+       if (post_config_pc(vm, cfg) == -1) {
+           PrintError("PC Post configuration failure\n");
+           return -1;
+       }
+    } else {
+       PrintError("Invalid VM Class\n");
+       return -1;
+    }
+
+    return 0;
+}
+
+
+
+static int post_config_core(struct guest_info * info, v3_cfg_tree_t * cfg) {
+
+
+    if (info->vm_info->vm_class == V3_PC_VM) {
+       if (post_config_pc_core(info, cfg) == -1) {
            PrintError("PC Post configuration failure\n");
            return -1;
        }
@@ -327,70 +401,142 @@ static int post_config_guest(struct guest_info * info, struct v3_config * config
 
 
 
-int v3_config_guest(struct guest_info * info, void * cfg_blob) {
+static struct v3_vm_info * allocate_guest(int num_cores) {
+    int guest_state_size = sizeof(struct v3_vm_info) + (sizeof(struct guest_info) * num_cores);
+    struct v3_vm_info * vm = V3_Malloc(guest_state_size);
+
+    memset(vm, 0, guest_state_size);
+
+    vm->num_cores = num_cores;
+
+    return vm;
+}
+
+
+
+struct v3_vm_info * v3_config_guest(void * cfg_blob) {
     v3_cpu_arch_t cpu_type = v3_get_cpu_type(v3_get_cpu_id());
+    struct v3_config * cfg_data = NULL;
+    struct v3_vm_info * vm = NULL;
+    int num_cores = 0;
+    int i = 0;
+    v3_cfg_tree_t * cores_cfg = NULL;
+    v3_cfg_tree_t * per_core_cfg = NULL;
 
     if (cpu_type == V3_INVALID_CPU) {
        PrintError("Configuring guest on invalid CPU\n");
-       return -1;
+       return NULL;
     }
 
-    info->cfg_data = parse_config(cfg_blob);
+    cfg_data = parse_config(cfg_blob);
 
-    if (!info->cfg_data) {
+    if (!cfg_data) {
        PrintError("Could not parse configuration\n");
-       return -1;
+       return NULL;
+    }
+
+    cores_cfg = v3_cfg_subtree(cfg_data->cfg, "cores");
+
+    if (!cores_cfg) {
+       PrintError("Could not find core configuration (new config format required)\n");
+       return NULL;
     }
 
+    num_cores = atoi(v3_cfg_val(cores_cfg, "count"));
+
+    if (num_cores == 0) {
+       PrintError("No cores specified in configuration\n");
+       return NULL;
+    }
+
+    V3_Print("Configuring %d cores\n", num_cores);
+
+    vm = allocate_guest(num_cores);    
+
+    if (!vm) {
+       PrintError("Could not allocate %d core guest\n", vm->num_cores);
+       return NULL;
+    }
+
+    vm->cfg_data = cfg_data;
+
     V3_Print("Preconfiguration\n");
 
-    if (pre_config_guest(info, info->cfg_data) == -1) {
+    if (pre_config_vm(vm, vm->cfg_data->cfg) == -1) {
        PrintError("Error in preconfiguration\n");
-       return -1;
+       return NULL;
     }
 
-    V3_Print("Arch dependent configuration\n");
 
-    // init SVM/VMX
+    V3_Print("Per core configuration\n");
+    per_core_cfg = v3_cfg_subtree(cores_cfg, "core");
+
+    // per core configuration
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * info = &(vm->cores[i]);
+
+       
+       info->cpu_id = i;
+       info->vm_info = vm;
+
+       pre_config_core(info, per_core_cfg);
+
+       // init SVM/VMX
 #ifdef CONFIG_SVM
-    if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
-       if (v3_init_svm_vmcb(info, info->vm_class) == -1) {
-           PrintError("Error in SVM initialization\n");
-           return -1;
+       if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
+           if (v3_init_svm_vmcb(info, vm->vm_class) == -1) {
+               PrintError("Error in SVM initialization\n");
+               return NULL;
+           }
        }
-    } 
 #endif
 #ifdef CONFIG_VMX
-    else if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
-       if (v3_init_vmx_vmcs(info, info->vm_class) == -1) {
-           PrintError("Error in VMX initialization\n");
-           return -1;
+       else if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
+           if (v3_init_vmx_vmcs(info, vm->vm_class) == -1) {
+               PrintError("Error in VMX initialization\n");
+               return NULL;
+           }
        }
-    }
 #endif
-    else {
-       PrintError("Invalid CPU Type\n");
-       return -1;
+       else {
+           PrintError("Invalid CPU Type\n");
+           return NULL;
+       }
+       
+       per_core_cfg = v3_cfg_next_branch(per_core_cfg);
     }
 
+
     V3_Print("Post Configuration\n");
 
-    if (post_config_guest(info, info->cfg_data) == -1) {
+    if (post_config_vm(vm, vm->cfg_data->cfg) == -1) {
        PrintError("Error in postconfiguration\n");
-       return -1;
+       return NULL;
+    }
+
+
+    per_core_cfg = v3_cfg_subtree(cores_cfg, "core");
+
+    // per core configuration
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * info = &(vm->cores[i]);
+
+       post_config_core(info, per_core_cfg);
+
+       per_core_cfg = v3_cfg_next_branch(per_core_cfg);
     }
 
     V3_Print("Configuration successfull\n");
 
-    return 0;
+    return vm;
 }
 
 
 
 
 
-static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr) {
-    v3_cfg_tree_t * mem_region = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "memmap"), "region");
+static int setup_memory_map(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    v3_cfg_tree_t * mem_region = v3_cfg_subtree(v3_cfg_subtree(cfg, "memmap"), "region");
 
     while (mem_region) {
        addr_t start_addr = atox(v3_cfg_val(mem_region, "start"));
@@ -398,7 +544,7 @@ static int setup_memory_map(struct guest_info * info, struct v3_config * config_
        addr_t host_addr = atox(v3_cfg_val(mem_region, "host_addr"));
 
     
-       if (v3_add_shadow_mem(info, start_addr, end_addr, host_addr) == -1) {
+       if (v3_add_shadow_mem(vm, V3_MEM_CORE_ANY, start_addr, end_addr, host_addr) == -1) {
            PrintError("Could not map memory region: %p-%p => %p\n", 
                       (void *)start_addr, (void *)end_addr, (void *)host_addr);
            return -1;
@@ -413,13 +559,8 @@ static int setup_memory_map(struct guest_info * info, struct v3_config * config_
 
 
 
-
-
-
-
-
-static int setup_devices(struct guest_info * info, struct v3_config * config_ptr) {
-    v3_cfg_tree_t * device = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "devices"), "device");
+static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    v3_cfg_tree_t * device = v3_cfg_subtree(v3_cfg_subtree(cfg, "devices"), "device");
 
     
     while (device) {
@@ -427,7 +568,7 @@ static int setup_devices(struct guest_info * info, struct v3_config * config_ptr
 
        V3_Print("configuring device %s\n", id);
 
-       if (v3_create_device(info, id, device) == -1) {
+       if (v3_create_device(vm, id, device) == -1) {
            PrintError("Error creating device %s\n", id);
            return -1;
        }
@@ -435,10 +576,11 @@ static int setup_devices(struct guest_info * info, struct v3_config * config_ptr
        device = v3_cfg_next_branch(device);
     }
 
-
-   v3_print_dev_mgr(info);
+    v3_print_dev_mgr(vm);
 
     return 0;
 }
 
 
+
+
index b2edaee..a0b2ba4 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 
-static int pre_config_pc(struct guest_info * info, struct v3_config * config_ptr) {
+static int pre_config_pc_core(struct guest_info * info, v3_cfg_tree_t * cfg) { 
 
 
     info->cpu_mode = REAL;
@@ -37,7 +37,13 @@ static int pre_config_pc(struct guest_info * info, struct v3_config * config_ptr
     return 0;
 }
 
-static int post_config_pc(struct guest_info * info, struct v3_config * config_ptr) {
+static int post_config_pc_core(struct guest_info * info, v3_cfg_tree_t * cfg) { 
+
+    v3_print_mem_map(info->vm_info);
+    return 0;
+}
+
+static int post_config_pc(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
 #define VGABIOS_START 0x000c0000
 #define ROMBIOS_START 0x000f0000
@@ -47,7 +53,7 @@ static int post_config_pc(struct guest_info * info, struct v3_config * config_pt
        extern uint8_t v3_vgabios_start[];
        extern uint8_t v3_vgabios_end[];
        
-       addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
+       addr_t vgabios_dst = v3_get_shadow_addr(&(vm->mem_map.base_region), V3_MEM_CORE_ANY, VGABIOS_START);
        memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start);     
     }
     
@@ -56,12 +62,10 @@ static int post_config_pc(struct guest_info * info, struct v3_config * config_pt
        extern uint8_t v3_rombios_start[];
        extern uint8_t v3_rombios_end[];
 
-       addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
+       addr_t rombios_dst = v3_get_shadow_addr(&(vm->mem_map.base_region), V3_MEM_CORE_ANY, ROMBIOS_START);
        memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start);
     }
 
-    v3_print_mem_map(info);
-
     return 0;
 }
 
index 34040d8..232531c 100644 (file)
 #include <palacios/vm_guest.h>
 
 
-void v3_init_cpuid_map(struct guest_info * info) {
-    info->cpuid_map.map.rb_node = NULL;
+void v3_init_cpuid_map(struct v3_vm_info * vm) {
+    vm->cpuid_map.map.rb_node = NULL;
 }
 
 
-static inline struct v3_cpuid_hook * __insert_cpuid_hook(struct guest_info * info, struct v3_cpuid_hook * hook) {
-  struct rb_node ** p = &(info->cpuid_map.map.rb_node);
+static inline struct v3_cpuid_hook * __insert_cpuid_hook(struct v3_vm_info * vm, struct v3_cpuid_hook * hook) {
+  struct rb_node ** p = &(vm->cpuid_map.map.rb_node);
   struct rb_node * parent = NULL;
   struct v3_cpuid_hook * tmp_hook = NULL;
 
@@ -51,22 +51,22 @@ static inline struct v3_cpuid_hook * __insert_cpuid_hook(struct guest_info * inf
 }
 
 
-static inline struct v3_cpuid_hook * insert_cpuid_hook(struct guest_info * info, struct v3_cpuid_hook * hook) {
+static inline struct v3_cpuid_hook * insert_cpuid_hook(struct v3_vm_info * vm, struct v3_cpuid_hook * hook) {
   struct v3_cpuid_hook * ret;
 
-  if ((ret = __insert_cpuid_hook(info, hook))) {
+  if ((ret = __insert_cpuid_hook(vm, hook))) {
     return ret;
   }
 
-  v3_rb_insert_color(&(hook->tree_node), &(info->cpuid_map.map));
+  v3_rb_insert_color(&(hook->tree_node), &(vm->cpuid_map.map));
 
   return NULL;
 }
 
 
 
-static struct v3_cpuid_hook * get_cpuid_hook(struct guest_info * info, uint32_t cpuid) {
-  struct rb_node * n = info->cpuid_map.map.rb_node;
+static struct v3_cpuid_hook * get_cpuid_hook(struct v3_vm_info * vm, uint32_t cpuid) {
+  struct rb_node * n = vm->cpuid_map.map.rb_node;
   struct v3_cpuid_hook * hook = NULL;
 
   while (n) {
@@ -85,22 +85,22 @@ static struct v3_cpuid_hook * get_cpuid_hook(struct guest_info * info, uint32_t
 }
 
 
-int v3_unhook_cpuid(struct guest_info * info, uint32_t cpuid) {
-    struct v3_cpuid_hook * hook = get_cpuid_hook(info, cpuid);
+int v3_unhook_cpuid(struct v3_vm_info * vm, uint32_t cpuid) {
+    struct v3_cpuid_hook * hook = get_cpuid_hook(vm, cpuid);
 
     if (hook == NULL) {
        PrintError("Could not find cpuid to unhook (0x%x)\n", cpuid);
        return -1;
     }
 
-    v3_rb_erase(&(hook->tree_node), &(info->cpuid_map.map));
+    v3_rb_erase(&(hook->tree_node), &(vm->cpuid_map.map));
 
     V3_Free(hook);
 
     return 0;
 }
 
-int v3_hook_cpuid(struct guest_info * info, uint32_t cpuid, 
+int v3_hook_cpuid(struct v3_vm_info * vm, uint32_t cpuid, 
                  int (*hook_fn)(struct guest_info * info, uint32_t cpuid, \
                                 uint32_t * eax, uint32_t * ebx, \
                                 uint32_t * ecx, uint32_t * edx, \
@@ -118,7 +118,7 @@ int v3_hook_cpuid(struct guest_info * info, uint32_t cpuid,
     hook->private_data = private_data;
     hook->hook_fn = hook_fn;
 
-    if (insert_cpuid_hook(info, hook)) {
+    if (insert_cpuid_hook(vm, hook)) {
        PrintError("Could not hook cpuid 0x%x (already hooked)\n", cpuid);
        V3_Free(hook);
        return -1;
@@ -129,7 +129,7 @@ int v3_hook_cpuid(struct guest_info * info, uint32_t cpuid,
 
 int v3_handle_cpuid(struct guest_info * info) {
     uint32_t cpuid = info->vm_regs.rax;
-    struct v3_cpuid_hook * hook = get_cpuid_hook(info, cpuid);
+    struct v3_cpuid_hook * hook = get_cpuid_hook(info->vm_info, cpuid);
 
     //PrintDebug("CPUID called for 0x%x\n", cpuid);
 
index d3e9360..04fba8e 100644 (file)
@@ -542,11 +542,10 @@ int v3_handle_cr4_write(struct guest_info * info) {
 }
 
 
-int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
-    struct guest_info * info = (struct guest_info *)(priv_data);
-    PrintDebug("EFER Read HI=%x LO=%x\n", info->shdw_pg_state.guest_efer.hi, info->shdw_pg_state.guest_efer.lo);
+int v3_handle_efer_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
+    PrintDebug("EFER Read HI=%x LO=%x\n", core->shdw_pg_state.guest_efer.hi, core->shdw_pg_state.guest_efer.lo);
     
-    dst->value = info->shdw_pg_state.guest_efer.value;
+    dst->value = core->shdw_pg_state.guest_efer.value;
     
     return 0;
 }
@@ -554,11 +553,10 @@ int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
 
 
 // TODO: this is a disaster we need to clean this up...
-int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data) {
-    struct guest_info * info = (struct guest_info *)(priv_data);
+int v3_handle_efer_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
     //struct efer_64 * new_efer = (struct efer_64 *)&(src.value);
-    struct efer_64 * shadow_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
-    struct v3_msr * guest_efer = &(info->shdw_pg_state.guest_efer);
+    struct efer_64 * shadow_efer = (struct efer_64 *)&(core->ctrl_regs.efer);
+    struct v3_msr * guest_efer = &(core->shdw_pg_state.guest_efer);
     
     PrintDebug("EFER Write\n");
     PrintDebug("EFER Write Values: HI=%x LO=%x\n", src.hi, src.lo);
index a96d27b..0b50c36 100644 (file)
@@ -86,8 +86,8 @@ int v3_init_devices() {
 }
 
 
-int v3_init_dev_mgr(struct guest_info * info) {
-    struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+int v3_init_dev_mgr(struct v3_vm_info * vm) {
+    struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
 
     INIT_LIST_HEAD(&(mgr->dev_list));
     mgr->num_devs = 0;
@@ -106,9 +106,9 @@ int v3_init_dev_mgr(struct guest_info * info) {
 }
 
 
-int v3_dev_mgr_deinit(struct guest_info * info) {
+int v3_dev_mgr_deinit(struct v3_vm_info * vm) {
     struct vm_device * dev;
-    struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+    struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
     struct vm_device * tmp;
 
     list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
@@ -116,13 +116,40 @@ int v3_dev_mgr_deinit(struct guest_info * info) {
        v3_free_device(dev);
     }
 
+
+    /* TODO: Clear hash tables */
+
     return 0;
 }
 
+/*
+int v3_init_core_dev_mgr(struct v3_vm_info * vm) {
+    struct v3_core_dev_mgr * mgr = &(vm->core_dev_mgr);
+
+    INIT_LIST_HEAD(&(mgr->dev_list));
+    mgr->dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
 
+    return 0;
+}
 
-int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg) {
-    int (*dev_init)(struct guest_info * info, void * cfg_data);
+int v3_core_dev_mgr_deinit(struct v3_vm_info * vm) {
+    struct vm_device * dev;
+    struct v3_core_dev_mgr * mgr = &(vm->core_dev_mgr);
+    struct vm_device * tmp;
+
+    list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
+       v3_detach_device(dev);
+       v3_free_device(dev);
+    }
+
+    // TODO: Clear hash tables 
+
+}
+*/
+
+
+int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg) {
+    int (*dev_init)(struct v3_vm_info * vm, void * cfg_data);
 
     dev_init = (void *)v3_htable_search(master_dev_table, (addr_t)dev_name);
 
@@ -132,7 +159,7 @@ int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tre
     }
 
 
-    if (dev_init(info, cfg) == -1) {
+    if (dev_init(vm, cfg) == -1) {
        PrintError("Could not initialize Device %s\n", dev_name);
        return -1;
     }
@@ -147,8 +174,8 @@ void v3_free_device(struct vm_device * dev) {
 
 
 
-struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name) {
-    struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+struct vm_device * v3_find_dev(struct v3_vm_info * vm, const char * dev_name) {
+    struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
 
     if (!dev_name) {
        return NULL;
@@ -164,11 +191,11 @@ struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name)
 
 /* IO HOOKS */
 int v3_dev_hook_io(struct vm_device * dev, uint16_t port,
-                  int (*read)(uint16_t port, void * dst, uint_t length, struct vm_device * dev),
-                  int (*write)(uint16_t port, void * src, uint_t length, struct vm_device * dev)) {
+                  int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, struct vm_device * dev),
+                  int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev)) {
     return v3_hook_io_port(dev->vm, port, 
-                          (int (*)(ushort_t, void *, uint_t, void *))read, 
-                          (int (*)(ushort_t, void *, uint_t, void *))write, 
+                          (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))read, 
+                          (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))write, 
                           (void *)dev);
 }
 
@@ -210,7 +237,7 @@ struct vm_device * v3_allocate_device(char * name,
 }
 
 
-int v3_attach_device(struct guest_info * vm, struct vm_device * dev ) {
+int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev ) {
     struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
 
     dev->vm = vm;
@@ -226,8 +253,8 @@ int v3_attach_device(struct guest_info * vm, struct vm_device * dev ) {
 
 
 
-void v3_print_dev_mgr(struct guest_info * info) {
-    struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+void v3_print_dev_mgr(struct v3_vm_info * vm) {
+    struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
     struct vm_device * dev;
 
     V3_Print("%d devices registered with manager\n", mgr->num_devs);
@@ -243,7 +270,7 @@ void v3_print_dev_mgr(struct guest_info * info) {
 
 
 struct blk_frontend {
-    int (*connect)(struct guest_info * info, 
+    int (*connect)(struct v3_vm_info * vm, 
                    void * frontend_data, 
                    struct v3_dev_blk_ops * ops, 
                    v3_cfg_tree_t * cfg, 
@@ -257,9 +284,9 @@ struct blk_frontend {
 
 
 
-int v3_dev_add_blk_frontend(struct guest_info * info, 
+int v3_dev_add_blk_frontend(struct v3_vm_info * vm, 
                            char * name, 
-                           int (*connect)(struct guest_info * info, 
+                           int (*connect)(struct v3_vm_info * vm, 
                                            void * frontend_data, 
                                            struct v3_dev_blk_ops * ops, 
                                            v3_cfg_tree_t * cfg, 
@@ -274,13 +301,13 @@ int v3_dev_add_blk_frontend(struct guest_info * info,
     frontend->connect = connect;
     frontend->priv_data = priv_data;
        
-    list_add(&(frontend->blk_node), &(info->dev_mgr.blk_list));
-    v3_htable_insert(info->dev_mgr.blk_table, (addr_t)(name), (addr_t)frontend);
+    list_add(&(frontend->blk_node), &(vm->dev_mgr.blk_list));
+    v3_htable_insert(vm->dev_mgr.blk_table, (addr_t)(name), (addr_t)frontend);
 
     return 0;
 }
 
-int v3_dev_connect_blk(struct guest_info * info, 
+int v3_dev_connect_blk(struct v3_vm_info * vm, 
                       char * frontend_name, 
                       struct v3_dev_blk_ops * ops, 
                       v3_cfg_tree_t * cfg, 
@@ -288,7 +315,7 @@ int v3_dev_connect_blk(struct guest_info * info,
 
     struct blk_frontend * frontend = NULL;
 
-    frontend = (struct blk_frontend *)v3_htable_search(info->dev_mgr.blk_table,
+    frontend = (struct blk_frontend *)v3_htable_search(vm->dev_mgr.blk_table,
                                                       (addr_t)frontend_name);
     
     if (frontend == NULL) {
@@ -296,7 +323,7 @@ int v3_dev_connect_blk(struct guest_info * info,
        return 0;
     }
 
-    if (frontend->connect(info, frontend->priv_data, ops, cfg, private_data) == -1) {
+    if (frontend->connect(vm, frontend->priv_data, ops, cfg, private_data) == -1) {
        PrintError("Error connecting to block frontend %s\n", frontend_name);
        return -1;
     }
@@ -307,7 +334,7 @@ int v3_dev_connect_blk(struct guest_info * info,
 
 
 struct net_frontend {
-    int (*connect)(struct guest_info * info, 
+    int (*connect)(struct v3_vm_info * vm, 
                    void * frontend_data, 
                    struct v3_dev_net_ops * ops, 
                    v3_cfg_tree_t * cfg, 
@@ -320,9 +347,9 @@ struct net_frontend {
 };
 
 
-int v3_dev_add_net_frontend(struct guest_info * info, 
+int v3_dev_add_net_frontend(struct v3_vm_info * vm, 
                            char * name, 
-                           int (*connect)(struct guest_info * info, 
+                           int (*connect)(struct v3_vm_info * vm, 
                                            void * frontend_data, 
                                            struct v3_dev_net_ops * ops, 
                                            v3_cfg_tree_t * cfg, 
@@ -337,14 +364,14 @@ int v3_dev_add_net_frontend(struct guest_info * info,
     frontend->connect = connect;
     frontend->priv_data = priv_data;
        
-    list_add(&(frontend->net_node), &(info->dev_mgr.net_list));
-    v3_htable_insert(info->dev_mgr.net_table, (addr_t)(name), (addr_t)frontend);
+    list_add(&(frontend->net_node), &(vm->dev_mgr.net_list));
+    v3_htable_insert(vm->dev_mgr.net_table, (addr_t)(name), (addr_t)frontend);
 
     return 0;
 }
 
 
-int v3_dev_connect_net(struct guest_info * info, 
+int v3_dev_connect_net(struct v3_vm_info * vm, 
                       char * frontend_name, 
                       struct v3_dev_net_ops * ops, 
                       v3_cfg_tree_t * cfg, 
@@ -352,7 +379,7 @@ int v3_dev_connect_net(struct guest_info * info,
 {
     struct net_frontend * frontend = NULL;
 
-    frontend = (struct net_frontend *)v3_htable_search(info->dev_mgr.net_table,
+    frontend = (struct net_frontend *)v3_htable_search(vm->dev_mgr.net_table,
                                                       (addr_t)frontend_name);
     
     if (frontend == NULL) {
@@ -360,7 +387,7 @@ int v3_dev_connect_net(struct guest_info * info,
        return 0;
     }
 
-    if (frontend->connect(info, frontend->priv_data, ops, cfg, private_data) == -1) {
+    if (frontend->connect(vm, frontend->priv_data, ops, cfg, private_data) == -1) {
        PrintError("Error connecting to net frontend %s\n", frontend_name);
        return -1;
     }
index 52f0991..bfbb4a3 100644 (file)
@@ -39,7 +39,7 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info,
     int pde_index = PDE32_INDEX(fault_addr);
     int pte_index = PTE32_INDEX(fault_addr);
     
-    struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
+    struct v3_shadow_region * region = v3_get_shadow_region(info->vm_info, info->cpu_id, fault_addr);
 
     if (region == NULL) {
        PrintError("Invalid region in passthrough page fault 32, addr=%p\n", 
@@ -47,7 +47,7 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info,
        return -1;
     }
     
-    host_addr = v3_get_shadow_addr(region, fault_addr);
+    host_addr = v3_get_shadow_addr(region, info->cpu_id, fault_addr);
     
     // Lookup the correct PDE address based on the PAGING MODE
     if (info->shdw_pg_mode == SHADOW_PAGING) {
index fb97ee4..f7c1f76 100644 (file)
@@ -40,7 +40,7 @@ static inline int handle_passthrough_pagefault_32pae(struct guest_info * info,
     int pde_index = PDE32PAE_INDEX(fault_addr);
     int pte_index = PTE32PAE_INDEX(fault_addr);
 
-    struct v3_shadow_region * region =  v3_get_shadow_region(info, fault_addr);
+    struct v3_shadow_region * region =  v3_get_shadow_region(info->vm_info, info->cpu_id, fault_addr);
   
     if (region == NULL) {
        PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n", 
@@ -48,7 +48,7 @@ static inline int handle_passthrough_pagefault_32pae(struct guest_info * info,
        return -1;
     }
 
-    host_addr = v3_get_shadow_addr(region, fault_addr);
+    host_addr = v3_get_shadow_addr(region, info->cpu_id, fault_addr);
 
     // Lookup the correct PDPE address based on the PAGING MODE
     if (info->shdw_pg_mode == SHADOW_PAGING) {
index 1c819ee..0511754 100644 (file)
@@ -46,7 +46,7 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
 
     
 
-    struct v3_shadow_region * region =  v3_get_shadow_region(info, fault_addr);
+    struct v3_shadow_region * region =  v3_get_shadow_region(info->vm_info, info->cpu_id, fault_addr);
   
     if (region == NULL) {
        PrintError("Invalid region in passthrough page fault 64, addr=%p\n", 
@@ -54,7 +54,7 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
        return -1;
     }
 
-    host_addr = v3_get_shadow_addr(region, fault_addr);
+    host_addr = v3_get_shadow_addr(region, info->cpu_id, fault_addr);
     //
 
     // Lookup the correct PML address based on the PAGING MODE
index f80aade..83d6d1a 100644 (file)
@@ -35,7 +35,7 @@ static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_add
 // We emulate up to the next 4KB page boundry
 static int emulate_string_write_op(struct guest_info * info, struct x86_instr * dec_instr, 
                                   addr_t write_gva, addr_t write_gpa, addr_t dst_addr, 
-                                  int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
+                                  int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data), 
                                   void * priv_data) {
     uint_t emulation_length = 0;
     uint_t emulation_iter_cnt = 0;
@@ -126,7 +126,7 @@ static int emulate_string_write_op(struct guest_info * info, struct x86_instr *
        return -1;
     }
 
-    if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
+    if (write_fn(info, write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
        PrintError("Did not fully read hooked data\n");
        return -1;
     }
@@ -141,7 +141,7 @@ static int emulate_string_write_op(struct guest_info * info, struct x86_instr *
 
 static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * dec_instr, 
                                 addr_t write_gva, addr_t write_gpa, addr_t dst_addr, 
-                                int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
+                                int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data), 
                                 void * priv_data) {
     addr_t src_addr = 0;
     addr_t em_dst_addr = 0;
@@ -197,7 +197,7 @@ static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * de
        return -1;
     }
     
-    if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
+    if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
        PrintError("Did not fully write hooked data\n");
        return -1;
     }
@@ -211,8 +211,8 @@ static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * de
 
 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr, 
                                addr_t read_gva, addr_t read_gpa, addr_t src_addr, 
-                               int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
-                               int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),                        
+                               int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
+                               int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),                      
                                void * priv_data) {
     addr_t em_src_addr = 0;
     addr_t em_dst_addr = 0;
@@ -262,7 +262,7 @@ static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec
               (void *)em_dst_addr, (void *)em_src_addr);
 
 
-    if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
+    if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
        PrintError("Did not fully read hooked data\n");
        return -1;
     }
@@ -272,7 +272,7 @@ static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec
        return -1;
     }
 
-    if (write_fn(read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
+    if (write_fn(info, read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
        PrintError("Did not fully write hooked data\n");
        return -1;
     }
@@ -286,7 +286,7 @@ static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec
 
 
 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa,  addr_t dst_addr, 
-                       int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
+                       int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data), 
                        void * priv_data) {
     struct x86_instr dec_instr;
     uchar_t instr[15];
@@ -366,7 +366,7 @@ int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write
        return -1;
     }
 
-    if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
+    if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
        PrintError("Did not fully write hooked data\n");
        return -1;
     }
@@ -378,8 +378,8 @@ int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write
 
 
 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
-                      int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
-                      int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),  
+                      int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
+                      int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),  
                       void * priv_data) {
     struct x86_instr dec_instr;
     uchar_t instr[15];
@@ -451,7 +451,7 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp
     PrintDebug("Dst_Addr = %p, SRC Addr = %p\n", 
               (void *)dst_addr, (void *)src_addr);
 
-    if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
+    if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
        PrintError("Did not fully read hooked data\n");
        return -1;
     }
index 2be016c..056d568 100644 (file)
@@ -63,7 +63,7 @@ int v3_handle_halt(struct guest_info * info) {
         * interrupt and stall the guest.
         */
        if (!v3_intr_pending(info)) {
-           v3_raise_irq(info, 0);
+           v3_advance_time(info);
        }
 
        
index 791898c..5e6baf2 100644 (file)
@@ -21,8 +21,8 @@
 #include <palacios/vmm_host_events.h>
 #include <palacios/vm_guest.h>
 
-int v3_init_host_events(struct guest_info * info) {
-    struct v3_host_events * host_evts = &(info->host_event_hooks);
+int v3_init_host_events(struct v3_vm_info * vm) {
+    struct v3_host_events * host_evts = &(vm->host_event_hooks);
 
     INIT_LIST_HEAD(&(host_evts->keyboard_events));
     INIT_LIST_HEAD(&(host_evts->mouse_events));
@@ -32,12 +32,12 @@ int v3_init_host_events(struct guest_info * info) {
 }
 
 
-int v3_hook_host_event(struct guest_info * info, 
+int v3_hook_host_event(struct v3_vm_info * vm, 
                       v3_host_evt_type_t event_type, 
                       union v3_host_event_handler cb, 
                       void * private_data) {
   
-    struct v3_host_events * host_evts = &(info->host_event_hooks);
+    struct v3_host_events * host_evts = &(vm->host_event_hooks);
     struct v3_host_event_hook * hook = NULL;
 
     hook = (struct v3_host_event_hook *)V3_Malloc(sizeof(struct v3_host_event_hook));
@@ -65,17 +65,17 @@ int v3_hook_host_event(struct guest_info * info,
 }
 
 
-int v3_deliver_keyboard_event(struct guest_info * info, 
+int v3_deliver_keyboard_event(struct v3_vm_info * vm, 
                              struct v3_keyboard_event * evt) {
-    struct v3_host_events * host_evts = &(info->host_event_hooks);
+    struct v3_host_events * host_evts = &(vm->host_event_hooks);
     struct v3_host_event_hook * hook = NULL;
 
-    if (info->run_state != VM_RUNNING) {
+    if (vm->run_state != VM_RUNNING) {
        return -1;
     }
 
     list_for_each_entry(hook, &(host_evts->keyboard_events), link) {
-       if (hook->cb.keyboard_handler(info, evt, hook->private_data) == -1) {
+       if (hook->cb.keyboard_handler(vm, evt, hook->private_data) == -1) {
            return -1;
        }
     }
@@ -84,17 +84,17 @@ int v3_deliver_keyboard_event(struct guest_info * info,
 }
 
 
-int v3_deliver_mouse_event(struct guest_info * info, 
+int v3_deliver_mouse_event(struct v3_vm_info * vm, 
                           struct v3_mouse_event * evt) {
-    struct v3_host_events * host_evts = &(info->host_event_hooks);
+    struct v3_host_events * host_evts = &(vm->host_event_hooks);
     struct v3_host_event_hook * hook = NULL;
 
-    if (info->run_state != VM_RUNNING) {
+    if (vm->run_state != VM_RUNNING) {
        return -1;
     }
 
     list_for_each_entry(hook, &(host_evts->mouse_events), link) {
-       if (hook->cb.mouse_handler(info, evt, hook->private_data) == -1) {
+       if (hook->cb.mouse_handler(vm, evt, hook->private_data) == -1) {
            return -1;
        }
     }
@@ -103,17 +103,17 @@ int v3_deliver_mouse_event(struct guest_info * info,
 }
 
 
-int v3_deliver_timer_event(struct guest_info * info, 
+int v3_deliver_timer_event(struct v3_vm_info * vm, 
                           struct v3_timer_event * evt) {
-    struct v3_host_events * host_evts = &(info->host_event_hooks);
+    struct v3_host_events * host_evts = &(vm->host_event_hooks);
     struct v3_host_event_hook * hook = NULL;
 
-    if (info->run_state != VM_RUNNING) {
+    if (vm->run_state != VM_RUNNING) {
        return -1;
     }
 
     list_for_each_entry(hook, &(host_evts->timer_events), link) {
-       if (hook->cb.timer_handler(info, evt, hook->private_data) == -1) {
+       if (hook->cb.timer_handler(vm, evt, hook->private_data) == -1) {
            return -1;
        }
     }
index 0d62ab3..05a6630 100644 (file)
@@ -35,10 +35,10 @@ static int hcall_test(struct guest_info * info, uint_t hcall_id, void * private_
 
 
 
-void v3_init_hypercall_map(struct guest_info * info) {
-    info->hcall_map.rb_node = NULL;
+void v3_init_hypercall_map(struct v3_vm_info * vm) {
+    vm->hcall_map.rb_node = NULL;
 
-    v3_register_hypercall(info, HYPERCALL_TEST_HCALL, hcall_test, NULL);
+    v3_register_hypercall(vm, HYPERCALL_TEST_HCALL, hcall_test, NULL);
 }
 
 
@@ -53,8 +53,8 @@ struct hypercall {
 
 
 
-static inline struct hypercall * __insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
-    struct rb_node ** p = &(info->hcall_map.rb_node);
+static inline struct hypercall * __insert_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
+    struct rb_node ** p = &(vm->hcall_map.rb_node);
     struct rb_node * parent = NULL;
     struct hypercall * tmp_hcall = NULL;
 
@@ -77,21 +77,21 @@ static inline struct hypercall * __insert_hypercall(struct guest_info * info, st
 }
 
 
-static inline struct hypercall * insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
+static inline struct hypercall * insert_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
     struct hypercall * ret;
 
-    if ((ret = __insert_hypercall(info, hcall))) {
+    if ((ret = __insert_hypercall(vm, hcall))) {
        return ret;
     }
 
-    v3_rb_insert_color(&(hcall->tree_node), &(info->hcall_map));
+    v3_rb_insert_color(&(hcall->tree_node), &(vm->hcall_map));
 
     return NULL;
 }
 
 
-static struct hypercall * get_hypercall(struct guest_info * info, uint_t id) {
-    struct rb_node * n = info->hcall_map.rb_node;
+static struct hypercall * get_hypercall(struct v3_vm_info * vm, uint_t id) {
+    struct rb_node * n = vm->hcall_map.rb_node;
     struct hypercall * hcall = NULL;
 
     while (n) {
@@ -110,7 +110,7 @@ static struct hypercall * get_hypercall(struct guest_info * info, uint_t id) {
 }
 
 
-int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id, 
+int v3_register_hypercall(struct v3_vm_info * vm, uint_t hypercall_id, 
                          int (*hypercall)(struct guest_info * info, uint_t hcall_id, void * priv_data), 
                          void * priv_data) {
 
@@ -120,7 +120,7 @@ int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id,
     hcall->priv_data = priv_data;
     hcall->hcall_fn = hypercall;
 
-    if (insert_hypercall(info, hcall)) {
+    if (insert_hypercall(vm, hcall)) {
        V3_Free(hcall);
        return -1;
     }
@@ -132,7 +132,7 @@ int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id,
 int v3_handle_hypercall(struct guest_info * info) {
     uint_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
 
-    struct hypercall * hcall = get_hypercall(info, hypercall_id);
+    struct hypercall * hcall = get_hypercall(info->vm_info, hypercall_id);
 
     if (!hcall) {
        PrintError("Invalid Hypercall (%d(0x%x) not registered)\n", 
index 656fa1e..87b6802 100644 (file)
@@ -42,41 +42,69 @@ struct intr_controller {
 };
 
 
-void v3_init_interrupt_state(struct guest_info * info) {
+struct intr_router {
+    struct intr_router_ops * router_ops;
 
-    info->intr_state.irq_pending = 0;
-    info->intr_state.irq_started = 0;
-    info->intr_state.irq_vector = 0;
+    void * priv_data;
+    struct list_head router_node;
+
+};
+
+void v3_init_intr_controllers(struct guest_info * info) {
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
+
+    intr_state->irq_pending = 0;
+    intr_state->irq_started = 0;
+    intr_state->irq_vector = 0;
 
-    INIT_LIST_HEAD(&(info->intr_state.controller_list));
+    v3_lock_init(&(intr_state->irq_lock));
 
-    v3_lock_init(&(info->intr_state.irq_lock));
+    INIT_LIST_HEAD(&(intr_state->controller_list));
+}
+
+void v3_init_intr_routers(struct v3_vm_info * vm) {
+    
+    INIT_LIST_HEAD(&(vm->intr_routers.router_list));
+    
+    v3_lock_init(&(vm->intr_routers.irq_lock));
 
-    memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
+    memset((uchar_t *)(vm->intr_routers.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
 }
 
-void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
+
+int v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * priv_data) {
     struct intr_controller * ctrlr = (struct intr_controller *)V3_Malloc(sizeof(struct intr_controller));
 
-    ctrlr->priv_data = state;
+    ctrlr->priv_data = priv_data;
     ctrlr->ctrl_ops = ops;
 
-    list_add(&(ctrlr->ctrl_node), &(info->intr_state.controller_list));
-
+    list_add(&(ctrlr->ctrl_node), &(info->intr_core_state.controller_list));
+    
+    return 0;
 }
 
+int v3_register_intr_router(struct v3_vm_info * vm, struct intr_router_ops * ops, void * priv_data) {
+    struct intr_router * router = (struct intr_router *)V3_Malloc(sizeof(struct intr_router));
 
+    router->priv_data = priv_data;
+    router->router_ops = ops;
+
+    list_add(&(router->router_node), &(vm->intr_routers.router_list));
+    
+    return 0;
+}
 
 
-static inline struct v3_irq_hook * get_irq_hook(struct guest_info * info, uint_t irq) {
+
+static inline struct v3_irq_hook * get_irq_hook(struct v3_vm_info * vm, uint_t irq) {
     V3_ASSERT(irq <= 256);
-    return info->intr_state.hooks[irq];
+    return vm->intr_routers.hooks[irq];
 }
 
 
-int v3_hook_irq(struct guest_info * info, 
+int v3_hook_irq(struct v3_vm_info * vm,
                uint_t irq,
-               int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data),
+               int (*handler)(struct v3_vm_info * vm, struct v3_interrupt * intr, void * priv_data),
                void  * priv_data) 
 {
     struct v3_irq_hook * hook = (struct v3_irq_hook *)V3_Malloc(sizeof(struct v3_irq_hook));
@@ -85,7 +113,7 @@ int v3_hook_irq(struct guest_info * info,
        return -1; 
     }
 
-    if (get_irq_hook(info, irq) != NULL) {
+    if (get_irq_hook(vm, irq) != NULL) {
        PrintError("IRQ %d already hooked\n", irq);
        return -1;
     }
@@ -93,9 +121,9 @@ int v3_hook_irq(struct guest_info * info,
     hook->handler = handler;
     hook->priv_data = priv_data;
   
-    info->intr_state.hooks[irq] = hook;
+    vm->intr_routers.hooks[irq] = hook;
 
-    if (V3_Hook_Interrupt(info, irq)) { 
+    if (V3_Hook_Interrupt(vm, irq)) { 
        PrintError("hook_irq: failed to hook irq %d\n", irq);
        return -1;
     } else {
@@ -106,21 +134,21 @@ int v3_hook_irq(struct guest_info * info,
 
 
 
-static int passthrough_irq_handler(struct guest_info * info, struct v3_interrupt * intr, void * priv_data) {
+static int passthrough_irq_handler(struct v3_vm_info * vm, struct v3_interrupt * intr, void * priv_data) {
     PrintDebug("[passthrough_irq_handler] raise_irq=%d (guest=0x%p)\n", 
-              intr->irq, (void *)info);
+              intr->irq, (void *)vm);
 
-    return v3_raise_irq(info, intr->irq);
+    return v3_raise_irq(vm, intr->irq);
 }
 
-int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq) {
-    int rc = v3_hook_irq(info, irq, passthrough_irq_handler, NULL);
+int v3_hook_passthrough_irq(struct v3_vm_info * vm, uint_t irq) {
+    int rc = v3_hook_irq(vm, irq, passthrough_irq_handler, NULL);
 
     if (rc) { 
-       PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%p)\n", irq, (void *)info);
+       PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%p)\n", irq, (void *)vm);
        return -1;
     } else {
-       PrintDebug("guest_irq_injection: hooked irq 0x%x (guest=0x%p)\n", irq, (void *)info);
+       PrintDebug("guest_irq_injection: hooked irq 0x%x (guest=0x%p)\n", irq, (void *)vm);
        return 0;
     }
 }
@@ -129,17 +157,17 @@ int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq) {
 
 
 
-int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
+int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr) {
     PrintDebug("v3_deliver_irq: irq=%d state=0x%p, \n", intr->irq, (void *)intr);
   
-    struct v3_irq_hook * hook = get_irq_hook(info, intr->irq);
+    struct v3_irq_hook * hook = get_irq_hook(vm, intr->irq);
 
     if (hook == NULL) {
        PrintError("Attempting to deliver interrupt to non registered hook(irq=%d)\n", intr->irq);
        return -1;
     }
   
-    return hook->handler(info, intr, hook->priv_data);
+    return hook->handler(vm, intr, hook->priv_data);
 }
 
 
@@ -147,7 +175,7 @@ int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
 
 
 int v3_raise_virq(struct guest_info * info, int irq) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
     int major = irq / 8;
     int minor = irq % 8;
 
@@ -157,7 +185,7 @@ int v3_raise_virq(struct guest_info * info, int irq) {
 }
 
 int v3_lower_virq(struct guest_info * info, int irq) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
     int major = irq / 8;
     int minor = irq % 8;
 
@@ -167,34 +195,34 @@ int v3_lower_virq(struct guest_info * info, int irq) {
 }
 
 
-int v3_lower_irq(struct guest_info * info, int irq) {
-    struct intr_controller * ctrl = NULL;
-    struct v3_intr_state * intr_state = &(info->intr_state);
+int v3_lower_irq(struct v3_vm_info * vm, int irq) {
+    struct intr_router * router = NULL;
+    struct v3_intr_routers * routers = &(vm->intr_routers);
 
     //    PrintDebug("[v3_lower_irq]\n");
-    addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);
+    addr_t irq_state = v3_lock_irqsave(routers->irq_lock);
 
-    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-       ctrl->ctrl_ops->lower_intr(info, ctrl->priv_data, irq);
+    list_for_each_entry(router, &(routers->router_list), router_node) {
+       router->router_ops->lower_intr(vm, router->priv_data, irq);
     }
  
-    v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
+    v3_unlock_irqrestore(routers->irq_lock, irq_state);
 
     return 0;
 }
 
-int v3_raise_irq(struct guest_info * info, int irq) {
-    struct intr_controller * ctrl = NULL;
-    struct v3_intr_state * intr_state = &(info->intr_state);
+int v3_raise_irq(struct v3_vm_info * vm, int irq) {
+    struct intr_router * router = NULL;
+    struct v3_intr_routers * routers = &(vm->intr_routers);
 
     //  PrintDebug("[v3_raise_irq (%d)]\n", irq);
-    addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);
+    addr_t irq_state = v3_lock_irqsave(routers->irq_lock);
 
-    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-       ctrl->ctrl_ops->raise_intr(info, ctrl->priv_data, irq);
+    list_for_each_entry(router, &(routers->router_list), router_node) {
+       router->router_ops->raise_intr(vm, router->priv_data, irq);
     }
 
-    v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
+    v3_unlock_irqrestore(routers->irq_lock, irq_state);
 
     return 0;
 }
@@ -202,7 +230,7 @@ int v3_raise_irq(struct guest_info * info, int irq) {
 
 
 v3_intr_type_t v3_intr_pending(struct guest_info * info) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
     struct intr_controller * ctrl = NULL;
     int ret = V3_INVALID_INTR;
     int i = 0;
@@ -234,7 +262,7 @@ v3_intr_type_t v3_intr_pending(struct guest_info * info) {
 
 
 uint32_t v3_get_intr(struct guest_info * info) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
     struct intr_controller * ctrl = NULL;
     uint_t ret = 0;
     int i = 0;
@@ -305,7 +333,7 @@ intr_type_t v3_get_intr_type(struct guest_info * info) {
 
 
 int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
+    struct v3_intr_core_state * intr_state = &(info->intr_core_state);
 
     if (type == V3_EXTERNAL_IRQ) {
        struct intr_controller * ctrl = NULL;
index 0211b99..d094d79 100644 (file)
 #endif
 
 
-static int default_write(uint16_t port, void *src, uint_t length, void * priv_data);
-static int default_read(uint16_t port, void * dst, uint_t length, void * priv_data);
+static int default_write(struct guest_info * core, uint16_t port, void *src, uint_t length, void * priv_data);
+static int default_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data);
 
 
-void v3_init_io_map(struct guest_info * info) {
+void v3_init_io_map(struct v3_vm_info * vm) {
 
-  info->io_map.map.rb_node = NULL;
-  info->io_map.arch_data = NULL;
-  info->io_map.update_map = NULL;
+  vm->io_map.map.rb_node = NULL;
+  vm->io_map.arch_data = NULL;
+  vm->io_map.update_map = NULL;
 
 }
 
 
 
 
-static inline struct v3_io_hook * __insert_io_hook(struct guest_info * info, struct v3_io_hook * hook) {
-  struct rb_node ** p = &(info->io_map.map.rb_node);
+static inline struct v3_io_hook * __insert_io_hook(struct v3_vm_info * vm, struct v3_io_hook * hook) {
+  struct rb_node ** p = &(vm->io_map.map.rb_node);
   struct rb_node * parent = NULL;
   struct v3_io_hook * tmp_hook = NULL;
 
@@ -68,21 +68,21 @@ static inline struct v3_io_hook * __insert_io_hook(struct guest_info * info, str
 }
 
 
-static inline struct v3_io_hook * insert_io_hook(struct guest_info * info, struct v3_io_hook * hook) {
+static inline struct v3_io_hook * insert_io_hook(struct v3_vm_info * vm, struct v3_io_hook * hook) {
   struct v3_io_hook * ret;
 
-  if ((ret = __insert_io_hook(info, hook))) {
+  if ((ret = __insert_io_hook(vm, hook))) {
     return ret;
   }
 
-  v3_rb_insert_color(&(hook->tree_node), &(info->io_map.map));
+  v3_rb_insert_color(&(hook->tree_node), &(vm->io_map.map));
 
   return NULL;
 }
 
 
-struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint16_t port) {
-  struct rb_node * n = info->io_map.map.rb_node;
+struct v3_io_hook * v3_get_io_hook(struct v3_vm_info * vm, uint16_t port) {
+  struct rb_node * n = vm->io_map.map.rb_node;
   struct v3_io_hook * hook = NULL;
 
   while (n) {
@@ -104,9 +104,9 @@ struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint16_t port) {
 
 
 
-int v3_hook_io_port(struct guest_info * info, uint16_t port, 
-                   int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data),
-                   int (*write)(uint16_t port, void * src, uint_t length, void * priv_data), 
+int v3_hook_io_port(struct v3_vm_info * vm, uint16_t port, 
+                   int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data),
+                   int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data), 
                    void * priv_data) {
   struct v3_io_hook * io_hook = (struct v3_io_hook *)V3_Malloc(sizeof(struct v3_io_hook));
 
@@ -127,14 +127,14 @@ int v3_hook_io_port(struct guest_info * info, uint16_t port,
 
   io_hook->priv_data = priv_data;
 
-  if (insert_io_hook(info, io_hook)) {
+  if (insert_io_hook(vm, io_hook)) {
       PrintError("Could not insert IO hook for port %u (0x%x)\n", port, port);
       V3_Free(io_hook);
       return -1;
   }
 
-  if (info->io_map.update_map) {
-      if (info->io_map.update_map(info, port, 
+  if (vm->io_map.update_map) {
+      if (vm->io_map.update_map(vm, port, 
                                  ((read == NULL) ? 0 : 1), 
                                  ((write == NULL) ? 0 : 1)) == -1) {
          PrintError("Could not update IO map for port %u (0x%x)\n", port, port);
@@ -146,19 +146,19 @@ int v3_hook_io_port(struct guest_info * info, uint16_t port,
   return 0;
 }
 
-int v3_unhook_io_port(struct guest_info * info, uint16_t port) {
-    struct v3_io_hook * hook = v3_get_io_hook(info, port);
+int v3_unhook_io_port(struct v3_vm_info * vm, uint16_t port) {
+    struct v3_io_hook * hook = v3_get_io_hook(vm, port);
 
     if (hook == NULL) {
        PrintError("Could not find port to unhook %u (0x%x)\n", port, port);
        return -1;
     }
 
-    v3_rb_erase(&(hook->tree_node), &(info->io_map.map));
+    v3_rb_erase(&(hook->tree_node), &(vm->io_map.map));
 
-    if (info->io_map.update_map) {
+    if (vm->io_map.update_map) {
        // set the arch map to default (this should be 1, 1)
-       info->io_map.update_map(info, port, 0, 0);
+       vm->io_map.update_map(vm, port, 0, 0);
     }
 
     V3_Free(hook);
@@ -172,8 +172,8 @@ int v3_unhook_io_port(struct guest_info * info, uint16_t port) {
 
 
 
-void v3_refresh_io_map(struct guest_info * info) {
-    struct v3_io_map * io_map = &(info->io_map);
+void v3_refresh_io_map(struct v3_vm_info * vm) {
+    struct v3_io_map * io_map = &(vm->io_map);
     struct v3_io_hook * tmp = NULL;
     
     if (io_map->update_map == NULL) {
@@ -182,7 +182,7 @@ void v3_refresh_io_map(struct guest_info * info) {
     }
 
     v3_rb_for_each_entry(tmp, &(io_map->map), tree_node) {
-       io_map->update_map(info, tmp->port, 
+       io_map->update_map(vm, tmp->port, 
                           ((tmp->read == NULL) ? 0 : 1), 
                           ((tmp->write == NULL) ? 0 : 1));
     }
@@ -191,8 +191,8 @@ void v3_refresh_io_map(struct guest_info * info) {
 
 
 
-void v3_print_io_map(struct guest_info * info) {
-    struct v3_io_map * io_map = &(info->io_map);
+void v3_print_io_map(struct v3_vm_info * vm) {
+    struct v3_io_map * io_map = &(vm->io_map);
     struct v3_io_hook * tmp_hook = NULL;
 
     V3_Print("VMM IO Map\n");
@@ -288,7 +288,7 @@ uint_t v3_indw(uint16_t port) {
 
 
 /* FIX ME */
-static int default_write(uint16_t port, void * src, uint_t length, void * priv_data) {
+static int default_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
     if (length == 1) {
        v3_outb(port, *(uint8_t *)src);
     } else if (length == 2) {
@@ -302,7 +302,7 @@ static int default_write(uint16_t port, void * src, uint_t length, void * priv_d
     return length;
 }
 
-static int default_read(uint16_t port, void * dst, uint_t length, void * priv_data) {
+static int default_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data) {
     if (length == 1) {
        *(uint8_t *)dst = v3_inb(port);
     } else if (length == 2) {
index 298d22d..0c66a43 100644 (file)
 
 
 static inline
-struct v3_shadow_region * insert_shadow_region(struct guest_info * info, 
+struct v3_shadow_region * insert_shadow_region(struct v3_vm_info * vm, 
                                               struct v3_shadow_region * region);
 
 
 static int mem_offset_hypercall(struct guest_info * info, uint_t hcall_id, void * private_data) {
     PrintDebug("V3Vee: Memory offset hypercall (offset=%p)\n", 
-              (void *)(info->mem_map.base_region.host_addr));
+              (void *)(info->vm_info->mem_map.base_region.host_addr));
 
-    info->vm_regs.rbx = info->mem_map.base_region.host_addr;
+    info->vm_regs.rbx = info->vm_info->mem_map.base_region.host_addr;
 
     return 0;
 }
 
 
-int v3_init_shadow_map(struct guest_info * info) {
-    v3_shdw_map_t * map = &(info->mem_map);
-    addr_t mem_pages = info->mem_size >> 12;
+int v3_init_mem_map(struct v3_vm_info * vm) {
+    struct v3_mem_map * map = &(vm->mem_map);
+    addr_t mem_pages = vm->mem_size >> 12;
 
     map->shdw_regions.rb_node = NULL;
-    map->hook_hva = (addr_t)V3_VAddr(V3_AllocPages(1));
+
+
+    map->hook_hvas = V3_VAddr(V3_AllocPages(vm->num_cores));
+
 
     // There is an underlying region that contains all of the guest memory
     // PrintDebug("Mapping %d pages of memory (%u bytes)\n", (int)mem_pages, (uint_t)info->mem_size);
@@ -67,13 +70,18 @@ int v3_init_shadow_map(struct guest_info * info) {
        
     //memset(V3_VAddr((void *)map->base_region.host_addr), 0xffffffff, map->base_region.guest_end);
 
-    v3_register_hypercall(info, MEM_OFFSET_HCALL, mem_offset_hypercall, NULL);
+    v3_register_hypercall(vm, MEM_OFFSET_HCALL, mem_offset_hypercall, NULL);
 
     return 0;
 }
 
-void v3_delete_shadow_map(struct guest_info * info) {
-    struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
+
+static inline addr_t get_hook_hva(struct guest_info * info) {
+    return (addr_t)(info->vm_info->mem_map.hook_hvas + (PAGE_SIZE_4KB * info->cpu_id));
+}
+
+void v3_delete_shadow_map(struct v3_vm_info * vm) {
+    struct rb_node * node = v3_rb_first(&(vm->mem_map.shdw_regions));
     struct v3_shadow_region * reg;
     struct rb_node * tmp_node = NULL;
   
@@ -82,17 +90,17 @@ void v3_delete_shadow_map(struct guest_info * info) {
        tmp_node = node;
        node = v3_rb_next(node);
 
-       v3_delete_shadow_region(info, reg);
+       v3_delete_shadow_region(vm, reg);
     }
 
-    V3_FreePage((void *)(info->mem_map.base_region.host_addr));
-    V3_FreePage(V3_PAddr((void *)(info->mem_map.hook_hva)));
+    V3_FreePage((void *)(vm->mem_map.base_region.host_addr));
+    V3_FreePage(V3_PAddr((void *)(vm->mem_map.hook_hvas)));
 }
 
 
 
 
-int v3_add_shadow_mem( struct guest_info *  info,
+int v3_add_shadow_mem( struct v3_vm_info * vm, uint16_t core_id,
                       addr_t               guest_addr_start,
                       addr_t               guest_addr_end,
                       addr_t               host_addr)
@@ -106,8 +114,9 @@ int v3_add_shadow_mem( struct guest_info *  info,
     entry->write_hook = NULL;
     entry->read_hook = NULL;
     entry->priv_data = NULL;
+    entry->core_id = core_id;
 
-    if (insert_shadow_region(info, entry)) {
+    if (insert_shadow_region(vm, entry)) {
        V3_Free(entry);
        return -1;
     }
@@ -117,9 +126,9 @@ int v3_add_shadow_mem( struct guest_info *  info,
 
 
 
-int v3_hook_write_mem(struct guest_info * info, addr_t guest_addr_start, addr_t guest_addr_end, 
-                     addr_t host_addr,
-                     int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+int v3_hook_write_mem(struct v3_vm_info * vm, uint16_t core_id,
+                     addr_t guest_addr_start, addr_t guest_addr_end, addr_t host_addr,
+                     int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
                      void * priv_data) {
 
     struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
@@ -132,8 +141,9 @@ int v3_hook_write_mem(struct guest_info * info, addr_t guest_addr_start, addr_t
     entry->write_hook = write;
     entry->read_hook = NULL;
     entry->priv_data = priv_data;
+    entry->core_id = core_id;
 
-    if (insert_shadow_region(info, entry)) {
+    if (insert_shadow_region(vm, entry)) {
        V3_Free(entry);
        return -1;
     }
@@ -141,9 +151,10 @@ int v3_hook_write_mem(struct guest_info * info, addr_t guest_addr_start, addr_t
     return 0;  
 }
 
-int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t guest_addr_end,
-                    int (*read)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
-                    int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+int v3_hook_full_mem(struct v3_vm_info * vm, uint16_t core_id, 
+                    addr_t guest_addr_start, addr_t guest_addr_end,
+                    int (*read)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
+                    int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
                     void * priv_data) {
   
     struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
@@ -155,8 +166,9 @@ int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t g
     entry->write_hook = write;
     entry->read_hook = read;
     entry->priv_data = priv_data;
-  
-    if (insert_shadow_region(info, entry)) {
+    entry->core_id = core_id;
+
+    if (insert_shadow_region(vm, entry)) {
        V3_Free(entry);
        return -1;
     }
@@ -167,8 +179,8 @@ int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t g
 
 // This will unhook the memory hook registered at start address
 // We do not support unhooking subregions
-int v3_unhook_mem(struct guest_info * info, addr_t guest_addr_start) {
-    struct v3_shadow_region * reg = v3_get_shadow_region(info, guest_addr_start);
+int v3_unhook_mem(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr_start) {
+    struct v3_shadow_region * reg = v3_get_shadow_region(vm, core_id, guest_addr_start);
 
     if ((reg->host_type != SHDW_REGION_FULL_HOOK) || 
        (reg->host_type != SHDW_REGION_WRITE_HOOK)) {
@@ -176,7 +188,7 @@ int v3_unhook_mem(struct guest_info * info, addr_t guest_addr_start) {
        return -1;
     }
 
-    v3_delete_shadow_region(info, reg);
+    v3_delete_shadow_region(vm, reg);
 
     return 0;
 }
@@ -184,9 +196,9 @@ int v3_unhook_mem(struct guest_info * info, addr_t guest_addr_start) {
 
 
 static inline 
-struct v3_shadow_region * __insert_shadow_region(struct guest_info * info, 
+struct v3_shadow_region * __insert_shadow_region(struct v3_vm_info * vm, 
                                                 struct v3_shadow_region * region) {
-    struct rb_node ** p = &(info->mem_map.shdw_regions.rb_node);
+    struct rb_node ** p = &(vm->mem_map.shdw_regions.rb_node);
     struct rb_node * parent = NULL;
     struct v3_shadow_region * tmp_region;
 
@@ -199,7 +211,17 @@ struct v3_shadow_region * __insert_shadow_region(struct guest_info * info,
        } else if (region->guest_start >= tmp_region->guest_end) {
            p = &(*p)->rb_right;
        } else {
-           return tmp_region;
+           if ((region->guest_end != tmp_region->guest_end) ||
+               (region->guest_start != tmp_region->guest_start)) {
+               PrintError("Trying to map a partial overlapped core specific page...\n");
+               return tmp_region; // This is ugly... 
+           } else if (region->core_id == tmp_region->core_id) {
+               return tmp_region;
+           } else if (region->core_id < tmp_region->core_id) {
+               p = &(*p)->rb_left;
+           } else {
+               p = &(*p)->rb_right;
+           }
        }
     }
 
@@ -210,43 +232,49 @@ struct v3_shadow_region * __insert_shadow_region(struct guest_info * info,
 
 
 static inline
-struct v3_shadow_region * insert_shadow_region(struct guest_info * info, 
+struct v3_shadow_region * insert_shadow_region(struct v3_vm_info * vm, 
                                               struct v3_shadow_region * region) {
     struct v3_shadow_region * ret;
+    int i = 0;
 
-    if ((ret = __insert_shadow_region(info, region))) {
+    if ((ret = __insert_shadow_region(vm, region))) {
        return ret;
     }
 
-    v3_rb_insert_color(&(region->tree_node), &(info->mem_map.shdw_regions));
+    v3_rb_insert_color(&(region->tree_node), &(vm->mem_map.shdw_regions));
 
 
 
-    // flush virtual page tables 
-    // 3 cases shadow, shadow passthrough, and nested
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-       v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * info = &(vm->cores[i]);
 
-       if (mem_mode == PHYSICAL_MEM) {
-           addr_t cur_addr;
+       // flush virtual page tables 
+       // 3 cases shadow, shadow passthrough, and nested
 
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
+           v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
+           
+           if (mem_mode == PHYSICAL_MEM) {
+               addr_t cur_addr;
+               
+               for (cur_addr = region->guest_start;
+                    cur_addr < region->guest_end;
+                    cur_addr += PAGE_SIZE_4KB) {
+                   v3_invalidate_passthrough_addr(info, cur_addr);
+               }
+           } else {
+               v3_invalidate_shadow_pts(info);
+           }
+           
+       } else if (info->shdw_pg_mode == NESTED_PAGING) {
+           addr_t cur_addr;
+           
            for (cur_addr = region->guest_start;
                 cur_addr < region->guest_end;
                 cur_addr += PAGE_SIZE_4KB) {
-               v3_invalidate_passthrough_addr(info, cur_addr);
+               
+               v3_invalidate_nested_addr(info, cur_addr);
            }
-       } else {
-           v3_invalidate_shadow_pts(info);
-       }
-
-    } else if (info->shdw_pg_mode == NESTED_PAGING) {
-       addr_t cur_addr;
-
-       for (cur_addr = region->guest_start;
-            cur_addr < region->guest_end;
-            cur_addr += PAGE_SIZE_4KB) {
-           
-           v3_invalidate_nested_addr(info, cur_addr);
        }
     }
 
@@ -256,11 +284,10 @@ struct v3_shadow_region * insert_shadow_region(struct guest_info * info,
 
 
 
-int handle_special_page_fault(struct guest_info * info, 
-                             addr_t fault_gva, addr_t fault_gpa, 
-                             pf_error_t access_info) 
+int handle_special_page_fault(struct guest_info * info,
+                             addr_t fault_gva, addr_t fault_gpa, pf_error_t access_info) 
 {
-    struct v3_shadow_region * reg = v3_get_shadow_region(info, fault_gpa);
+    struct v3_shadow_region * reg = v3_get_shadow_region(info->vm_info, info->cpu_id, fault_gpa);
 
     PrintDebug("Handling Special Page Fault\n");
 
@@ -280,7 +307,7 @@ int handle_special_page_fault(struct guest_info * info,
 int v3_handle_mem_wr_hook(struct guest_info * info, addr_t guest_va, addr_t guest_pa, 
                          struct v3_shadow_region * reg, pf_error_t access_info) {
 
-    addr_t dst_addr = (addr_t)V3_VAddr((void *)v3_get_shadow_addr(reg, guest_pa));
+    addr_t dst_addr = (addr_t)V3_VAddr((void *)v3_get_shadow_addr(reg, info->cpu_id, guest_pa));
 
     if (v3_emulate_write_op(info, guest_va, guest_pa, dst_addr, 
                            reg->write_hook, reg->priv_data) == -1) {
@@ -294,7 +321,7 @@ int v3_handle_mem_wr_hook(struct guest_info * info, addr_t guest_va, addr_t gues
 int v3_handle_mem_full_hook(struct guest_info * info, addr_t guest_va, addr_t guest_pa, 
                            struct v3_shadow_region * reg, pf_error_t access_info) {
   
-    addr_t op_addr = info->mem_map.hook_hva;
+    addr_t op_addr = get_hook_hva(info);
 
     if (access_info.write == 1) {
        if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr, 
@@ -316,8 +343,8 @@ int v3_handle_mem_full_hook(struct guest_info * info, addr_t guest_va, addr_t gu
 
 
 
-struct v3_shadow_region * v3_get_shadow_region(struct guest_info * info, addr_t guest_addr) {
-    struct rb_node * n = info->mem_map.shdw_regions.rb_node;
+struct v3_shadow_region * v3_get_shadow_region(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr) {
+    struct rb_node * n = vm->mem_map.shdw_regions.rb_node;
     struct v3_shadow_region * reg = NULL;
 
     while (n) {
@@ -328,60 +355,71 @@ struct v3_shadow_region * v3_get_shadow_region(struct guest_info * info, addr_t
        } else if (guest_addr >= reg->guest_end) {
            n = n->rb_right;
        } else {
+           if ((core_id == reg->core_id) || 
+               (reg->core_id == V3_MEM_CORE_ANY)) {
            return reg;
+           } else {
+               n = n->rb_right;
+           }
        }
     }
 
 
     // There is not registered region, so we check if its a valid address in the base region
 
-    if (guest_addr > info->mem_map.base_region.guest_end) {
+    if (guest_addr > vm->mem_map.base_region.guest_end) {
        PrintError("Guest Address Exceeds Base Memory Size (ga=%p), (limit=%p)\n", 
-                  (void *)guest_addr, (void *)info->mem_map.base_region.guest_end);
-       v3_print_mem_map(info);
+                  (void *)guest_addr, (void *)vm->mem_map.base_region.guest_end);
+       v3_print_mem_map(vm);
 
        return NULL;
     }
     
-    return &(info->mem_map.base_region);
+    return &(vm->mem_map.base_region);
 }
 
 
-void v3_delete_shadow_region(struct guest_info * info, struct v3_shadow_region * reg) {
+void v3_delete_shadow_region(struct v3_vm_info * vm, struct v3_shadow_region * reg) {
+    int i = 0;
+
     if (reg == NULL) {
        return;
     }
 
-    // flush virtual page tables 
-    // 3 cases shadow, shadow passthrough, and nested
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-       v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * info = &(vm->cores[i]);
+
+       // flush virtual page tables 
+       // 3 cases shadow, shadow passthrough, and nested
+
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
+           v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
            
-       if (mem_mode == PHYSICAL_MEM) {
-           addr_t cur_addr;
+           if (mem_mode == PHYSICAL_MEM) {
+               addr_t cur_addr;
                
+               for (cur_addr = reg->guest_start;
+                    cur_addr < reg->guest_end;
+                    cur_addr += PAGE_SIZE_4KB) {
+                   v3_invalidate_passthrough_addr(info, cur_addr);
+               }
+           } else {
+               v3_invalidate_shadow_pts(info);
+           }
+           
+       } else if (info->shdw_pg_mode == NESTED_PAGING) {
+           addr_t cur_addr;
+           
            for (cur_addr = reg->guest_start;
                 cur_addr < reg->guest_end;
                 cur_addr += PAGE_SIZE_4KB) {
-               v3_invalidate_passthrough_addr(info, cur_addr);
+               
+               v3_invalidate_nested_addr(info, cur_addr);
            }
-       } else {
-           v3_invalidate_shadow_pts(info);
-       }
-
-    } else if (info->shdw_pg_mode == NESTED_PAGING) {
-       addr_t cur_addr;
-
-       for (cur_addr = reg->guest_start;
-            cur_addr < reg->guest_end;
-            cur_addr += PAGE_SIZE_4KB) {
-           
-           v3_invalidate_nested_addr(info, cur_addr);
        }
     }
 
-
-    v3_rb_erase(&(reg->tree_node), &(info->mem_map.shdw_regions));
+    v3_rb_erase(&(reg->tree_node), &(vm->mem_map.shdw_regions));
 
     V3_Free(reg);
 
@@ -393,7 +431,7 @@ void v3_delete_shadow_region(struct guest_info * info, struct v3_shadow_region *
 
 
 
-addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, addr_t guest_addr) {
+addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, uint16_t core_id, addr_t guest_addr) {
     if ( (reg) && 
          (reg->host_type != SHDW_REGION_FULL_HOOK)) {
         return (guest_addr - reg->guest_start) + reg->host_addr;
@@ -406,9 +444,9 @@ addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, addr_t guest_addr) {
 
 
 
-void v3_print_mem_map(struct guest_info * info) {
-    struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
-    struct v3_shadow_region * reg = &(info->mem_map.base_region);
+void v3_print_mem_map(struct v3_vm_info * vm) {
+    struct rb_node * node = v3_rb_first(&(vm->mem_map.shdw_regions));
+    struct v3_shadow_region * reg = &(vm->mem_map.base_region);
     int i = 0;
 
     V3_Print("Memory Layout:\n");
index de68a86..96d3ddc 100644 (file)
@@ -23,8 +23,8 @@
 #include <palacios/vm_guest.h>
 
 
-void v3_init_msr_map(struct guest_info * info) {
-    struct v3_msr_map * msr_map  = &(info->msr_map);
+void v3_init_msr_map(struct v3_vm_info * vm) {
+    struct v3_msr_map * msr_map  = &(vm->msr_map);
 
     INIT_LIST_HEAD(&(msr_map->hook_list));
     msr_map->num_hooks = 0;
@@ -40,7 +40,7 @@ int v3_handle_msr_write(struct guest_info * info) {
 
     PrintDebug("MSR write for msr 0x%x\n", msr_num);
 
-    hook = v3_get_msr_hook(info, msr_num);
+    hook = v3_get_msr_hook(info->vm_info, msr_num);
 
     if (!hook) {
         PrintError("Hook for MSR write %d not found\n", msr_num);
@@ -51,7 +51,7 @@ int v3_handle_msr_write(struct guest_info * info) {
     msr_val.lo = info->vm_regs.rax;
     msr_val.hi = info->vm_regs.rdx;
 
-    if (hook->write(msr_num, msr_val, hook->priv_data) == -1) {
+    if (hook->write(info, msr_num, msr_val, hook->priv_data) == -1) {
         PrintError("Error in MSR hook Write\n");
         return -1;
     }
@@ -67,7 +67,7 @@ int v3_handle_msr_read(struct guest_info * info) {
     struct v3_msr msr_val;
     struct v3_msr_hook * hook = NULL;
 
-    hook = v3_get_msr_hook(info, msr_num);
+    hook = v3_get_msr_hook(info->vm_info, msr_num);
 
     if (!hook) {
         PrintError("Hook for MSR read %d not found\n", msr_num);
@@ -76,7 +76,7 @@ int v3_handle_msr_read(struct guest_info * info) {
 
     msr_val.value = 0;
 
-    if (hook->read(msr_num, &msr_val, hook->priv_data) == -1) {
+    if (hook->read(info, msr_num, &msr_val, hook->priv_data) == -1) {
         PrintError("Error in MSR hook Read\n");
         return -1;
     }
@@ -88,12 +88,12 @@ int v3_handle_msr_read(struct guest_info * info) {
     return 0;
 }
 
-int v3_hook_msr(struct guest_info * info, uint_t msr, 
-               int (*read)(uint_t msr, struct v3_msr * dst, void * priv_data),
-               int (*write)(uint_t msr, struct v3_msr src, void * priv_data),
+int v3_hook_msr(struct v3_vm_info * vm, uint_t msr, 
+               int (*read)(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data),
+               int (*write)(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data),
                void * priv_data) {
 
-    struct v3_msr_map * msr_map = &(info->msr_map);
+    struct v3_msr_map * msr_map = &(vm->msr_map);
     struct v3_msr_hook * hook = NULL;
 
     hook = (struct v3_msr_hook *)V3_Malloc(sizeof(struct v3_msr_hook));
@@ -113,7 +113,7 @@ int v3_hook_msr(struct guest_info * info, uint_t msr,
     list_add(&(hook->link), &(msr_map->hook_list));
 
     if (msr_map->update_map) {
-       msr_map->update_map(info, msr, 
+       msr_map->update_map(vm, msr, 
                            (read == NULL) ? 0 : 1,
                            (write == NULL) ? 0 : 1);
     }
@@ -122,15 +122,15 @@ int v3_hook_msr(struct guest_info * info, uint_t msr,
 }
 
 
-int v3_unhook_msr(struct guest_info * info, uint_t msr) {
+int v3_unhook_msr(struct v3_vm_info * vm, uint_t msr) {
     PrintError("Unhooking MSRs currently not supported\n");
     return -1;
 }
 
 
 
-struct v3_msr_hook * v3_get_msr_hook(struct guest_info * info, uint_t msr) {
-    struct v3_msr_map * msr_map = &(info->msr_map);
+struct v3_msr_hook * v3_get_msr_hook(struct v3_vm_info * vm, uint_t msr) {
+    struct v3_msr_map * msr_map = &(vm->msr_map);
     struct v3_msr_hook * hook = NULL;
 
     list_for_each_entry(hook, &(msr_map->hook_list), link) {
@@ -143,8 +143,8 @@ struct v3_msr_hook * v3_get_msr_hook(struct guest_info * info, uint_t msr) {
 }
 
 
-void v3_refresh_msr_map(struct guest_info * info) {
-    struct v3_msr_map * msr_map = &(info->msr_map);
+void v3_refresh_msr_map(struct v3_vm_info * vm) {
+    struct v3_msr_map * msr_map = &(vm->msr_map);
     struct v3_msr_hook * hook = NULL;
 
     if (msr_map->update_map == NULL) {
@@ -154,14 +154,14 @@ void v3_refresh_msr_map(struct guest_info * info) {
 
     list_for_each_entry(hook, &(msr_map->hook_list), link) {
        PrintDebug("updating MSR map for msr %d\n", hook->msr);
-       msr_map->update_map(info, hook->msr,    
+       msr_map->update_map(vm, hook->msr,      
                            (hook->read == NULL) ? 0 : 1,
                            (hook->write == NULL) ? 0 : 1);
     }
 }
 
-void v3_print_msr_map(struct guest_info * info) {
-    struct v3_msr_map * msr_map = &(info->msr_map);
+void v3_print_msr_map(struct v3_vm_info * vm) {
+    struct v3_msr_map * msr_map = &(vm->msr_map);
     struct v3_msr_hook * hook = NULL;
 
     list_for_each_entry(hook, &(msr_map->hook_list), link) {
index 0afc383..a6817f9 100644 (file)
@@ -71,8 +71,13 @@ static int is_guest_pf(pt_access_status_t guest_access, pt_access_status_t shado
 
 
 #ifdef CONFIG_SHADOW_PAGING_TELEMETRY
-static void telemetry_cb(struct guest_info * info, void * private_data, char * hdr) {
-    V3_Print("%s Guest Page faults: %d\n", hdr, info->shdw_pg_state.guest_faults);
+static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) {
+    int i = 0;
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * core = &(vm->cores[i]);
+
+       V3_Print("%s Guest Page faults: %d\n", hdr, core->shdw_pg_state.guest_faults);
+    }
 }
 #endif
 
@@ -88,9 +93,7 @@ int v3_init_shadow_page_state(struct guest_info * info) {
     INIT_LIST_HEAD(&(state->page_list));
 
 #ifdef CONFIG_SHADOW_PAGING_TELEMETRY
-    if (info->enable_telemetry) {
-       v3_add_telemetry_cb(info, telemetry_cb, NULL);
-    }
+    v3_add_telemetry_cb(info->vm_info, telemetry_cb, NULL);
 #endif
   
     return 0;
index fc2df95..5e1d9c9 100644 (file)
@@ -34,7 +34,7 @@ static inline int activate_shadow_pt_32(struct guest_info * info) {
     shadow_cr3->pcd = guest_cr3->pcd;
   
 #ifdef CONFIG_SYMBIOTIC_SWAP
-    v3_swap_flush(info);
+    v3_swap_flush(info->vm_info);
 #endif
 
     return 0;
@@ -206,7 +206,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
     pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
     addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) +  PAGE_OFFSET(fault_addr);
 
-    struct v3_shadow_region * shdw_reg =  v3_get_shadow_region(info, guest_pa);
+    struct v3_shadow_region * shdw_reg =  v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
 
     if (shdw_reg == NULL) {
        // Inject a machine check in the guest
@@ -244,14 +244,14 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
            if (error_code.write == 0) {
-               info->swap_state.read_faults++;
+               info->vm_info->swap_state.read_faults++;
            } else {
-               info->swap_state.write_faults++;
+               info->vm_info->swap_state.write_faults++;
            }
 #endif
 
 
-           swp_pg_addr = v3_get_swapped_pg_addr(info,  guest_pte);
+           swp_pg_addr = v3_get_swapped_pg_addr(info->vm_info,  guest_pte);
 
            if (swp_pg_addr != 0) {
                PrintDebug("Swapped page address=%p\n", (void *)swp_pg_addr);
@@ -286,7 +286,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
                           (error_code.user == 0) ) ) {
                        addr_t swp_pg_pa = 0;
                        
-                       swp_pg_pa = v3_map_swp_page(info, shadow_pte, guest_pte, (void *)swp_pg_addr);
+                       swp_pg_pa = v3_map_swp_page(info->vm_info, shadow_pte, guest_pte, (void *)swp_pg_addr);
 
                        PrintDebug("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", 
                                   (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code);
@@ -303,7 +303,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
                        shadow_pte->page_base_addr = swp_pg_pa;
                        
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
-                       info->swap_state.mapped_pages++;
+                       info->vm_info->swap_state.mapped_pages++;
 #endif
                        //              PrintError("Swap fault handled\n");
                        return 0;
@@ -341,7 +341,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
 
        if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
            (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
       
            shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
 
@@ -427,7 +427,7 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * info,
     PrintDebug("Handling 4MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
     PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde);
 
-    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
+    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_fault_pa);
 
  
     if (shdw_reg == NULL) {
@@ -450,7 +450,7 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * info,
 
        if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || 
            (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
+           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_fault_pa);
 
            shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
 
index 421707a..af149fd 100644 (file)
@@ -408,7 +408,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault
 
     PrintDebug("Handling PTE fault\n");
 
-    struct v3_shadow_region * shdw_reg =  v3_get_shadow_region(info, guest_pa);
+    struct v3_shadow_region * shdw_reg =  v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
 
 
 
@@ -454,7 +454,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault
 
        if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
            (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
       
            shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
       
@@ -536,7 +536,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info,
     PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
     PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde);
 
-    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
+    struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_fault_pa);
 
  
     if (shdw_reg == NULL) {
@@ -560,7 +560,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info,
 
        if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || 
            (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
+           addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_fault_pa);
 
            shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
 
index 8395955..e3d22d0 100644 (file)
 #define SYMCALL_GS_MSR  0x539
 #define SYMCALL_FS_MSR  0x540
 
-
 static int msr_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
     struct guest_info * info = (struct guest_info *)priv_data;
-    struct v3_sym_state * state = &(info->sym_state);
+    struct v3_sym_state * state = &(info->vm_info->sym_state);
 
     switch (msr) {
        case SYM_PAGE_MSR:
            dst->value = state->guest_pg_addr;
            break;
+       default:
+           return -1;
+    }
+
+    return 0;
+}
+
+static int symcall_msr_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
+    struct guest_info * info = (struct guest_info *)priv_data;
+    struct v3_symcall_state * state = &(info->vm_info->sym_state.symcalls[info->cpu_id]);
+
+    switch (msr) {
        case SYMCALL_RIP_MSR:
            dst->value = state->sym_call_rip;
            break;
@@ -81,21 +92,21 @@ static int msr_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
 
 static int msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
     struct guest_info * info = (struct guest_info *)priv_data;
-    struct v3_sym_state * state = &(info->sym_state);
+    struct v3_sym_state * state = &(info->vm_info->sym_state);
 
     if (msr == SYM_PAGE_MSR) {
-       PrintDebug("Symbiotic MSR write for page %p\n", (void *)src.value);
+       PrintDebug("Symbiotic MSR write for page %p\n", (void *)(addr_t)src.value);
 
        if (state->active == 1) {
            // unmap page
-           struct v3_shadow_region * old_reg = v3_get_shadow_region(info, (addr_t)state->guest_pg_addr);
+           struct v3_shadow_region * old_reg = v3_get_shadow_region(info->vm_info, (addr_t)state->guest_pg_addr);
 
            if (old_reg == NULL) {
-               PrintError("Could not find previously active symbiotic page (%p)\n", (void *)state->guest_pg_addr);
+               PrintError("Could not find previously active symbiotic page (%p)\n", (void *)(addr_t)state->guest_pg_addr);
                return -1;
            }
 
-           v3_delete_shadow_region(info, old_reg);
+           v3_delete_shadow_region(info->vm_info, old_reg);
        }
 
        state->guest_pg_addr = src.value;
@@ -104,21 +115,9 @@ static int msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
        state->active = 1;
 
        // map page
-       v3_add_shadow_mem(info, (addr_t)state->guest_pg_addr, 
+       v3_add_shadow_mem(info->vm_info, (addr_t)state->guest_pg_addr, 
                          (addr_t)(state->guest_pg_addr + PAGE_SIZE_4KB - 1), 
                          state->sym_page_pa);
-
-
-    } else if (msr == SYMCALL_RIP_MSR) {
-       state->sym_call_rip = src.value;
-    } else if (msr == SYMCALL_RSP_MSR) {
-       state->sym_call_rsp = src.value;
-    } else if (msr == SYMCALL_CS_MSR) {
-       state->sym_call_cs = src.value;
-    } else if (msr == SYMCALL_GS_MSR) {
-       state->sym_call_gs = src.value;
-    } else if (msr == SYMCALL_FS_MSR) {
-       state->sym_call_fs = src.value;
     } else {
        PrintError("Invalid Symbiotic MSR write (0x%x)\n", msr);
        return -1;
@@ -127,6 +126,34 @@ static int msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
     return 0;
 }
 
+
+static int symcall_msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
+    struct guest_info * info = (struct guest_info *)priv_data;
+    struct v3_symcall_state * state = &(info->vm_info->sym_state.symcalls[info->cpu_id]);
+
+    switch (msr) {
+       case SYMCALL_RIP_MSR:
+           state->sym_call_rip = src.value;
+           break;
+       case SYMCALL_RSP_MSR:
+           state->sym_call_rsp = src.value;
+           break;
+       case SYMCALL_CS_MSR:
+           state->sym_call_cs = src.value;
+           break;
+       case SYMCALL_GS_MSR:
+           state->sym_call_gs = src.value;
+           break;
+       case SYMCALL_FS_MSR:
+           state->sym_call_fs = src.value;
+           break;
+       default:
+           PrintError("Invalid Symbiotic MSR write (0x%x)\n", msr);
+           return -1;
+    }
+    return 0;
+}
+
 static int cpuid_fn(struct guest_info * info, uint32_t cpuid, 
                    uint32_t * eax, uint32_t * ebx,
                    uint32_t * ecx, uint32_t * edx,
@@ -153,8 +180,8 @@ static int sym_call_err(struct guest_info * info, uint_t hcall_id, void * privat
 
 
 
-int v3_init_sym_iface(struct guest_info * info) {
-    struct v3_sym_state * state = &(info->sym_state);
+int v3_init_sym_iface(struct v3_vm_info * vm) {
+    struct v3_sym_state * state = &(vm->sym_state);
     memset(state, 0, sizeof(struct v3_sym_state));
 
     state->sym_page_pa = (addr_t)V3_AllocPages(1);
@@ -164,24 +191,24 @@ int v3_init_sym_iface(struct guest_info * info) {
     
     memcpy(&(state->sym_page->magic), "V3V", 3);
 
-    v3_hook_msr(info, SYM_PAGE_MSR, msr_read, msr_write, info);
+    v3_hook_msr(vm, SYM_PAGE_MSR, msr_read, msr_write, info);
 
-    v3_hook_cpuid(info, SYM_CPUID_NUM, cpuid_fn, info);
+    v3_hook_cpuid(vm, SYM_CPUID_NUM, cpuid_fn, info);
 
-    v3_hook_msr(info, SYMCALL_RIP_MSR, msr_read, msr_write, info);
-    v3_hook_msr(info, SYMCALL_RSP_MSR, msr_read, msr_write, info);
-    v3_hook_msr(info, SYMCALL_CS_MSR, msr_read, msr_write, info);
-    v3_hook_msr(info, SYMCALL_GS_MSR, msr_read, msr_write, info);
-    v3_hook_msr(info, SYMCALL_FS_MSR, msr_read, msr_write, info);
+    v3_hook_msr(vm, SYMCALL_RIP_MSR, symcall_msr_read, msr_write, info);
+    v3_hook_msr(vm, SYMCALL_RSP_MSR, symcall_msr_read, msr_write, info);
+    v3_hook_msr(vm, SYMCALL_CS_MSR, symcall_msr_read, msr_write, info);
+    v3_hook_msr(vm, SYMCALL_GS_MSR, symcall_msr_read, msr_write, info);
+    v3_hook_msr(vm, SYMCALL_FS_MSR, symcall_msr_read, msr_write, info);
 
-    v3_register_hypercall(info, SYM_CALL_RET_HCALL, sym_call_ret, NULL);
-    v3_register_hypercall(info, SYM_CALL_ERR_HCALL, sym_call_err, NULL);
+    v3_register_hypercall(vm, SYM_CALL_RET_HCALL, sym_call_ret, NULL);
+    v3_register_hypercall(vm, SYM_CALL_ERR_HCALL, sym_call_err, NULL);
 
     return 0;
 }
 
-int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
-    struct v3_sym_state * state = &(info->sym_state);
+int v3_sym_map_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
+    struct v3_sym_state * state = &(vm->sym_state);
     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
     uint_t major = dev_index / 8;
     uint_t minor = dev_index % 8;
@@ -202,8 +229,8 @@ int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev,
     return 0;
 }
 
-int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
-    struct v3_sym_state * state = &(info->sym_state);
+int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
+    struct v3_sym_state * state = &(vm->sym_state);
     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
     uint_t major = dev_index / 8;
     uint_t minor = dev_index % 8;
@@ -220,7 +247,7 @@ int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t de
 
 
 static int sym_call_err(struct guest_info * info, uint_t hcall_id, void * private_data) {
-    struct v3_sym_state * state = (struct v3_sym_state *)&(info->sym_state);
+    struct v3_symcall_state * state = (struct v3_symcall_state *)&(info->sym_state.symcalls[info->cpu_id]);
 
     PrintError("sym call error\n");
 
@@ -236,7 +263,7 @@ static int sym_call_err(struct guest_info * info, uint_t hcall_id, void * privat
 }
 
 static int sym_call_ret(struct guest_info * info, uint_t hcall_id, void * private_data) {
-    struct v3_sym_state * state = (struct v3_sym_state *)&(info->sym_state);
+    struct v3_symcall_state * state = (struct v3_symcall_state *)&(info->vm_info->sym_state.symcalls[info->cpu_id]);
 
     //    PrintError("Return from sym call (ID=%x)\n", hcall_id);
     //   v3_print_guest_state(info);
@@ -247,8 +274,9 @@ static int sym_call_ret(struct guest_info * info, uint_t hcall_id, void * privat
 }
 
 static int execute_symcall(struct guest_info * info) {
+    struct v3_symcall_state * state = (struct v3_symcall_state *)&(info->vm_info->sym_state.symcalls[info->cpu_id]);
 
-    while (info->sym_state.sym_call_returned == 0) {
+    while (state->sym_call_returned == 0) {
        if (v3_vm_enter(info) == -1) {
            PrintError("Error in Sym call\n");
            return -1;
@@ -263,7 +291,8 @@ int v3_sym_call(struct guest_info * info,
                uint64_t call_num, sym_arg_t * arg0, 
                sym_arg_t * arg1, sym_arg_t * arg2,
                sym_arg_t * arg3, sym_arg_t * arg4) {
-    struct v3_sym_state * state = (struct v3_sym_state *)&(info->sym_state);
+    struct v3_sym_state * sym_state = (struct v3_sym_state *)&(info->vm_info->sym_sate);
+    struct v3_symcall_state * state = (struct v3_symcall_state *)&(sym_state->symcalls[info->cpu_id]);
     struct v3_sym_context * old_ctx = (struct v3_sym_context *)&(state->old_ctx);
     struct v3_segment sym_cs;
     struct v3_segment sym_ss;
@@ -272,7 +301,7 @@ int v3_sym_call(struct guest_info * info,
     //   PrintDebug("Making Sym call\n");
     //    v3_print_guest_state(info);
 
-    if ((state->sym_page->sym_call_enabled == 0) ||
+    if ((sym_state->sym_page->sym_call_enabled == 0) ||
        (state->sym_call_active == 1)) {
        return -1;
     }
index 5e1aa80..80f6162 100644 (file)
@@ -71,7 +71,7 @@ static inline uint32_t get_dev_index(pte32_t * pte) {
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
 static void telemetry_cb(struct guest_info * info, void * private_data, char * hdr) {
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+    struct v3_sym_swap_state * swap_state = &(info->vm_info->swap_state);
 
     V3_Print("%sSymbiotic Swap:\n", hdr);
     V3_Print("%s\tRead faults=%d\n", hdr, swap_state->read_faults);
@@ -83,15 +83,15 @@ static void telemetry_cb(struct guest_info * info, void * private_data, char * h
 #endif
 
 
-int v3_init_sym_swap(struct guest_info * info) {
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+int v3_init_sym_swap(struct v3_vm_info * vm) {
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
 
     memset(swap_state, 0, sizeof(struct v3_sym_swap_state));
     swap_state->shdw_ptr_ht = v3_create_htable(0, swap_hash_fn, swap_eq_fn);
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
     if (info->enable_telemetry) {
-       v3_add_telemetry_cb(info, telemetry_cb, NULL);
+       v3_add_telemetry_cb(vm, telemetry_cb, NULL);
     }
 #endif
 
@@ -101,9 +101,9 @@ int v3_init_sym_swap(struct guest_info * info) {
 }
 
 
-int v3_register_swap_disk(struct guest_info * info, int dev_index, 
+int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, 
                          struct v3_swap_ops * ops, void * private_data) {
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
 
     swap_state->devs[dev_index].present = 1;
     swap_state->devs[dev_index].private_data = private_data;
@@ -115,9 +115,9 @@ int v3_register_swap_disk(struct guest_info * info, int dev_index,
 
 
 
-int v3_swap_in_notify(struct guest_info * info, int pg_index, int dev_index) {
+int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index) {
     struct list_head * shdw_ptr_list = NULL;
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
     struct shadow_pointer * tmp_shdw_ptr = NULL;
     struct shadow_pointer * shdw_ptr = NULL;
     struct swap_pte guest_pte = {0, dev_index, pg_index};
@@ -146,8 +146,8 @@ int v3_swap_in_notify(struct guest_info * info, int pg_index, int dev_index) {
 
 
 
-int v3_swap_flush(struct guest_info * info) {
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+int v3_swap_flush(struct v3_vm_info * vm) {
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
     struct hashtable_iter * ht_iter = v3_create_htable_iter(swap_state->shdw_ptr_ht);
 
     //    PrintDebug("Flushing Symbiotic Swap table\n");
@@ -209,8 +209,8 @@ int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_p
 
 
 
-addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * guest_pte) {
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+addr_t v3_get_swapped_pg_addr(struct v3_vm_info * vm, pte32_t * guest_pte) {
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
     int dev_index = get_dev_index(guest_pte);
     struct v3_swap_dev * swp_dev = &(swap_state->devs[dev_index]);
 
@@ -223,9 +223,9 @@ addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * guest_pte) {
 }
 
 
-addr_t v3_map_swp_page(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr) {
+addr_t v3_map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr) {
     struct list_head * shdw_ptr_list = NULL;
-    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+    struct v3_sym_swap_state * swap_state = &(vm->swap_state);
     struct shadow_pointer * shdw_ptr = NULL;
 
 
index 898850a..8d94db0 100644 (file)
 #ifdef CONFIG_TELEMETRY_GRANULARITY
 #define DEFAULT_GRANULARITY CONFIG_TELEMETRY_GRANULARITY
 #else 
-#define DEFAULT_GRANULARITY 50000
+#define DEFAULT_GRANULARITY 500
 #endif
 
 
 
 struct telemetry_cb {
     
-    void (*telemetry_fn)(struct guest_info * info, void * private_data, char * hdr);
+    void (*telemetry_fn)(struct v3_vm_info * vm, void * private_data, char * hdr);
 
     void * private_data;
     struct list_head cb_node;
@@ -50,25 +50,33 @@ struct exit_event {
 };
 
 
-void v3_init_telemetry(struct guest_info * info) {
-    struct v3_telemetry_state * telemetry = &(info->telemetry);
+void v3_init_telemetry(struct v3_vm_info * vm) {
+    struct v3_telemetry_state * telemetry = &(vm->telemetry);
 
-    telemetry->exit_cnt = 0;
-    telemetry->vmm_start_tsc = 0;
-    telemetry->prev_tsc = 0;
     telemetry->invoke_cnt = 0;
     telemetry->granularity = DEFAULT_GRANULARITY;
 
+    telemetry->prev_tsc = 0;
 
-    telemetry->exit_root.rb_node = NULL;
     INIT_LIST_HEAD(&(telemetry->cb_list));
 }
 
+void v3_init_core_telemetry(struct guest_info * core) {
+    struct v3_core_telemetry * telemetry = &(core->core_telem);
+
+    telemetry->exit_cnt = 0;
+    telemetry->vmm_start_tsc = 0;
+
+    telemetry->vm_telem = &(core->vm_info->telemetry);
+
+    telemetry->exit_root.rb_node = NULL;
+}
+
 
 
 static inline struct exit_event * __insert_event(struct guest_info * info, 
                                                 struct exit_event * evt) {
-    struct rb_node ** p = &(info->telemetry.exit_root.rb_node);
+    struct rb_node ** p = &(info->core_telem.exit_root.rb_node);
     struct rb_node * parent = NULL;
     struct exit_event * tmp_evt = NULL;
 
@@ -97,14 +105,14 @@ static inline struct exit_event * insert_event(struct guest_info * info,
        return ret;
     }
 
-    v3_rb_insert_color(&(evt->tree_node), &(info->telemetry.exit_root));
+    v3_rb_insert_color(&(evt->tree_node), &(info->core_telem.exit_root));
 
     return NULL;
 }
 
 
 static struct exit_event * get_exit(struct guest_info * info, uint_t exit_code) {
-    struct rb_node * n = info->telemetry.exit_root.rb_node;
+    struct rb_node * n = info->core_telem.exit_root.rb_node;
     struct exit_event * evt = NULL;
 
     while (n) {
@@ -134,12 +142,12 @@ static inline struct exit_event * create_exit(uint_t exit_code) {
 }
 
 void v3_telemetry_start_exit(struct guest_info * info) {
-    rdtscll(info->telemetry.vmm_start_tsc);
+    rdtscll(info->core_telem.vmm_start_tsc);
 }
 
 
 void v3_telemetry_end_exit(struct guest_info * info, uint_t exit_code) {
-    struct v3_telemetry_state * telemetry = &(info->telemetry);
+    struct v3_core_telemetry * telemetry = &(info->core_telem);
     struct exit_event * evt = NULL;
     uint64_t end_tsc = 0;
 
@@ -160,18 +168,18 @@ void v3_telemetry_end_exit(struct guest_info * info, uint_t exit_code) {
 
 
     // check if the exit count has expired
-    if ((telemetry->exit_cnt % telemetry->granularity) == 0) {
-       v3_print_telemetry(info);
+    if ((telemetry->exit_cnt % telemetry->vm_telem->granularity) == 0) {
+       v3_print_telemetry(info->vm_info);
     }
 }
 
 
 
 
-void v3_add_telemetry_cb(struct guest_info * info, 
-                        void (*telemetry_fn)(struct guest_info * info, void * private_data, char * hdr),
+void v3_add_telemetry_cb(struct v3_vm_info * vm, 
+                        void (*telemetry_fn)(struct v3_vm_info * vm, void * private_data, char * hdr),
                         void * private_data) {
-    struct v3_telemetry_state * telemetry = &(info->telemetry);
+    struct v3_telemetry_state * telemetry = &(vm->telemetry);
     struct telemetry_cb * cb = (struct telemetry_cb *)V3_Malloc(sizeof(struct telemetry_cb));
 
     cb->private_data = private_data;
@@ -182,10 +190,11 @@ void v3_add_telemetry_cb(struct guest_info * info,
 
 
 
-void v3_print_telemetry(struct guest_info * info) {
-    struct v3_telemetry_state * telemetry = &(info->telemetry);
+void v3_print_telemetry(struct v3_vm_info * vm) {
+    struct v3_telemetry_state * telemetry = &(vm->telemetry);
     uint64_t invoke_tsc = 0;
     char hdr_buf[32];
+    int i;
 
     rdtscll(invoke_tsc);
 
@@ -193,11 +202,15 @@ void v3_print_telemetry(struct guest_info * info) {
 
     V3_Print("%stelemetry window tsc cnt: %d\n", hdr_buf, (uint32_t)(invoke_tsc - telemetry->prev_tsc));
 
+
     // Exit Telemetry
-    {
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * core = &(vm->cores[i]);
        struct exit_event * evt = NULL;
-       struct rb_node * node = v3_rb_first(&(info->telemetry.exit_root));
+       struct rb_node * node = v3_rb_first(&(core->core_telem.exit_root));
        
+       V3_Print("Exit information for Core %d\n", core->cpu_id);
+
        do {
            evt = rb_entry(node, struct exit_event, tree_node);
            const char * code_str = vmexit_code_to_str(evt->exit_code);
@@ -218,7 +231,7 @@ void v3_print_telemetry(struct guest_info * info) {
        struct telemetry_cb * cb = NULL;
 
        list_for_each_entry(cb, &(telemetry->cb_list), cb_node) {
-           cb->telemetry_fn(info, cb->private_data, hdr_buf);
+           cb->telemetry_fn(vm, cb->private_data, hdr_buf);
        }
     }
 
index 319d158..44d5d02 100644 (file)
@@ -60,16 +60,32 @@ int v3_remove_timer(struct guest_info * info, struct vm_timer * timer) {
 
 
 
-void v3_update_time(struct guest_info * info, ullong_t cycles) {
+void v3_update_time(struct guest_info * info, uint64_t cycles) {
     struct vm_timer * tmp_timer;
-  
+    
+    //   cycles *= 8;
+
+//    cycles /= 150;
+
     info->time_state.guest_tsc += cycles;
 
     list_for_each_entry(tmp_timer, &(info->time_state.timers), timer_link) {
-       tmp_timer->ops->update_time(cycles, info->time_state.cpu_freq, tmp_timer->private_data);
+       tmp_timer->ops->update_time(info, cycles, info->time_state.cpu_freq, tmp_timer->private_data);
     }
   
 
 
     //info->time_state.pending_cycles = 0;
 }
+
+void v3_advance_time(struct guest_info * core) {
+    struct vm_timer * tmp_timer;
+
+
+    list_for_each_entry(tmp_timer, &(core->time_state.timers), timer_link) {
+       tmp_timer->ops->advance_timer(core, tmp_timer->private_data);
+    }
+  
+
+
+}
index e632a4f..f3641be 100644 (file)
@@ -363,6 +363,7 @@ static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) {
     return 0;
 }
 
+#if 0
 // checks for circular entity references, returns non-zero if no circular
 // references are found, zero otherwise
 static int v3_xml_ent_ok(char * name, char * s, char ** ent) {
@@ -390,6 +391,7 @@ static int v3_xml_ent_ok(char * name, char * s, char ** ent) {
        }
     }
 }
+#endif
 
 
 
index aba5656..f3f51f1 100644 (file)
@@ -199,8 +199,7 @@ static int init_vmcs_bios(struct guest_info * info, struct vmx_data * vmx_state)
 
     /********** Setup and VMX Control Fields from MSR ***********/
     /* Setup IO map */
-    v3_init_vmx_io_map(info);
-    v3_init_vmx_msr_map(info);
+
 
     struct v3_msr tmp_msr;
 
@@ -220,11 +219,12 @@ static int init_vmcs_bios(struct guest_info * info, struct vmx_data * vmx_state)
     vmx_state->pri_proc_ctrls.use_msr_bitmap = 1;
     vmx_state->pri_proc_ctrls.pause_exit = 1;
 
-    vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_A_ADDR, (addr_t)V3_PAddr(info->io_map.arch_data));
+    vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_A_ADDR, (addr_t)V3_PAddr(info->vm_info->io_map.arch_data));
     vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_B_ADDR, 
-            (addr_t)V3_PAddr(info->io_map.arch_data) + PAGE_SIZE_4KB); 
+            (addr_t)V3_PAddr(info->vm_info->io_map.arch_data) + PAGE_SIZE_4KB);
+
 
-    vmx_ret |= check_vmcs_write(VMCS_MSR_BITMAP, (addr_t)V3_PAddr(info->msr_map.arch_data));
+    vmx_ret |= check_vmcs_write(VMCS_MSR_BITMAP, (addr_t)V3_PAddr(info->vm_info->msr_map.arch_data));
 
     v3_get_msr(VMX_EXIT_CTLS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
     vmx_state->exit_ctrls.value = tmp_msr.lo;
@@ -453,12 +453,12 @@ static int update_irq_exit_state(struct guest_info * info) {
 
     check_vmcs_read(VMCS_IDT_VECTOR_INFO, &(idt_vec_info.value));
 
-    if ((info->intr_state.irq_started == 1) && (idt_vec_info.valid == 0)) {
+    if ((info->intr_core_state.irq_started == 1) && (idt_vec_info.valid == 0)) {
 #ifdef CONFIG_DEBUG_INTERRUPTS
         PrintDebug("Calling v3_injecting_intr\n");
 #endif
-        info->intr_state.irq_started = 0;
-        v3_injecting_intr(info, info->intr_state.irq_vector, V3_EXTERNAL_IRQ);
+        info->intr_core_state.irq_started = 0;
+        v3_injecting_intr(info, info->intr_core_state.irq_vector, V3_EXTERNAL_IRQ);
     }
 
     return 0;
@@ -466,11 +466,11 @@ static int update_irq_exit_state(struct guest_info * info) {
 
 static int update_irq_entry_state(struct guest_info * info) {
     struct vmx_exit_idt_vec_info idt_vec_info;
-    struct vmcs_interrupt_state intr_state;
+    struct vmcs_interrupt_state intr_core_state;
     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
 
     check_vmcs_read(VMCS_IDT_VECTOR_INFO, &(idt_vec_info.value));
-    check_vmcs_read(VMCS_GUEST_INT_STATE, &(intr_state));
+    check_vmcs_read(VMCS_GUEST_INT_STATE, &(intr_core_state));
 
     /* Check for pending exceptions to inject */
     if (v3_excp_pending(info)) {
@@ -501,9 +501,9 @@ static int update_irq_entry_state(struct guest_info * info) {
         v3_injecting_excp(info, int_info.vector);
 
     } else if ((((struct rflags *)&(info->ctrl_regs.rflags))->intr == 1) && 
-              (intr_state.val == 0)) {
+              (intr_core_state.val == 0)) {
        
-        if ((info->intr_state.irq_started == 1) && (idt_vec_info.valid == 1)) {
+        if ((info->intr_core_state.irq_started == 1) && (idt_vec_info.valid == 1)) {
 
 #ifdef CONFIG_DEBUG_INTERRUPTS
             PrintDebug("IRQ pending from previous injection\n");
@@ -526,21 +526,21 @@ static int update_irq_entry_state(struct guest_info * info) {
 
             switch (v3_intr_pending(info)) {
                 case V3_EXTERNAL_IRQ: {
-                    info->intr_state.irq_vector = v3_get_intr(info); 
-                    ent_int.vector = info->intr_state.irq_vector;
+                    info->intr_core_state.irq_vector = v3_get_intr(info); 
+                    ent_int.vector = info->intr_core_state.irq_vector;
                     ent_int.type = 0;
                     ent_int.error_code = 0;
                     ent_int.valid = 1;
 
 #ifdef CONFIG_DEBUG_INTERRUPTS
                     PrintDebug("Injecting Interrupt %d at exit %u(EIP=%p)\n", 
-                              info->intr_state.irq_vector, 
+                              info->intr_core_state.irq_vector, 
                               (uint32_t)info->num_exits, 
                               (void *)info->rip);
 #endif
 
                     check_vmcs_write(VMCS_ENTRY_INT_INFO, ent_int.value);
-                    info->intr_state.irq_started = 1;
+                    info->intr_core_state.irq_started = 1;
 
                     break;
                 }
@@ -645,7 +645,7 @@ int v3_vmx_enter(struct guest_info * info) {
 
 
 #ifdef CONFIG_SYMBIOTIC
-    if (info->sym_state.sym_call_active == 0) {
+    if (info->vm_info->sym_state.symcalls[info->cpu_id].sym_call_active == 0) {
        update_irq_entry_state(info);
     }
 #else 
@@ -660,8 +660,8 @@ int v3_vmx_enter(struct guest_info * info) {
 
     rdtscll(info->time_state.cached_host_tsc);
 
-    if (info->run_state == VM_STOPPED) {
-       info->run_state = VM_RUNNING;
+    if (info->vm_info->run_state == VM_STOPPED) {
+       info->vm_info->run_state = VM_RUNNING;
        ret = v3_vmx_launch(&(info->vm_regs), info, &(info->ctrl_regs));
     } else {
        ret = v3_vmx_resume(&(info->vm_regs), info, &(info->ctrl_regs));
@@ -707,7 +707,7 @@ int v3_vmx_enter(struct guest_info * info) {
 
 
 #ifdef CONFIG_SYMBIOTIC
-    if (info->sym_state.sym_call_active == 0) {
+    if (info->vm_info->sym_state.symcalls[info->cpu_id].sym_call_active == 0) {
        update_irq_exit_state(info);
     }
 #else
@@ -794,7 +794,7 @@ void v3_init_vmx_cpu(int cpu_id) {
     uint64_t ret = 0;
 
     v3_get_msr(VMX_CR4_FIXED0_MSR,&(tmp_msr.hi),&(tmp_msr.lo));
-    
+#ifdef __V3_64BIT__
     __asm__ __volatile__ (
                          "movq %%cr4, %%rbx;"
                          "orq  $0x00002000, %%rbx;"
@@ -823,6 +823,38 @@ void v3_init_vmx_cpu(int cpu_id) {
                          :
                          : "%rbx"
                          );
+#elif __V3_32BIT__
+    __asm__ __volatile__ (
+                         "movq %%cr4, %%ecx;"
+                         "orq  $0x00002000, %%ecx;"
+                         "movq %%ecx, %0;"
+                         : "=m"(ret) 
+                         :
+                         : "%ecx"
+                         );
+
+    if ((~ret & tmp_msr.value) == 0) {
+        __asm__ __volatile__ (
+                             "movq %0, %%cr4;"
+                             :
+                             : "q"(ret)
+                             );
+    } else {
+        PrintError("Invalid CR4 Settings!\n");
+        return;
+    }
+
+    __asm__ __volatile__ (
+                         "movq %%cr0, %%ecx; "
+                         "orq  $0x00000020,%%ecx; "
+                         "movq %%ecx, %%cr0;"
+                         :
+                         :
+                         : "%ecx"
+                         );
+
+#endif
+
     //
     // Should check and return Error here.... 
 
index 1da8a58..60b3134 100644 (file)
@@ -52,7 +52,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf
       v3_print_vmcs();
     */
 #ifdef CONFIG_TELEMETRY
-    if (info->enable_telemetry) {
+    if (info->vm_info->enable_telemetry) {
        v3_telemetry_start_exit(info);
     }
 #endif
@@ -223,7 +223,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf
     }
 
 #ifdef CONFIG_TELEMETRY
-    if (info->enable_telemetry) {
+    if (info->vm_info->enable_telemetry) {
         v3_telemetry_end_exit(info, exit_info->exit_reason);
     }
 #endif
index 309d2cf..4e94f69 100644 (file)
@@ -32,8 +32,8 @@
 
 
 /* Same as SVM */
-static int update_map(struct guest_info * info, uint16_t port, int hook_read, int hook_write) {
-    uchar_t * bitmap = (uint8_t *)(info->io_map.arch_data);
+static int update_map(struct v3_vm_info * vm, uint16_t port, int hook_read, int hook_write) {
+    uchar_t * bitmap = (uint8_t *)(vm->io_map.arch_data);
     int major = port / 8;
     int minor = port % 8;
 
@@ -46,24 +46,24 @@ static int update_map(struct guest_info * info, uint16_t port, int hook_read, in
     return 0;
 }
 
-int v3_init_vmx_io_map(struct guest_info * info) {
-    info->io_map.update_map = update_map;
+int v3_init_vmx_io_map(struct v3_vm_info * vm) {
+    vm->io_map.update_map = update_map;
     
-    info->io_map.arch_data = V3_VAddr(V3_AllocPages(2));
-    memset(info->io_map.arch_data, 0, PAGE_SIZE_4KB * 2);
+    vm->io_map.arch_data = V3_VAddr(V3_AllocPages(2));
+    memset(vm->io_map.arch_data, 0, PAGE_SIZE_4KB * 2);
 
-    v3_refresh_io_map(info);
+    v3_refresh_io_map(vm);
 
     return 0;
 }
 
-int v3_handle_vmx_io_in(struct guest_info * info, struct vmx_exit_info * exit_info) {
+int v3_handle_vmx_io_in(struct guest_info * core, struct vmx_exit_info * exit_info) {
     struct vmx_exit_io_qual io_qual = *(struct vmx_exit_io_qual *)&(exit_info->exit_qual);;
     struct v3_io_hook * hook = NULL;
     int read_size = 0;
 
 
-    hook = v3_get_io_hook(info, io_qual.port);
+    hook = v3_get_io_hook(core->vm_info, io_qual.port);
 
     if (hook == NULL) {
         PrintError("Hook not present for IN on port %x\n", io_qual.port);
@@ -74,18 +74,18 @@ int v3_handle_vmx_io_in(struct guest_info * info, struct vmx_exit_info * exit_in
 
     PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_qual.port, io_qual.port);
 
-    if (hook->read(io_qual.port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
+    if (hook->read(core, io_qual.port, &(core->vm_regs.rax), read_size, hook->priv_data) != read_size) {
         PrintError("Read failure for IN on port %x\n", io_qual.port);
         return -1;
     }
 
 
-    info->rip += exit_info->instr_len;
+    core->rip += exit_info->instr_len;
 
     return 0;
 }
 
-int v3_handle_vmx_io_ins(struct guest_info * info, struct vmx_exit_info * exit_info) {
+int v3_handle_vmx_io_ins(struct guest_info * core, struct vmx_exit_info * exit_info) {
     struct vmx_exit_io_qual io_qual = *(struct vmx_exit_io_qual *)&(exit_info->exit_qual);;
     struct v3_io_hook * hook = NULL;
     int read_size = 0;
@@ -93,9 +93,9 @@ int v3_handle_vmx_io_ins(struct guest_info * info, struct vmx_exit_info * exit_i
     addr_t host_addr = 0;
     int rdi_change = 0;
     ulong_t rep_num = 1;
-    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);
+    struct rflags * flags = (struct rflags *)&(core->ctrl_regs.rflags);
 
-    hook = v3_get_io_hook(info, io_qual.port);
+    hook = v3_get_io_hook(core->vm_info, io_qual.port);
 
     if (hook == NULL) {
         PrintError("Hook not present for INS on port 0x%x\n", io_qual.port);
@@ -110,11 +110,11 @@ int v3_handle_vmx_io_ins(struct guest_info * info, struct vmx_exit_info * exit_i
         struct vmx_exit_io_instr_info instr_info = *(struct vmx_exit_io_instr_info *)&(exit_info->instr_info);
 
         if (instr_info.addr_size == 0) {
-            rep_num = info->vm_regs.rcx & 0xffff;
+            rep_num = core->vm_regs.rcx & 0xffff;
         } else if(instr_info.addr_size == 1) {
-            rep_num = info->vm_regs.rcx & 0xffffffff;
+            rep_num = core->vm_regs.rcx & 0xffffffff;
         } else if(instr_info.addr_size == 2) {
-            rep_num = info->vm_regs.rcx & 0xffffffffffffffffLL;
+            rep_num = core->vm_regs.rcx & 0xffffffffffffffffLL;
         } else {
             PrintDebug("Unknown INS address size!\n");
             return -1;
@@ -131,40 +131,40 @@ int v3_handle_vmx_io_ins(struct guest_info * info, struct vmx_exit_info * exit_i
 
 
 
-    if (guest_va_to_host_va(info, guest_va, &host_addr) == -1) {
+    if (guest_va_to_host_va(core, guest_va, &host_addr) == -1) {
         PrintError("Could not convert Guest VA to host VA\n");
         return -1;
     }
 
     do {
-        if (hook->read(io_qual.port, (char *)host_addr, read_size, hook->priv_data) != read_size) {
+        if (hook->read(core, io_qual.port, (char *)host_addr, read_size, hook->priv_data) != read_size) {
             PrintError("Read Failure for INS on port 0x%x\n", io_qual.port);
             return -1;
         }
 
         host_addr += rdi_change;
-        info->vm_regs.rdi += rdi_change;
+        core->vm_regs.rdi += rdi_change;
 
         if (io_qual.rep) {
-            info->vm_regs.rcx--;
+            core->vm_regs.rcx--;
         }
         
     } while (--rep_num > 0);
 
 
-    info->rip += exit_info->instr_len;
+    core->rip += exit_info->instr_len;
 
     return 0;
 }
 
 
 
-int v3_handle_vmx_io_out(struct guest_info * info, struct vmx_exit_info * exit_info) {
+int v3_handle_vmx_io_out(struct guest_info * core, struct vmx_exit_info * exit_info) {
     struct vmx_exit_io_qual io_qual = *(struct vmx_exit_io_qual *)&(exit_info->exit_qual);
     struct v3_io_hook * hook = NULL;
     int write_size = 0;
 
-    hook =  v3_get_io_hook(info, io_qual.port);
+    hook =  v3_get_io_hook(core->vm_info, io_qual.port);
 
     if (hook == NULL) {
         PrintError("Hook not present for out on port %x\n", io_qual.port);
@@ -175,21 +175,21 @@ int v3_handle_vmx_io_out(struct guest_info * info, struct vmx_exit_info * exit_i
     
     PrintDebug("OUT of %d bytes on port %d (0x%x)\n", write_size, io_qual.port, io_qual.port);
 
-    if (hook->write(io_qual.port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
+    if (hook->write(core, io_qual.port, &(core->vm_regs.rax), write_size, hook->priv_data) != write_size) {
         PrintError("Write failure for out on port %x\n",io_qual.port);
         return -1;
     }
 
 
 
-    info->rip += exit_info->instr_len;
+    core->rip += exit_info->instr_len;
 
     return 0;
 }
 
 
 
-int v3_handle_vmx_io_outs(struct guest_info * info, struct vmx_exit_info * exit_info) {
+int v3_handle_vmx_io_outs(struct guest_info * core, struct vmx_exit_info * exit_info) {
     struct vmx_exit_io_qual io_qual = *(struct vmx_exit_io_qual *)&(exit_info->exit_qual);
     struct v3_io_hook * hook = NULL;
     int write_size;
@@ -197,9 +197,9 @@ int v3_handle_vmx_io_outs(struct guest_info * info, struct vmx_exit_info * exit_
     addr_t host_addr;
     int rsi_change;
     ulong_t rep_num = 1;
-    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);
+    struct rflags * flags = (struct rflags *)&(core->ctrl_regs.rflags);
 
-    hook = v3_get_io_hook(info, io_qual.port);
+    hook = v3_get_io_hook(core->vm_info, io_qual.port);
 
     if (hook == NULL) {
         PrintError("Hook not present for OUTS on port 0x%x\n", io_qual.port);
@@ -215,11 +215,11 @@ int v3_handle_vmx_io_outs(struct guest_info * info, struct vmx_exit_info * exit_
         struct vmx_exit_io_instr_info instr_info = *(struct vmx_exit_io_instr_info *)&(exit_info->instr_info);
 
         if (instr_info.addr_size == 0) {
-            rep_num = info->vm_regs.rcx & 0xffff;
+            rep_num = core->vm_regs.rcx & 0xffff;
         } else if(instr_info.addr_size == 1) {
-            rep_num = info->vm_regs.rcx & 0xffffffff;
+            rep_num = core->vm_regs.rcx & 0xffffffff;
         } else if(instr_info.addr_size == 2) {
-            rep_num = info->vm_regs.rcx & 0xffffffffffffffffLL;
+            rep_num = core->vm_regs.rcx & 0xffffffffffffffffLL;
         } else {
             PrintDebug("Unknown INS address size!\n");
             return -1;
@@ -236,28 +236,28 @@ int v3_handle_vmx_io_outs(struct guest_info * info, struct vmx_exit_info * exit_
 
     PrintDebug("OUTS size=%d for %ld steps\n", write_size, rep_num);
 
-    if (guest_va_to_host_va(info, guest_va, &host_addr) == -1) {
+    if (guest_va_to_host_va(core, guest_va, &host_addr) == -1) {
         PrintError("Could not convert guest VA to host VA\n");
         return -1;
     }
 
     do {
-       if (hook->write(io_qual.port, (char *)host_addr, write_size, hook->priv_data) != write_size) {
+       if (hook->write(core, io_qual.port, (char *)host_addr, write_size, hook->priv_data) != write_size) {
            PrintError("Read failure for INS on port 0x%x\n", io_qual.port);
            return -1;
        }
 
        host_addr += rsi_change;
-       info->vm_regs.rsi += rsi_change;
+       core->vm_regs.rsi += rsi_change;
 
        if (io_qual.rep) {
-           --info->vm_regs.rcx;
+           --core->vm_regs.rcx;
        }
 
     } while (--rep_num > 0);
 
 
-    info->rip += exit_info->instr_len;
+    core->rip += exit_info->instr_len;
 
     return 0;
 }
index 2d9df85..4368c9c 100644 (file)
@@ -42,7 +42,7 @@ static int get_bitmap_index(uint_t msr)
 }
 
 /* Same as SVM */
-static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int hook_writes) {
+static int update_map(struct v3_vm_info * vm, uint_t msr, int hook_reads, int hook_writes) {
 
     int index = get_bitmap_index(msr);
     uint_t major = index / 8;
@@ -50,7 +50,7 @@ static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int
     uchar_t mask = 0x1;
     uint8_t read_val = (hook_reads) ? 0x1 : 0x0;
     uint8_t write_val = (hook_writes) ? 0x1 : 0x0;
-    uint8_t * bitmap = (uint8_t *)(info->msr_map.arch_data);
+    uint8_t * bitmap = (uint8_t *)(vm->msr_map.arch_data);
 
 
     *(bitmap + major) &= ~(mask << minor);
@@ -63,15 +63,15 @@ static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int
     return 0;
 }
 
-int v3_init_vmx_msr_map(struct guest_info * info) {
-    struct v3_msr_map * msr_map = &(info->msr_map);
+int v3_init_vmx_msr_map(struct v3_vm_info * vm) {
+    struct v3_msr_map * msr_map = &(vm->msr_map);
 
     msr_map->update_map = update_map;
     
     msr_map->arch_data = V3_VAddr(V3_AllocPages(1));
     memset(msr_map->arch_data, 0, PAGE_SIZE_4KB);
     
-    v3_refresh_msr_map(info);
+    v3_refresh_msr_map(vm);
     
     return 0;
 }
index c022473..11326fc 100644 (file)
@@ -3,13 +3,15 @@
 <vm class="PC"> 
 
        <!-- Memory in MB -->
-       <memory>1024</memory> 
+       <memory>256</memory> 
 
        <!-- Basic VMM system flags -->
        <telemetry>enable</telemetry>
        <paging>nested</paging>
        <schedule_hz>100</schedule_hz>
 
+       <cores count="1"><core /></cores>
+
 
        <!-- Memory redirections -->
        <!-- Redirects a guest's memory region to a host physical address -->
@@ -27,7 +29,7 @@
        <!-- This is where you add disk images -->
        <files>
                <!-- The file 'id' is used as a reference for other configuration components -->
-               <file id="boot-cd" filename="/home/jarusl/image.iso" />
+               <file id="boot-cd" filename="/home/ktpedre/google_code/smp_guest/kitten_guest/arch/x86_64/boot/image.iso" />
                <!--<file id="harddisk" filename="firefox.img" />-->
        </files>
 
                <device id="8254_PIT" name="PIT" />
                <device id="BOCHS_DEBUG" name="bochs debug"/>
                <device id="OS_DEBUG" name="os debug" />
+<!--
                <device id="LAPIC" name="apic"/>
                <device id="IOAPIC" name="ioapic">
                        <irq_bus>apic</irq_bus>
                </device>
+-->
 
 <!--
                <device id="CGA_VIDEO" name="cga" passthrough="enable" />
                        <bus>pci0</bus>
                </device>
 
-               <device id="LNX_VIRTIO_SYM" name="sym_pci">
+               <device id="IDE" name="ide">
                        <bus>pci0</bus>
+                       <controller>southbridge</controller>
                </device>
 
-               <device id="LNX_VIRTIO_BLK" name="blk_virtio">
+<!--
+               <device id="LNX_VIRTIO_SYM" name="sym_pci">
                        <bus>pci0</bus>
                </device>
 
-               <device id="LNX_VIRTIO_BALLOON" name="balloon">
+               <device id="LNX_VIRTIO_BLK" name="blk_virtio">
                        <bus>pci0</bus>
                </device>
 
-               <device id="IDE" name="ide">
+               <device id="LNX_VIRTIO_BALLOON" name="balloon">
                        <bus>pci0</bus>
-                       <controller>southbridge</controller>
                </device>
 
                <device id="PCI_PASSTHROUGH" name="e1000">
@@ -94,6 +99,7 @@
                        <device_id>0x107c</device_id>
                        <irq>64</irq>
                </device>
+-->
 
 
                <!-- This is a Storage Backend that connects to a frontend -->
                        </frontend>
                </device>
 
+<!---
                <device id="SYM_SWAP" name="sym swap">
                        <frontend tag="blk_virtio" />
                        <size>150</size>
                </device>
+-->