merge with xen-unstable.hg

This commit is contained in:
Alex Williamson committed 2007-04-11 07:30:02 -06:00
commit ec0addc57f
37 files changed
+1135 -192

No files matched your search

+11 -16
View File
@@ -41,22 +41,17 @@ Date: \datestring{}
\end{center}
\vspace{.5cm}
\begin{large}
\textbf{Contributors:}
\begin{multicols}{2}{
Stefan Berger, IBM \\
Daniel Berrang\'e, Red Hat \\
Gareth Bestor, IBM \\
Hollis Blanchard, IBM \\
Mike Day, IBM \\
Jim Fehlig, Novell \\
Jon Harrop, XenSource \\
Vincent Hanquez, XenSource \\
John Levon, Sun Microsystems \\
Jon Ludlam, XenSource \\
Alastair Tse, XenSource \\
Daniel Veillard, Red Hat \\
Tom Wilkie, University of Cambridge}
\end{multicols}
\textbf{Contributors:} \\
\\
\begin{tabular}{p{0.5\textwidth}l}
Stefan Berger, IBM & Vincent Hanquez, XenSource \\
Daniel Berrang\'e, Red Hat & John Levon, Sun Microsystems \\
Gareth Bestor, IBM & Jon Ludlam, XenSource \\
Hollis Blanchard, IBM & Alastair Tse, XenSource \\
Mike Day, IBM & Daniel Veillard, Red Hat \\
Jim Fehlig, Novell & Tom Wilkie, University of Cambridge \\
Jon Harrop, XenSource & \\
\end{tabular}
\end{large}
\vfill
+338
View File
@@ -1558,6 +1558,81 @@ void
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~send\_sysrq}
{\bf Overview:}
Send the given key as a sysrq to this VM. The key is specified as a single
character (a String of length 1). This can only be called when the
specified VM is in the Running state.
\noindent {\bf Signature:}
\begin{verbatim} void send_sysrq (session_id s, VM ref vm, string key)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt VM ref } & vm & The VM \\ \hline
{\tt string } & key & The key to send \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
void
}
\vspace{0.3cm}
\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
\vspace{0.6cm}
\subsubsection{RPC name:~send\_trigger}
{\bf Overview:}
Send the named trigger to this VM. This can only be called when the
specified VM is in the Running state.
\noindent {\bf Signature:}
\begin{verbatim} void send_trigger (session_id s, VM ref vm, string trigger)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt VM ref } & vm & The VM \\ \hline
{\tt string } & trigger & The trigger to send \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
void
}
\vspace{0.3cm}
\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
\vspace{0.6cm}
\subsubsection{RPC name:~get\_all}
{\bf Overview:}
@@ -4107,6 +4182,9 @@ $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object ref
$\mathit{RO}_\mathit{run}$ & {\tt memory/actual} & int & Guest's actual memory (bytes) \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/number} & int & Current number of VCPUs \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/CPU} & (int $\rightarrow$ int) Map & VCPU to PCPU map \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/params} & (string $\rightarrow$ string) Map & The live equivalent to VM.VCPUs\_params \\
$\mathit{RO}_\mathit{run}$ & {\tt start\_time} & datetime & Time at which this VM was last booted \\
$\mathit{RO}_\mathit{run}$ & {\tt last\_updated} & datetime & Time at which this information was last updated \\
\hline
\end{longtable}
@@ -4256,6 +4334,102 @@ Get the VCPUs/utilisation field of the given VM\_metrics.
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_VCPUs\_CPU}
{\bf Overview:}
Get the VCPUs/CPU field of the given VM\_metrics.
\noindent {\bf Signature:}
\begin{verbatim} ((int -> int) Map) get_VCPUs_CPU (session_id s, VM_metrics ref self)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt VM\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
(int $\rightarrow$ int) Map
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_VCPUs\_params}
{\bf Overview:}
Get the VCPUs/params field of the given VM\_metrics.
\noindent {\bf Signature:}
\begin{verbatim} ((string -> string) Map) get_VCPUs_params (session_id s, VM_metrics ref self)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt VM\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
(string $\rightarrow$ string) Map
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_start\_time}
{\bf Overview:}
Get the start\_time field of the given VM\_metrics.
\noindent {\bf Signature:}
\begin{verbatim} datetime get_start_time (session_id s, VM_metrics ref self)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt VM\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
datetime
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
@@ -4744,6 +4918,8 @@ $\mathit{RO}_\mathit{run}$ & {\tt API\_version/vendor\_implementation} & (strin
$\mathit{RO}_\mathit{run}$ & {\tt software\_version} & (string $\rightarrow$ string) Map & version strings \\
$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
$\mathit{RO}_\mathit{run}$ & {\tt capabilities} & string Set & Xen capabilities \\
$\mathit{RO}_\mathit{run}$ & {\tt cpu\_configuration} & (string $\rightarrow$ string) Map & The CPU configuration on this host. May contain keys such as ``nr\_nodes'', ``sockets\_per\_node'', ``cores\_per\_socket'', or ``threads\_per\_core'' \\
$\mathit{RO}_\mathit{run}$ & {\tt sched\_policy} & string & Scheduler policy currently in force on this host \\
$\mathit{RO}_\mathit{run}$ & {\tt supported\_bootloaders} & string Set & a list of the bootloaders installed on the machine \\
$\mathit{RO}_\mathit{run}$ & {\tt resident\_VMs} & (VM ref) Set & list of VMs currently resident on host \\
$\mathit{RW}$ & {\tt logging} & (string $\rightarrow$ string) Map & logging configuration \\
@@ -4916,6 +5092,104 @@ string
dmesg string
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~dmesg\_clear}
{\bf Overview:}
Get the host xen dmesg, and clear the buffer.
\noindent {\bf Signature:}
\begin{verbatim} string dmesg_clear (session_id s, host ref host)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt host ref } & host & The Host to query \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
string
}
dmesg string
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_log}
{\bf Overview:}
Get the host's log file.
\noindent {\bf Signature:}
\begin{verbatim} string get_log (session_id s, host ref host)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt host ref } & host & The Host to query \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
string
}
The contents of the host's primary log file
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~send\_debug\_keys}
{\bf Overview:}
Inject the given string as debugging keys into Xen.
\noindent {\bf Signature:}
\begin{verbatim} void send_debug_keys (session_id s, host ref host, string keys)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt host ref } & host & The host \\ \hline
{\tt string } & keys & The keys to send \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
void
}
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -5450,6 +5724,70 @@ string Set
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_cpu\_configuration}
{\bf Overview:}
Get the cpu\_configuration field of the given host.
\noindent {\bf Signature:}
\begin{verbatim} ((string -> string) Map) get_cpu_configuration (session_id s, host ref self)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt host ref } & self & reference to the object \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
(string $\rightarrow$ string) Map
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_sched\_policy}
{\bf Overview:}
Get the sched\_policy field of the given host.
\noindent {\bf Signature:}
\begin{verbatim} string get_sched_policy (session_id s, host ref self)\end{verbatim}
\noindent{\bf Arguments:}
\vspace{0.3cm}
\begin{tabular}{|c|c|p{7cm}|}
\hline
{\bf type} & {\bf name} & {\bf description} \\ \hline
{\tt host ref } & self & reference to the object \\ \hline
\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
string
}
value of the field
\vspace{0.3cm}
\vspace{0.3cm}
-1
View File
@@ -17,7 +17,6 @@
\usepackage{graphics}
\usepackage{longtable}
\usepackage{fancyhdr}
\usepackage{multicol}
\setlength\topskip{0cm}
\setlength\topmargin{0cm}
@@ -127,8 +127,10 @@ static int take_machine_down(void *p_fast_suspend)
extern void time_resume(void);
if (fast_suspend) {
preempt_disable();
BUG_ON(!irqs_disabled());
} else {
BUG_ON(irqs_disabled());
for (;;) {
err = smp_suspend();
if (err)
@@ -143,11 +145,11 @@ static int take_machine_down(void *p_fast_suspend)
preempt_enable();
xenbus_suspend_cancel();
}
local_irq_disable();
}
mm_pin_all();
local_irq_disable();
preempt_enable();
gnttab_suspend();
pre_suspend();
@@ -178,7 +180,9 @@ static int take_machine_down(void *p_fast_suspend)
#endif
}
time_resume();
local_irq_enable();
if (!fast_suspend)
local_irq_enable();
return suspend_cancelled;
}
+30 -32
View File
@@ -34,28 +34,7 @@ static int fast_suspend;
static void __shutdown_handler(void *unused);
static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
#ifdef CONFIG_XEN
int __xen_suspend(int fast_suspend);
#else
extern void xenbus_suspend(void);
extern void xenbus_resume(void);
extern void platform_pci_suspend(void);
extern void platform_pci_resume(void);
int __xen_suspend(int fast_suspend)
{
xenbus_suspend();
platform_pci_suspend();
/* pvdrv sleep in this hyper-call when save */
HYPERVISOR_shutdown(SHUTDOWN_suspend);
platform_pci_resume();
xenbus_resume();
printk("PV stuff on HVM resume successfully!\n");
return 0;
}
#endif
static int shutdown_process(void *__unused)
{
@@ -210,13 +189,11 @@ static struct xenbus_watch shutdown_watch = {
};
static struct xenbus_watch sysrq_watch = {
.node ="control/sysrq",
.node = "control/sysrq",
.callback = sysrq_handler
};
static int setup_shutdown_watcher(struct notifier_block *notifier,
unsigned long event,
void *data)
static int setup_shutdown_watcher(void)
{
int err;
@@ -225,24 +202,36 @@ static int setup_shutdown_watcher(struct notifier_block *notifier,
"%d", &fast_suspend);
err = register_xenbus_watch(&shutdown_watch);
if (err)
if (err) {
printk(KERN_ERR "Failed to set shutdown watcher\n");
else
xenbus_write(XBT_NIL, "control", "feature-reboot", "1");
return err;
}
xenbus_write(XBT_NIL, "control", "feature-reboot", "1");
err = register_xenbus_watch(&sysrq_watch);
if (err)
if (err) {
printk(KERN_ERR "Failed to set sysrq watcher\n");
else
xenbus_write(XBT_NIL, "control", "feature-sysrq", "1");
return err;
}
xenbus_write(XBT_NIL, "control", "feature-sysrq", "1");
return 0;
}
#ifdef CONFIG_XEN
static int shutdown_event(struct notifier_block *notifier,
unsigned long event,
void *data)
{
setup_shutdown_watcher();
return NOTIFY_DONE;
}
static int __init setup_shutdown_event(void)
{
static struct notifier_block xenstore_notifier = {
.notifier_call = setup_shutdown_watcher
.notifier_call = shutdown_event
};
register_xenstore_notifier(&xenstore_notifier);
@@ -250,3 +239,12 @@ static int __init setup_shutdown_event(void)
}
subsys_initcall(setup_shutdown_event);
#else /* !defined(CONFIG_XEN) */
int xen_reboot_init(void)
{
return setup_shutdown_watcher();
}
#endif /* !defined(CONFIG_XEN) */
@@ -394,8 +394,7 @@ static const struct file_operations xenbus_dev_file_ops = {
.poll = xenbus_dev_poll,
};
int __init
xenbus_dev_init(void)
int xenbus_dev_init(void)
{
xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
if (xenbus_dev_intf)
@@ -863,7 +863,7 @@ static int xsd_port_read(char *page, char **start, off_t off,
}
#endif
static int __init xenbus_probe_init(void)
static int xenbus_probe_init(void)
{
int err = 0;
unsigned long page = 0;
@@ -978,10 +978,15 @@ static int __init xenbus_probe_init(void)
return err;
}
#ifdef CONFIG_XEN
postcore_initcall(xenbus_probe_init);
MODULE_LICENSE("Dual BSD/GPL");
#else
int xenbus_init(void)
{
return xenbus_probe_init();
}
#endif
static int is_disconnected_device(struct device *dev, void *data)
{
+1 -1
View File
@@ -293,7 +293,7 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
...);
int __init xenbus_dev_init(void);
int xenbus_dev_init(void);
const char *xenbus_strstate(enum xenbus_state state);
int xenbus_dev_is_online(struct xenbus_device *dev);
+5 -3
View File
@@ -119,6 +119,7 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t dom,
{
/* Have a 'valid' PFN without a matching MFN - need to alloc */
p2m_batch[nr_mfns++] = pfn;
p2m[pfn]--;
}
}
@@ -146,8 +147,8 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t dom,
continue;
pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
if ( p2m[pfn] == INVALID_P2M_ENTRY )
if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) )
p2m[pfn] = p2m_batch[nr_mfns++];
pte &= ~MADDR_MASK_X86;
@@ -489,6 +490,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
{
/* Have a live PFN which hasn't had an MFN allocated */
p2m_batch[nr_mfns++] = pfn;
p2m[pfn]--;
}
}
@@ -514,7 +516,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
region_mfn[i] = ~0UL; /* map will fail but we don't care */
else
{
if ( p2m[pfn] == INVALID_P2M_ENTRY )
if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) )
{
/* We just allocated a new mfn above; update p2m */
p2m[pfn] = p2m_batch[nr_mfns++];
+39 -2
View File
@@ -79,6 +79,8 @@ typedef struct xen_host_record
xen_string_string_map *software_version;
xen_string_string_map *other_config;
struct xen_string_set *capabilities;
xen_string_string_map *cpu_configuration;
char *sched_policy;
struct xen_string_set *supported_bootloaders;
struct xen_vm_record_opt_set *resident_vms;
xen_string_string_map *logging;
@@ -260,6 +262,20 @@ extern bool
xen_host_get_capabilities(xen_session *session, struct xen_string_set **result, xen_host host);
/**
* Get the cpu_configuration field of the given host.
*/
extern bool
xen_host_get_cpu_configuration(xen_session *session, xen_string_string_map **result, xen_host host);
/**
* Get the sched_policy field of the given host.
*/
extern bool
xen_host_get_sched_policy(xen_session *session, char **result, xen_host host);
/**
* Get the supported_bootloaders field of the given host.
*/
@@ -414,7 +430,7 @@ xen_host_enable(xen_session *session, xen_host host);
/**
* Shutdown the host. (This function can only be called if there are no
* currently running VMs on the host and it is disabled.)
* currently running VMs on the host and it is disabled.).
*/
extern bool
xen_host_shutdown(xen_session *session, xen_host host);
@@ -422,7 +438,7 @@ xen_host_shutdown(xen_session *session, xen_host host);
/**
* Reboot the host. (This function can only be called if there are no
* currently running VMs on the host and it is disabled.)
* currently running VMs on the host and it is disabled.).
*/
extern bool
xen_host_reboot(xen_session *session, xen_host host);
@@ -435,6 +451,27 @@ extern bool
xen_host_dmesg(xen_session *session, char **result, xen_host host);
/**
* Get the host xen dmesg, and clear the buffer.
*/
extern bool
xen_host_dmesg_clear(xen_session *session, char **result, xen_host host);
/**
* Get the host's log file.
*/
extern bool
xen_host_get_log(xen_session *session, char **result, xen_host host);
/**
* Inject the given string as debugging keys into Xen.
*/
extern bool
xen_host_send_debug_keys(xen_session *session, xen_host host, char *keys);
/**
* List all supported methods.
*/
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XEN_INT_INT_MAP_H
#define XEN_INT_INT_MAP_H
#include "xen_common.h"
typedef struct xen_int_int_map_contents
{
int64_t key;
int64_t val;
} xen_int_int_map_contents;
typedef struct xen_int_int_map
{
size_t size;
xen_int_int_map_contents contents[];
} xen_int_int_map;
/**
* Allocate a xen_int_int_map of the given size.
*/
extern xen_int_int_map *
xen_int_int_map_alloc(size_t size);
/**
* Free the given xen_int_int_map, and all referenced values. The
* given map must have been allocated by this library.
*/
extern void
xen_int_int_map_free(xen_int_int_map *map);
#endif
+1
View File
@@ -86,6 +86,7 @@ extern const abstract_type abstract_type_ref_set;
extern const abstract_type abstract_type_string_string_map;
extern const abstract_type abstract_type_int_float_map;
extern const abstract_type abstract_type_int_int_map;
typedef struct abstract_value
+17
View File
@@ -837,6 +837,23 @@ extern bool
xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu);
/**
* Send the given key as a sysrq to this VM. The key is specified as a
* single character (a String of length 1). This can only be called when the
* specified VM is in the Running state.
*/
extern bool
xen_vm_send_sysrq(xen_session *session, xen_vm vm, char *key);
/**
* Send the named trigger to this VM. This can only be called when the
* specified VM is in the Running state.
*/
extern bool
xen_vm_send_trigger(xen_session *session, xen_vm vm, char *trigger);
/**
* Return a list of all the VMs known to the system.
*/
+26
View File
@@ -21,6 +21,8 @@
#include "xen_common.h"
#include "xen_int_float_map.h"
#include "xen_int_int_map.h"
#include "xen_string_string_map.h"
#include "xen_vm_metrics_decl.h"
@@ -66,6 +68,9 @@ typedef struct xen_vm_metrics_record
int64_t memory_actual;
int64_t vcpus_number;
xen_int_float_map *vcpus_utilisation;
xen_int_int_map *vcpus_cpu;
xen_string_string_map *vcpus_params;
time_t start_time;
time_t last_updated;
} xen_vm_metrics_record;
@@ -190,6 +195,27 @@ extern bool
xen_vm_metrics_get_vcpus_utilisation(xen_session *session, xen_int_float_map **result, xen_vm_metrics vm_metrics);
/**
* Get the VCPUs/CPU field of the given VM_metrics.
*/
extern bool
xen_vm_metrics_get_vcpus_cpu(xen_session *session, xen_int_int_map **result, xen_vm_metrics vm_metrics);
/**
* Get the VCPUs/params field of the given VM_metrics.
*/
extern bool
xen_vm_metrics_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm_metrics vm_metrics);
/**
* Get the start_time field of the given VM_metrics.
*/
extern bool
xen_vm_metrics_get_start_time(xen_session *session, time_t *result, xen_vm_metrics vm_metrics);
/**
* Get the last_updated field of the given VM_metrics.
*/
+19
View File
@@ -35,6 +35,7 @@
#include "xen_host.h"
#include "xen_internal.h"
#include "xen_int_float_map.h"
#include "xen_int_int_map.h"
#include "xen_string_string_map.h"
@@ -1697,3 +1698,21 @@ const abstract_type abstract_type_int_float_map =
.struct_size = sizeof(xen_int_float_map_contents),
.members = int_float_members
};
static struct struct_member int_int_members[] =
{
{
.type = &abstract_type_int,
.offset = offsetof(xen_int_int_map_contents, key)
},
{
.type = &abstract_type_int,
.offset = offsetof(xen_int_int_map_contents, val)
}
};
const abstract_type abstract_type_int_int_map =
{
.typename = MAP,
.struct_size = sizeof(xen_int_int_map_contents),
.members = int_int_members
};
+92
View File
@@ -73,6 +73,12 @@ static const struct_member xen_host_record_struct_members[] =
{ .key = "capabilities",
.type = &abstract_type_string_set,
.offset = offsetof(xen_host_record, capabilities) },
{ .key = "cpu_configuration",
.type = &abstract_type_string_string_map,
.offset = offsetof(xen_host_record, cpu_configuration) },
{ .key = "sched_policy",
.type = &abstract_type_string,
.offset = offsetof(xen_host_record, sched_policy) },
{ .key = "supported_bootloaders",
.type = &abstract_type_string_set,
.offset = offsetof(xen_host_record, supported_bootloaders) },
@@ -128,6 +134,8 @@ xen_host_record_free(xen_host_record *record)
xen_string_string_map_free(record->software_version);
xen_string_string_map_free(record->other_config);
xen_string_set_free(record->capabilities);
xen_string_string_map_free(record->cpu_configuration);
free(record->sched_policy);
xen_string_set_free(record->supported_bootloaders);
xen_vm_record_opt_set_free(record->resident_vms);
xen_string_string_map_free(record->logging);
@@ -349,6 +357,40 @@ xen_host_get_capabilities(xen_session *session, struct xen_string_set **result,
}
bool
xen_host_get_cpu_configuration(xen_session *session, xen_string_string_map **result, xen_host host)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = host }
};
abstract_type result_type = abstract_type_string_string_map;
*result = NULL;
XEN_CALL_("host.get_cpu_configuration");
return session->ok;
}
bool
xen_host_get_sched_policy(xen_session *session, char **result, xen_host host)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = host }
};
abstract_type result_type = abstract_type_string;
*result = NULL;
XEN_CALL_("host.get_sched_policy");
return session->ok;
}
bool
xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set **result, xen_host host)
{
@@ -739,6 +781,56 @@ xen_host_dmesg(xen_session *session, char **result, xen_host host)
}
bool
xen_host_dmesg_clear(xen_session *session, char **result, xen_host host)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = host }
};
abstract_type result_type = abstract_type_string;
*result = NULL;
XEN_CALL_("host.dmesg_clear");
return session->ok;
}
bool
xen_host_get_log(xen_session *session, char **result, xen_host host)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = host }
};
abstract_type result_type = abstract_type_string;
*result = NULL;
XEN_CALL_("host.get_log");
return session->ok;
}
bool
xen_host_send_debug_keys(xen_session *session, xen_host host, char *keys)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = host },
{ .type = &abstract_type_string,
.u.string_val = keys }
};
xen_call_(session, "host.send_debug_keys", param_values, 2, NULL, NULL);
return session->ok;
}
bool
xen_host_list_methods(xen_session *session, struct xen_string_set **result)
{
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "xen_common.h"
#include "xen_int_int_map.h"
#include "xen_internal.h"
xen_int_int_map *
xen_int_int_map_alloc(size_t size)
{
xen_int_int_map *result = calloc(1, sizeof(xen_int_int_map) +
size * sizeof(struct xen_int_int_map_contents));
result->size = size;
return result;
}
void
xen_int_int_map_free(xen_int_int_map *map)
{
free(map);
}
+32
View File
@@ -1609,6 +1609,38 @@ xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu)
}
bool
xen_vm_send_sysrq(xen_session *session, xen_vm vm, char *key)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
{ .type = &abstract_type_string,
.u.string_val = key }
};
xen_call_(session, "VM.send_sysrq", param_values, 2, NULL, NULL);
return session->ok;
}
bool
xen_vm_send_trigger(xen_session *session, xen_vm vm, char *trigger)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
{ .type = &abstract_type_string,
.u.string_val = trigger }
};
xen_call_(session, "VM.send_trigger", param_values, 2, NULL, NULL);
return session->ok;
}
bool
xen_vm_get_all(xen_session *session, struct xen_vm_set **result)
{
+63
View File
@@ -22,7 +22,9 @@
#include "xen_common.h"
#include "xen_int_float_map.h"
#include "xen_int_int_map.h"
#include "xen_internal.h"
#include "xen_string_string_map.h"
#include "xen_vm_metrics.h"
@@ -49,6 +51,15 @@ static const struct_member xen_vm_metrics_record_struct_members[] =
{ .key = "VCPUs_utilisation",
.type = &abstract_type_int_float_map,
.offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) },
{ .key = "VCPUs_CPU",
.type = &abstract_type_int_int_map,
.offset = offsetof(xen_vm_metrics_record, vcpus_cpu) },
{ .key = "VCPUs_params",
.type = &abstract_type_string_string_map,
.offset = offsetof(xen_vm_metrics_record, vcpus_params) },
{ .key = "start_time",
.type = &abstract_type_datetime,
.offset = offsetof(xen_vm_metrics_record, start_time) },
{ .key = "last_updated",
.type = &abstract_type_datetime,
.offset = offsetof(xen_vm_metrics_record, last_updated) }
@@ -74,6 +85,8 @@ xen_vm_metrics_record_free(xen_vm_metrics_record *record)
free(record->handle);
free(record->uuid);
xen_int_float_map_free(record->vcpus_utilisation);
xen_int_int_map_free(record->vcpus_cpu);
xen_string_string_map_free(record->vcpus_params);
free(record);
}
@@ -167,6 +180,56 @@ xen_vm_metrics_get_vcpus_utilisation(xen_session *session, xen_int_float_map **r
}
bool
xen_vm_metrics_get_vcpus_cpu(xen_session *session, xen_int_int_map **result, xen_vm_metrics vm_metrics)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm_metrics }
};
abstract_type result_type = abstract_type_int_int_map;
*result = NULL;
XEN_CALL_("VM_metrics.get_VCPUs_CPU");
return session->ok;
}
bool
xen_vm_metrics_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm_metrics vm_metrics)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm_metrics }
};
abstract_type result_type = abstract_type_string_string_map;
*result = NULL;
XEN_CALL_("VM_metrics.get_VCPUs_params");
return session->ok;
}
bool
xen_vm_metrics_get_start_time(xen_session *session, time_t *result, xen_vm_metrics vm_metrics)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm_metrics }
};
abstract_type result_type = abstract_type_datetime;
XEN_CALL_("VM_metrics.get_start_time");
return session->ok;
}
bool
xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_metrics vm_metrics)
{
+65
View File
@@ -285,6 +285,40 @@ int main(int argc, char **argv)
return 1;
}
xen_string_string_map *cpu_configuration;
if (!xen_host_get_cpu_configuration(session, &cpu_configuration, host))
{
print_error(session);
free(dmesg);
xen_string_set_free(capabilities);
xen_string_set_free(supported_bootloaders);
xen_string_string_map_free(versions);
xen_host_free(host);
xen_vm_record_free(vm_record);
xen_uuid_bytes_free(vm_uuid_bytes);
xen_uuid_free(vm_uuid);
xen_vm_free(vm);
CLEANUP;
return 1;
}
char *sched_policy;
if (!xen_host_get_sched_policy(session, &sched_policy, host))
{
print_error(session);
xen_string_string_map_free(cpu_configuration);
xen_string_set_free(capabilities);
xen_string_set_free(supported_bootloaders);
xen_string_string_map_free(versions);
xen_host_free(host);
xen_vm_record_free(vm_record);
xen_uuid_bytes_free(vm_uuid_bytes);
xen_uuid_free(vm_uuid);
xen_vm_free(vm);
CLEANUP;
return 1;
}
printf("%s.\n", vm_uuid);
printf("In bytes, the VM UUID is ");
@@ -318,6 +352,15 @@ int main(int argc, char **argv)
}
printf("\n");
printf("Host has the following CPU configuration:\n");
for (size_t i = 0; i < cpu_configuration->size; i++)
{
printf(" %s -> %s.\n", cpu_configuration->contents[i].key,
cpu_configuration->contents[i].val);
}
printf("Current scheduler policy: %s.\n\n", sched_policy);
printf("%s.\n", vm_record->uuid);
printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
@@ -334,6 +377,8 @@ int main(int argc, char **argv)
free(dmesg);
xen_string_set_free(supported_bootloaders);
xen_string_set_free(capabilities);
xen_string_string_map_free(cpu_configuration);
free(sched_policy);
print_vm_metrics(session, vm);
if (!session->ok)
@@ -712,6 +757,10 @@ static void print_vm_metrics(xen_session *session, xen_vm vm)
my_strftime(time, 256, "Metrics updated at %c, local time.\n", tm);
printf(time);
tm = localtime(&vm_metrics_record->start_time);
my_strftime(time, 256, "VM running since %c, local time.\n", tm);
printf(time);
for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
{
printf("%"PRId64" -> %lf.\n",
@@ -719,6 +768,22 @@ static void print_vm_metrics(xen_session *session, xen_vm vm)
vm_metrics_record->vcpus_utilisation->contents[i].val);
}
printf("VCPU -> PCPU mapping:\n");
for (size_t i = 0; i < vm_metrics_record->vcpus_cpu->size; i++)
{
printf(" %"PRId64" -> %"PRId64".\n",
vm_metrics_record->vcpus_cpu->contents[i].key,
vm_metrics_record->vcpus_cpu->contents[i].val);
}
printf("Live scheduling parameters:\n");
for (size_t i = 0; i < vm_metrics_record->vcpus_params->size; i++)
{
printf(" %s -> %s.\n",
vm_metrics_record->vcpus_params->contents[i].key,
vm_metrics_record->vcpus_params->contents[i].val);
}
xen_vm_metrics_record_free(vm_metrics_record);
xen_vm_metrics_free(vm_metrics);
+11 -2
View File
@@ -87,7 +87,16 @@ def xen_api_todo():
def now():
return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime()))
return datetime()
def datetime(when = None):
"""Marshall the given time as a Xen-API DateTime.
@param when The time in question, given as seconds since the epoch, UTC.
May be None, in which case the current time is used.
"""
return xmlrpclib.DateTime(time.gmtime(when))
# ---------------------------------------------------
@@ -860,13 +869,13 @@ class XendAPI(object):
'metrics',
'capabilities',
'supported_bootloaders',
'sched_policy',
'API_version_major',
'API_version_minor',
'API_version_vendor',
'API_version_vendor_implementation']
host_attr_rw = ['name_label',
'sched_policy',
'name_description',
'other_config']
+1
View File
@@ -430,6 +430,7 @@ class XendDomainInfo:
self._endRestore()
except:
log.exception('VM resume failed')
self.destroy()
raise
else:
raise XendError('VM already running')
+3 -1
View File
@@ -138,7 +138,9 @@ class XendVMMetrics:
return {}
def get_start_time(self):
return self.xend_domain_instance.info.get("start_time", -1)
import xen.xend.XendAPI as XendAPI
return XendAPI.datetime(
self.xend_domain_instance.info.get("start_time", 0))
def get_last_updated(self):
import xen.xend.XendAPI as XendAPI
+8 -1
View File
@@ -731,6 +731,12 @@ def xm_restore(args):
server.xend.domain.restore(savefile, paused)
def datetime_to_secs(v):
unwanted = ":-."
for c in unwanted:
v = str(v).replace(c, "")
return time.mktime(time.strptime(v[0:14], '%Y%m%dT%H%M%S'))
def getDomains(domain_names, state, full = 0):
if serverType == SERVER_XEN_API:
doms_sxp = []
@@ -756,7 +762,8 @@ def getDomains(domain_names, state, full = 0):
'vcpus': dom_metrics['VCPUs_number'],
'state': state_str,
'cpu_time': dom_metrics['VCPUs_utilisation'],
'start_time': dom_metrics['start_time']})
'start_time': datetime_to_secs(
dom_metrics['start_time'])})
doms_sxp.append(['domain'] + map2sxp(dom_rec))
doms_dict.append(dom_rec)
-2
View File
@@ -1,8 +1,6 @@
include $(M)/overrides.mk
obj-m += platform-pci/
obj-m += xenbus/
obj-m += balloon/
obj-m += blkfront/
obj-m += netfront/
obj-m += util/
+1 -1
View File
@@ -25,7 +25,7 @@ done
ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci
ln -sf ${XL}/drivers/xen/core/features.c platform-pci
ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus
ln -sf ${XL}/drivers/xen/core/reboot.c util
ln -sf ${XL}/drivers/xen/core/reboot.c platform-pci
mkdir -p include/asm include/xen
@@ -4,7 +4,16 @@ obj-m := xen-platform-pci.o
EXTRA_CFLAGS += -I$(M)/platform-pci
xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o platform-compat.o
xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o
xen-platform-pci-objs += features.o platform-compat.o
xen-platform-pci-objs += reboot.o machine_reboot.o
xen-platform-pci-objs += ../xenbus/xenbus_comms.o
xen-platform-pci-objs += ../xenbus/xenbus_xs.o
xen-platform-pci-objs += ../xenbus/xenbus_probe.o
xen-platform-pci-objs += ../xenbus/xenbus_dev.o
xen-platform-pci-objs += ../xenbus/xenbus_client.o
xen-platform-pci-objs += ../xenbus/xen_proc.o
# Can we do better ?
ifeq ($(ARCH),ia64)
@@ -41,16 +41,42 @@
void *shared_info_area;
#define MAX_EVTCHN 256
static DEFINE_MUTEX(irq_evtchn_mutex);
#define is_valid_evtchn(x) ((x) != 0)
#define evtchn_from_irq(x) (irq_evtchn[irq].evtchn)
static struct {
irqreturn_t(*handler) (int, void *, struct pt_regs *);
void *dev_id;
int close; /* close on unbind_from_irqhandler()? */
} evtchns[MAX_EVTCHN];
int evtchn;
int close:1; /* close on unbind_from_irqhandler()? */
int inuse:1;
} irq_evtchn[256];
static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
[0 ... NR_EVENT_CHANNELS-1] = -1 };
static int find_unbound_irq(void)
{
static int warned;
int irq;
for (irq = 0; irq < ARRAY_SIZE(irq_evtchn); irq++)
if (!irq_evtchn[irq].inuse)
return irq;
if (!warned) {
warned = 1;
printk(KERN_WARNING "No available IRQ to bind to: "
"increase irq_evtchn[] size in evtchn.c.\n");
}
return -ENOSPC;
}
int irq_to_evtchn_port(int irq)
{
return irq;
return irq_evtchn[irq].evtchn;
}
EXPORT_SYMBOL(irq_to_evtchn_port);
@@ -107,21 +133,37 @@ int bind_listening_port_to_irqhandler(
void *dev_id)
{
struct evtchn_alloc_unbound alloc_unbound;
int err;
int err, irq;
mutex_lock(&irq_evtchn_mutex);
irq = find_unbound_irq();
if (irq < 0) {
mutex_unlock(&irq_evtchn_mutex);
return irq;
}
alloc_unbound.dom = DOMID_SELF;
alloc_unbound.remote_dom = remote_domain;
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
if (err)
if (err) {
mutex_unlock(&irq_evtchn_mutex);
return err;
}
irq_evtchn[irq].handler = handler;
irq_evtchn[irq].dev_id = dev_id;
irq_evtchn[irq].evtchn = alloc_unbound.port;
irq_evtchn[irq].close = 1;
irq_evtchn[irq].inuse = 1;
evtchn_to_irq[alloc_unbound.port] = irq;
evtchns[alloc_unbound.port].handler = handler;
evtchns[alloc_unbound.port].dev_id = dev_id;
evtchns[alloc_unbound.port].close = 1;
unmask_evtchn(alloc_unbound.port);
return alloc_unbound.port;
mutex_unlock(&irq_evtchn_mutex);
return irq;
}
EXPORT_SYMBOL(bind_listening_port_to_irqhandler);
@@ -132,35 +174,59 @@ int bind_caller_port_to_irqhandler(
const char *devname,
void *dev_id)
{
if (caller_port >= MAX_EVTCHN)
return -EINVAL;
evtchns[caller_port].handler = handler;
evtchns[caller_port].dev_id = dev_id;
evtchns[caller_port].close = 0;
int irq;
mutex_lock(&irq_evtchn_mutex);
irq = find_unbound_irq();
if (irq < 0) {
mutex_unlock(&irq_evtchn_mutex);
return irq;
}
irq_evtchn[irq].handler = handler;
irq_evtchn[irq].dev_id = dev_id;
irq_evtchn[irq].evtchn = caller_port;
irq_evtchn[irq].close = 0;
irq_evtchn[irq].inuse = 1;
evtchn_to_irq[caller_port] = irq;
unmask_evtchn(caller_port);
return caller_port;
mutex_unlock(&irq_evtchn_mutex);
return irq;
}
EXPORT_SYMBOL(bind_caller_port_to_irqhandler);
void unbind_from_irqhandler(unsigned int evtchn, void *dev_id)
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
if (evtchn >= MAX_EVTCHN)
return;
int evtchn = evtchn_from_irq(irq);
mask_evtchn(evtchn);
evtchns[evtchn].handler = NULL;
mutex_lock(&irq_evtchn_mutex);
if (evtchns[evtchn].close) {
struct evtchn_close close = { .port = evtchn };
HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
if (is_valid_evtchn(evtchn)) {
evtchn_to_irq[irq] = -1;
mask_evtchn(evtchn);
if (irq_evtchn[irq].close) {
struct evtchn_close close = { .port = evtchn };
HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
}
}
irq_evtchn[irq].handler = NULL;
irq_evtchn[irq].evtchn = 0;
irq_evtchn[irq].inuse = 0;
mutex_unlock(&irq_evtchn_mutex);
}
EXPORT_SYMBOL(unbind_from_irqhandler);
void notify_remote_via_irq(int irq)
{
int evtchn = irq;
notify_remote_via_evtchn(evtchn);
int evtchn = evtchn_from_irq(irq);
if (is_valid_evtchn(evtchn))
notify_remote_via_evtchn(evtchn);
}
EXPORT_SYMBOL(notify_remote_via_irq);
@@ -183,9 +249,10 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while ((l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i])) {
port = (l1i * BITS_PER_LONG) + __ffs(l2);
synch_clear_bit(port, &s->evtchn_pending[0]);
if ((handler = evtchns[port].handler) != NULL)
handler(port, evtchns[port].dev_id,
regs);
irq = evtchn_to_irq[port];
if ((irq >= 0) &&
((handler = irq_evtchn[irq].handler) != NULL))
handler(irq, irq_evtchn[irq].dev_id, regs);
else
printk(KERN_WARNING "unexpected event channel "
"upcall on port %d!\n", port);
@@ -200,3 +267,28 @@ void force_evtchn_callback(void)
(void)HYPERVISOR_xen_version(0, NULL);
}
EXPORT_SYMBOL(force_evtchn_callback);
void irq_suspend(void)
{
mutex_lock(&irq_evtchn_mutex);
}
void irq_suspend_cancel(void)
{
mutex_unlock(&irq_evtchn_mutex);
}
void irq_resume(void)
{
int evtchn, irq;
for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
mask_evtchn(evtchn);
evtchn_to_irq[evtchn] = -1;
}
for (irq = 0; irq < ARRAY_SIZE(irq_evtchn); irq++)
irq_evtchn[irq].evtchn = 0;
mutex_unlock(&irq_evtchn_mutex);
}
@@ -0,0 +1,24 @@
#include <linux/config.h>
#include <xen/xenbus.h>
#include "platform-pci.h"
#include <asm/hypervisor.h>
int __xen_suspend(int fast_suspend)
{
int suspend_cancelled;
xenbus_suspend();
platform_pci_suspend();
suspend_cancelled = HYPERVISOR_shutdown(SHUTDOWN_suspend);
if (suspend_cancelled) {
platform_pci_suspend_cancel();
xenbus_suspend_cancel();
} else {
platform_pci_resume();
xenbus_resume();
}
return 0;
}
@@ -1,7 +1,9 @@
/******************************************************************************
* platform-pci.c
*
* Xen platform PCI device driver
* Copyright (C) 2005, Intel Corporation.
* Copyright (c) 2005, Intel Corporation.
* Copyright (c) 2007, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -35,7 +37,9 @@
#include <asm/hypervisor.h>
#include <asm/pgtable.h>
#include <xen/interface/memory.h>
#include <xen/interface/hvm/params.h>
#include <xen/features.h>
#include <xen/evtchn.h>
#include <xen/gnttab.h>
#ifdef __ia64__
#include <asm/xen/xencomm.h>
@@ -54,14 +58,10 @@
char *hypercall_stubs;
EXPORT_SYMBOL(hypercall_stubs);
// Used to be xiaofeng.ling@intel.com
MODULE_AUTHOR("ssmith@xensource.com");
MODULE_DESCRIPTION("Xen platform PCI device");
MODULE_LICENSE("GPL");
unsigned long *phys_to_machine_mapping;
EXPORT_SYMBOL(phys_to_machine_mapping);
static unsigned long shared_info_frame;
static uint64_t callback_via;
@@ -89,30 +89,11 @@ static int __devinit init_xen_info(void)
if (shared_info_area == NULL)
panic("can't map shared info\n");
phys_to_machine_mapping = NULL;
gnttab_init();
return 0;
}
static void __devexit platform_pci_remove(struct pci_dev *pdev)
{
long ioaddr, iolen;
long mmio_addr, mmio_len;
ioaddr = pci_resource_start(pdev, 0);
iolen = pci_resource_len(pdev, 0);
mmio_addr = pci_resource_start(pdev, 1);
mmio_len = pci_resource_len(pdev, 1);
release_region(ioaddr, iolen);
release_mem_region(mmio_addr, mmio_len);
pci_set_drvdata(pdev, NULL);
free_irq(pdev->irq, pdev);
}
static unsigned long platform_mmio;
static unsigned long platform_mmio_alloc;
static unsigned long platform_mmiolen;
@@ -208,6 +189,19 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
((uint64_t)(pin - 1) & 3));
}
static int set_callback_via(uint64_t via)
{
struct xen_hvm_param a;
a.domid = DOMID_SELF;
a.index = HVM_PARAM_CALLBACK_IRQ;
a.value = via;
return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
}
int xenbus_init(void);
int xen_reboot_init(void);
static int __devinit platform_pci_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -232,15 +226,13 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
return -ENOENT;
}
if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
{
if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",
mmio_addr, mmio_len);
return -EBUSY;
}
if (request_region(ioaddr, iolen, DRV_NAME) == NULL)
{
if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
printk(KERN_ERR DRV_NAME ":I/O resource 0x%lx @ 0x%lx busy\n",
iolen, ioaddr);
release_mem_region(mmio_addr, mmio_len);
@@ -265,6 +257,12 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
if ((ret = set_callback_via(callback_via)))
goto out;
if ((ret = xenbus_init()))
goto out;
if ((ret = xen_reboot_init()))
goto out;
out:
if (ret) {
release_mem_region(mmio_addr, mmio_len);
@@ -289,7 +287,6 @@ MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
static struct pci_driver platform_driver = {
name: DRV_NAME,
probe: platform_pci_init,
remove: __devexit_p(platform_pci_remove),
id_table: platform_pci_tbl,
};
@@ -298,13 +295,18 @@ static int pci_device_registered;
void platform_pci_suspend(void)
{
gnttab_suspend();
irq_suspend();
}
void platform_pci_suspend_cancel(void)
{
irq_suspend_cancel();
gnttab_resume();
}
EXPORT_SYMBOL_GPL(platform_pci_suspend);
void platform_pci_resume(void)
{
struct xen_add_to_physmap xatp;
phys_to_machine_mapping = NULL;
/* do 2 things for PV driver restore on HVM
* 1: rebuild share info
@@ -317,34 +319,27 @@ void platform_pci_resume(void)
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
if (( set_callback_via(callback_via)))
irq_resume();
if (set_callback_via(callback_via))
printk("platform_pci_resume failure!\n");
gnttab_resume();
}
EXPORT_SYMBOL_GPL(platform_pci_resume);
static int __init platform_pci_module_init(void)
{
int rc;
rc = pci_module_init(&platform_driver);
if (rc)
printk(KERN_INFO DRV_NAME ":No platform pci device model found\n");
else
pci_device_registered = 1;
if (rc) {
printk(KERN_INFO DRV_NAME
": No platform pci device model found\n");
return rc;
}
return rc;
}
static void __exit platform_pci_module_cleanup(void)
{
printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n");
/* disable hypervisor for callback irq */
set_callback_via(0);
if (pci_device_registered)
pci_unregister_driver(&platform_driver);
pci_device_registered = 1;
return 0;
}
module_init(platform_pci_module_init);
module_exit(platform_pci_module_cleanup);
@@ -1,7 +1,9 @@
/******************************************************************************
* evtchn-pci.h
* module driver support in unmodified Linux
* Copyright (C) 2004, Intel Corporation. <xiaofeng.ling@intel.com>
* platform-pci.h
*
* Xen platform PCI device driver
* Copyright (c) 2004, Intel Corporation. <xiaofeng.ling@intel.com>
* Copyright (c) 2007, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -15,31 +17,21 @@
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#ifndef __XEN_SUPPORT_H
#define __XEN_SUPPORT_H
#include <linux/version.h>
#ifndef _XEN_PLATFORM_PCI_H
#define _XEN_PLATFORM_PCI_H
#include <linux/interrupt.h>
#include <xen/interface/hvm/params.h>
static inline int set_callback_via(uint64_t via)
{
struct xen_hvm_param a;
a.domid = DOMID_SELF;
a.index = HVM_PARAM_CALLBACK_IRQ;
a.value = via;
return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
}
unsigned long alloc_xen_mmio(unsigned long len);
int gnttab_init(void);
void setup_xen_features(void);
irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
void irq_suspend(void);
void irq_suspend_cancel(void);
#endif
void platform_pci_suspend(void);
void platform_pci_suspend_cancel(void);
void platform_pci_resume(void);
#endif /* _XEN_PLATFORM_PCI_H */
-3
View File
@@ -1,3 +0,0 @@
include $(M)/overrides.mk
obj-m := reboot.o
@@ -1,3 +0,0 @@
ifneq ($(KERNELRELEASE),)
include $(src)/Kbuild
endif
@@ -1,10 +0,0 @@
include $(M)/overrides.mk
obj-m += xenbus.o
xenbus-objs =
xenbus-objs += xenbus_comms.o
xenbus-objs += xenbus_xs.o
xenbus-objs += xenbus_probe.o
xenbus-objs += xenbus_dev.o
xenbus-objs += xenbus_client.o
xenbus-objs += xen_proc.o
@@ -1,3 +0,0 @@
ifneq ($(KERNELRELEASE),)
include $(src)/Kbuild
endif
Whitespace-only changes.
+49
View File
@@ -443,6 +443,7 @@ void hap_final_teardown(struct domain *d)
hap_teardown(d);
p2m_teardown(d);
ASSERT( d->arch.paging.hap.p2m_pages == 0 );
}
void hap_teardown(struct domain *d)
@@ -635,12 +636,60 @@ void hap_update_paging_modes(struct vcpu *v)
hap_unlock(d);
}
#if CONFIG_PAGING_LEVELS == 3
static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e)
/* Special case, only used for external-mode domains on PAE hosts:
* update the mapping of the p2m table. Once again, this is trivial in
* other paging modes (one top-level entry points to the top-level p2m,
* no maintenance needed), but PAE makes life difficult by needing a
* copy l3es of the p2m table in eight l2h slots in the monitor table. This
* function makes fresh copies when a p2m l3e changes. */
{
l2_pgentry_t *ml2e;
struct vcpu *v;
unsigned int index;
index = ((unsigned long)l3e & ~PAGE_MASK) / sizeof(l3_pgentry_t);
ASSERT(index < MACHPHYS_MBYTES>>1);
for_each_vcpu(d, v) {
if ( pagetable_get_pfn(v->arch.monitor_table) == 0 )
continue;
ASSERT(paging_mode_external(v->domain));
if ( v == current ) /* OK to use linear map of monitor_table */
ml2e = __linear_l2_table + l2_linear_offset(RO_MPT_VIRT_START);
else {
l3_pgentry_t *ml3e;
ml3e = hap_map_domain_page(pagetable_get_mfn(v->arch.monitor_table));
ASSERT(l3e_get_flags(ml3e[3]) & _PAGE_PRESENT);
ml2e = hap_map_domain_page(_mfn(l3e_get_pfn(ml3e[3])));
ml2e += l2_table_offset(RO_MPT_VIRT_START);
hap_unmap_domain_page(ml3e);
}
ml2e[index] = l2e_from_pfn(l3e_get_pfn(*l3e), __PAGE_HYPERVISOR);
if ( v != current )
hap_unmap_domain_page(ml2e);
}
}
#endif
void
hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
l1_pgentry_t new, unsigned int level)
{
hap_lock(v->domain);
safe_write_pte(p, new);
#if CONFIG_PAGING_LEVELS == 3
/* install P2M in monitor table for PAE Xen */
if ( level == 3 ) {
/* We have written to the p2m l3: need to sync the per-vcpu
* copies of it in the monitor tables */
p2m_install_entry_in_monitors(v->domain, (l3_pgentry_t *)p);
}
#endif
hap_unlock(v->domain);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.