mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge with xen-ia64-unstable.hg
This commit is contained in:
commit
8e90ca4a3d
108 files changed
+1834
-1243
No files matched your search
@@ -31,17 +31,27 @@ EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
|
||||
EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
|
||||
endif
|
||||
|
||||
# cc-option
|
||||
# cc-option: Check if compiler supports first option, else fall back to second.
|
||||
# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
|
||||
cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
|
||||
/dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
|
||||
|
||||
# cc-ver
|
||||
# cc-ver: Check compiler is at least specified version. Return boolean 'y'/'n'.
|
||||
# Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
|
||||
cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
|
||||
'{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
|
||||
then echo y; else echo n; fi ;)
|
||||
|
||||
# cc-ver-check: Check compiler is at least specified version, else fail.
|
||||
# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
|
||||
cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
|
||||
define cc-ver-check-closure
|
||||
ifeq ($$(call cc-ver,$$($(1)),$(2)),n)
|
||||
override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
|
||||
cc-option := n
|
||||
endif
|
||||
endef
|
||||
|
||||
ifneq ($(debug),y)
|
||||
CFLAGS += -DNDEBUG
|
||||
else
|
||||
|
||||
@@ -6549,6 +6549,7 @@ $\mathit{RW}$ & {\tt name/label} & string & a human-readable name \\
|
||||
$\mathit{RW}$ & {\tt name/description} & string & a notes field containg human-readable description \\
|
||||
$\mathit{RO}_\mathit{run}$ & {\tt VIFs} & (VIF ref) Set & list of connected vifs \\
|
||||
$\mathit{RO}_\mathit{run}$ & {\tt PIFs} & (PIF ref) Set & list of connected pifs \\
|
||||
$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
|
||||
\hline
|
||||
\end{longtable}
|
||||
\subsection{RPCs associated with class: network}
|
||||
@@ -6798,6 +6799,145 @@ Get the PIFs field of the given network.
|
||||
|
||||
|
||||
value of the field
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~get\_other\_config}
|
||||
|
||||
{\bf Overview:}
|
||||
Get the other\_config field of the given network.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, network 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 network 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:~set\_other\_config}
|
||||
|
||||
{\bf Overview:}
|
||||
Set the other\_config field of the given network.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void set_other_config (session_id s, network ref self, (string -> string) Map value)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt network ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~add\_to\_other\_config}
|
||||
|
||||
{\bf Overview:}
|
||||
Add the given key-value pair to the other\_config field of the given
|
||||
network.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void add_to_other_config (session_id s, network ref self, string key, string value)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt network ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt string } & key & Key to add \\ \hline
|
||||
|
||||
{\tt string } & value & Value to add \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~remove\_from\_other\_config}
|
||||
|
||||
{\bf Overview:}
|
||||
Remove the given key and its corresponding value from the other\_config
|
||||
field of the given network. If the key is not in that Map, then do
|
||||
nothing.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void remove_from_other_config (session_id s, network ref self, 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 network ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt string } & key & Key to remove \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
|
||||
@@ -148,11 +148,11 @@ NMI_MASK = 0x80000000
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Must be consistent with the definition in arch-x86_64.h:
|
||||
* Must be consistent with the definition in arch-x86/xen-x86_64.h:
|
||||
* struct iret_context {
|
||||
* u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
|
||||
* };
|
||||
* #define VGCF_IN_SYSCALL (1<<8)
|
||||
* with rax, r11, and rcx being taken care of in the hypercall stub.
|
||||
*/
|
||||
.macro HYPERVISOR_IRET flag
|
||||
testb $3,1*8(%rsp)
|
||||
@@ -164,22 +164,16 @@ NMI_MASK = 0x80000000
|
||||
jnz 1f
|
||||
|
||||
/* Direct iret to kernel space. Correct CS and SS. */
|
||||
orb $3,1*8(%rsp)
|
||||
orb $3,4*8(%rsp)
|
||||
orl $3,1*8(%rsp)
|
||||
orl $3,4*8(%rsp)
|
||||
1: iretq
|
||||
|
||||
2: /* Slow iret via hypervisor. */
|
||||
andl $~NMI_MASK, 16(%rsp)
|
||||
andl $~NMI_MASK, 2*8(%rsp)
|
||||
pushq $\flag
|
||||
jmp hypercall_page + (__HYPERVISOR_iret * 32)
|
||||
.endm
|
||||
|
||||
.macro SWITCH_TO_KERNEL ssoff,adjust=0
|
||||
jc 1f
|
||||
orb $1,\ssoff-\adjust+4(%rsp)
|
||||
1:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* A newly forked process directly context switches into this.
|
||||
*/
|
||||
|
||||
@@ -123,7 +123,7 @@ static void post_suspend(int suspend_cancelled)
|
||||
static int take_machine_down(void *p_fast_suspend)
|
||||
{
|
||||
int fast_suspend = *(int *)p_fast_suspend;
|
||||
int suspend_cancelled, err, cpu;
|
||||
int suspend_cancelled, err;
|
||||
extern void time_resume(void);
|
||||
|
||||
if (fast_suspend) {
|
||||
|
||||
@@ -236,7 +236,10 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
break;
|
||||
|
||||
case XS_WATCH:
|
||||
case XS_UNWATCH:
|
||||
case XS_UNWATCH: {
|
||||
static const char *XS_RESP = "OK";
|
||||
struct xsd_sockmsg hdr;
|
||||
|
||||
path = u->u.buffer + sizeof(u->u.msg);
|
||||
token = memchr(path, 0, u->u.msg.len);
|
||||
if (token == NULL) {
|
||||
@@ -246,9 +249,6 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
token++;
|
||||
|
||||
if (msg_type == XS_WATCH) {
|
||||
static const char * XS_WATCH_RESP = "OK";
|
||||
struct xsd_sockmsg hdr;
|
||||
|
||||
watch = kmalloc(sizeof(*watch), GFP_KERNEL);
|
||||
watch->watch.node = kmalloc(strlen(path)+1,
|
||||
GFP_KERNEL);
|
||||
@@ -266,11 +266,6 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
}
|
||||
|
||||
list_add(&watch->list, &u->watches);
|
||||
|
||||
hdr.type = XS_WATCH;
|
||||
hdr.len = strlen(XS_WATCH_RESP) + 1;
|
||||
queue_reply(u, (char *)&hdr, sizeof(hdr));
|
||||
queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
|
||||
} else {
|
||||
list_for_each_entry_safe(watch, tmp_watch,
|
||||
&u->watches, list) {
|
||||
@@ -285,7 +280,12 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
}
|
||||
}
|
||||
|
||||
hdr.type = msg_type;
|
||||
hdr.len = strlen(XS_RESP) + 1;
|
||||
queue_reply(u, (char *)&hdr, sizeof(hdr));
|
||||
queue_reply(u, (char *)XS_RESP, hdr.len);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
|
||||
+3
-3
@@ -24,9 +24,9 @@ CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
|
||||
CFLAGS += $(CFLAGS-y)
|
||||
|
||||
# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
|
||||
ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
|
||||
$(error Xen tools require at least gcc-3.4)
|
||||
endif
|
||||
check-$(CONFIG_X86) = $(call cc-ver-check,CC,0x030400,\
|
||||
"Xen requires at least gcc-3.4")
|
||||
$(eval $(check-y))
|
||||
|
||||
%.opic: %.c
|
||||
$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
|
||||
|
||||
@@ -46,6 +46,11 @@
|
||||
# (xen-api-server ((9363 pam '^localhost$ example\\.com$')
|
||||
# (unix none)))
|
||||
#
|
||||
# Optionally, the TCP Xen-API server can use SSL by specifying the private
|
||||
# key and certificate location:
|
||||
#
|
||||
# (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
|
||||
#
|
||||
# Default:
|
||||
# (xen-api-server ((unix)))
|
||||
|
||||
@@ -59,11 +64,18 @@
|
||||
|
||||
#(xend-unix-path /var/lib/xend/xend-socket)
|
||||
|
||||
# Address and port xend should use for the TCP XMLRPC interface,
|
||||
|
||||
# Address and port xend should use for the legacy TCP XMLRPC interface,
|
||||
# if xen-tcp-xmlrpc-server is set.
|
||||
#(xen-tcp-xmlrpc-server-address 'localhost')
|
||||
#(xen-tcp-xmlrpc-server-port 8006)
|
||||
|
||||
# SSL key and certificate to use for the legacy TCP XMLRPC interface.
|
||||
# Setting these will mean that this port serves only SSL connections as
|
||||
# opposed to plaintext ones.
|
||||
#(xend-tcp-xmlrpc-server-ssl-key-file /etc/xen/xmlrpc.key)
|
||||
#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
|
||||
|
||||
|
||||
# Port xend should use for the HTTP interface, if xend-http-server is set.
|
||||
#(xend-port 8000)
|
||||
|
||||
@@ -193,6 +193,10 @@ ifdef CONFIG_SOLARIS
|
||||
LIBS+=-lsocket -lnsl -lresolv
|
||||
endif
|
||||
|
||||
ifeq ($(debug),y)
|
||||
CFLAGS += -DQEMU_VNC_MONITOR_EXPORT
|
||||
endif
|
||||
|
||||
# profiling code
|
||||
ifdef TARGET_GPROF
|
||||
LDFLAGS+=-p
|
||||
|
||||
@@ -113,8 +113,10 @@ struct VncState
|
||||
int visible_w;
|
||||
int visible_h;
|
||||
|
||||
#ifdef QEMU_VNC_MONITOR_EXPORT
|
||||
int ctl_keys; /* Ctrl+Alt starts calibration */
|
||||
int shift_keys; /* Shift / CapsLock keys */
|
||||
#endif
|
||||
int numlock;
|
||||
};
|
||||
|
||||
@@ -895,6 +897,7 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||
kbd_put_keycode(keycode & 0x7f);
|
||||
else
|
||||
kbd_put_keycode(keycode | 0x80);
|
||||
#ifdef QEMU_VNC_MONITOR_EXPORT
|
||||
} else if (down) {
|
||||
int qemu_keysym = 0;
|
||||
|
||||
@@ -922,8 +925,10 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||
}
|
||||
if (qemu_keysym != 0)
|
||||
kbd_put_keysym(qemu_keysym);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef QEMU_VNC_MONITOR_EXPORT
|
||||
if (down) {
|
||||
switch (sym) {
|
||||
case XK_Control_L:
|
||||
@@ -976,6 +981,10 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!down && sym == XK_Num_Lock)
|
||||
vs->numlock = !vs->numlock;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void key_event(VncState *vs, int down, uint32_t sym)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "xen_common.h"
|
||||
#include "xen_network_decl.h"
|
||||
#include "xen_pif_decl.h"
|
||||
#include "xen_string_string_map.h"
|
||||
#include "xen_vif_decl.h"
|
||||
|
||||
|
||||
@@ -68,6 +69,7 @@ typedef struct xen_network_record
|
||||
char *name_description;
|
||||
struct xen_vif_record_opt_set *vifs;
|
||||
struct xen_pif_record_opt_set *pifs;
|
||||
xen_string_string_map *other_config;
|
||||
} xen_network_record;
|
||||
|
||||
/**
|
||||
@@ -219,6 +221,13 @@ extern bool
|
||||
xen_network_get_pifs(xen_session *session, struct xen_pif_set **result, xen_network network);
|
||||
|
||||
|
||||
/**
|
||||
* Get the other_config field of the given network.
|
||||
*/
|
||||
extern bool
|
||||
xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network);
|
||||
|
||||
|
||||
/**
|
||||
* Set the name/label field of the given network.
|
||||
*/
|
||||
@@ -233,6 +242,30 @@ extern bool
|
||||
xen_network_set_name_description(xen_session *session, xen_network network, char *description);
|
||||
|
||||
|
||||
/**
|
||||
* Set the other_config field of the given network.
|
||||
*/
|
||||
extern bool
|
||||
xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config);
|
||||
|
||||
|
||||
/**
|
||||
* Add the given key-value pair to the other_config field of the given
|
||||
* network.
|
||||
*/
|
||||
extern bool
|
||||
xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given key and its corresponding value from the
|
||||
* other_config field of the given network. If the key is not in that Map,
|
||||
* then do nothing.
|
||||
*/
|
||||
extern bool
|
||||
xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key);
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of all the networks known to the system.
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "xen_internal.h"
|
||||
#include "xen_network.h"
|
||||
#include "xen_pif.h"
|
||||
#include "xen_string_string_map.h"
|
||||
#include "xen_vif.h"
|
||||
|
||||
|
||||
@@ -52,7 +53,10 @@ static const struct_member xen_network_record_struct_members[] =
|
||||
.offset = offsetof(xen_network_record, vifs) },
|
||||
{ .key = "PIFs",
|
||||
.type = &abstract_type_ref_set,
|
||||
.offset = offsetof(xen_network_record, pifs) }
|
||||
.offset = offsetof(xen_network_record, pifs) },
|
||||
{ .key = "other_config",
|
||||
.type = &abstract_type_string_string_map,
|
||||
.offset = offsetof(xen_network_record, other_config) }
|
||||
};
|
||||
|
||||
const abstract_type xen_network_record_abstract_type_ =
|
||||
@@ -78,6 +82,7 @@ xen_network_record_free(xen_network_record *record)
|
||||
free(record->name_description);
|
||||
xen_vif_record_opt_set_free(record->vifs);
|
||||
xen_pif_record_opt_set_free(record->pifs);
|
||||
xen_string_string_map_free(record->other_config);
|
||||
free(record);
|
||||
}
|
||||
|
||||
@@ -238,6 +243,23 @@ xen_network_get_pifs(xen_session *session, struct xen_pif_set **result, xen_netw
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = network }
|
||||
};
|
||||
|
||||
abstract_type result_type = abstract_type_string_string_map;
|
||||
|
||||
*result = NULL;
|
||||
XEN_CALL_("network.get_other_config");
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_set_name_label(xen_session *session, xen_network network, char *label)
|
||||
{
|
||||
@@ -270,6 +292,56 @@ xen_network_set_name_description(xen_session *session, xen_network network, char
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = network },
|
||||
{ .type = &abstract_type_string_string_map,
|
||||
.u.set_val = (arbitrary_set *)other_config }
|
||||
};
|
||||
|
||||
xen_call_(session, "network.set_other_config", param_values, 2, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = network },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = key },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = value }
|
||||
};
|
||||
|
||||
xen_call_(session, "network.add_to_other_config", param_values, 3, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = network },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = key }
|
||||
};
|
||||
|
||||
xen_call_(session, "network.remove_from_other_config", param_values, 2, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_network_get_all(xen_session *session, struct xen_network_set **result)
|
||||
{
|
||||
|
||||
+7
-10
@@ -125,16 +125,13 @@ class GrubLineEditor(curses.textpad.Textbox):
|
||||
is that we can handle lines longer than the window."""
|
||||
|
||||
self.win.clear()
|
||||
if self.pos > 70:
|
||||
if self.pos > 130:
|
||||
off = 120
|
||||
else:
|
||||
off = 55
|
||||
l = [ "<" ] + self.line[off:]
|
||||
p = self.pos - off
|
||||
else:
|
||||
l = self.line[:70]
|
||||
p = self.pos
|
||||
p = self.pos
|
||||
off = 0
|
||||
while p > 70:
|
||||
p -= 55
|
||||
off += 55
|
||||
|
||||
l = self.line[off:off+70]
|
||||
self.win.addstr(0, 0, string.join(l, ("")))
|
||||
if self.pos > 70:
|
||||
self.win.addch(0, 0, curses.ACS_LARROW)
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
|
||||
# Copyright (C) 2007 XenSource Inc.
|
||||
#============================================================================
|
||||
|
||||
|
||||
from httplib import FakeSocket, HTTPConnection, HTTP
|
||||
import socket
|
||||
import string
|
||||
import xmlrpclib
|
||||
from types import StringTypes
|
||||
|
||||
|
||||
try:
|
||||
import SSHTransport
|
||||
ssh_enabled = True
|
||||
except ImportError:
|
||||
# SSHTransport is disabled on Python <2.4, because it uses the subprocess
|
||||
# package.
|
||||
ssh_enabled = False
|
||||
|
||||
|
||||
# A new ServerProxy that also supports httpu urls. An http URL comes in the
|
||||
# form:
|
||||
#
|
||||
# httpu:///absolute/path/to/socket.sock
|
||||
#
|
||||
# It assumes that the RPC handler is /RPC2. This probably needs to be improved
|
||||
|
||||
class HTTPUnixConnection(HTTPConnection):
|
||||
def connect(self):
|
||||
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
self.sock.connect(self.host)
|
||||
|
||||
class HTTPUnix(HTTP):
|
||||
_connection_class = HTTPUnixConnection
|
||||
|
||||
class UnixTransport(xmlrpclib.Transport):
|
||||
def request(self, host, handler, request_body, verbose=0):
|
||||
self.__handler = handler
|
||||
return xmlrpclib.Transport.request(self, host, '/RPC2',
|
||||
request_body, verbose)
|
||||
def make_connection(self, host):
|
||||
return HTTPUnix(self.__handler)
|
||||
|
||||
|
||||
# We need our own transport for HTTPS, because xmlrpclib.SafeTransport is
|
||||
# broken -- it does not handle ERROR_ZERO_RETURN properly.
|
||||
class HTTPSTransport(xmlrpclib.SafeTransport):
|
||||
def _parse_response(self, file, sock):
|
||||
p, u = self.getparser()
|
||||
while 1:
|
||||
try:
|
||||
if sock:
|
||||
response = sock.recv(1024)
|
||||
else:
|
||||
response = file.read(1024)
|
||||
except socket.sslerror, exn:
|
||||
if exn[0] == socket.SSL_ERROR_ZERO_RETURN:
|
||||
break
|
||||
raise
|
||||
|
||||
if not response:
|
||||
break
|
||||
if self.verbose:
|
||||
print 'body:', repr(response)
|
||||
p.feed(response)
|
||||
|
||||
file.close()
|
||||
p.close()
|
||||
return u.close()
|
||||
|
||||
|
||||
# See xmlrpclib2.TCPXMLRPCServer._marshalled_dispatch.
|
||||
def conv_string(x):
|
||||
if isinstance(x, StringTypes):
|
||||
s = string.replace(x, "'", r"\047")
|
||||
exec "s = '" + s + "'"
|
||||
return s
|
||||
else:
|
||||
return x
|
||||
|
||||
|
||||
class ServerProxy(xmlrpclib.ServerProxy):
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
||||
allow_none=1):
|
||||
if transport == None:
|
||||
(protocol, rest) = uri.split(':', 1)
|
||||
if protocol == 'httpu':
|
||||
uri = 'http:' + rest
|
||||
transport = UnixTransport()
|
||||
elif protocol == 'https':
|
||||
transport = HTTPSTransport()
|
||||
elif protocol == 'ssh':
|
||||
global ssh_enabled
|
||||
if ssh_enabled:
|
||||
(transport, uri) = SSHTransport.getHTTPURI(uri)
|
||||
else:
|
||||
raise ValueError(
|
||||
"SSH transport not supported on Python <2.4.")
|
||||
xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
|
||||
verbose, allow_none)
|
||||
|
||||
def __request(self, methodname, params):
|
||||
response = xmlrpclib.ServerProxy.__request(self, methodname, params)
|
||||
|
||||
if isinstance(response, tuple):
|
||||
return tuple([conv_string(x) for x in response])
|
||||
else:
|
||||
return conv_string(response)
|
||||
@@ -21,12 +21,10 @@ An enhanced XML-RPC client/server interface for Python.
|
||||
"""
|
||||
|
||||
import re
|
||||
import string
|
||||
import fcntl
|
||||
from types import *
|
||||
|
||||
|
||||
from httplib import HTTPConnection, HTTP
|
||||
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
|
||||
import SocketServer
|
||||
import xmlrpclib, socket, os, stat
|
||||
@@ -36,14 +34,6 @@ import mkdir
|
||||
from xen.web import connection
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
try:
|
||||
import SSHTransport
|
||||
ssh_enabled = True
|
||||
except ImportError:
|
||||
# SSHTransport is disabled on Python <2.4, because it uses the subprocess
|
||||
# package.
|
||||
ssh_enabled = False
|
||||
|
||||
#
|
||||
# Convert all integers to strings as described in the Xen API
|
||||
#
|
||||
@@ -64,13 +54,6 @@ def stringify(value):
|
||||
return value
|
||||
|
||||
|
||||
# A new ServerProxy that also supports httpu urls. An http URL comes in the
|
||||
# form:
|
||||
#
|
||||
# httpu:///absolute/path/to/socket.sock
|
||||
#
|
||||
# It assumes that the RPC handler is /RPC2. This probably needs to be improved
|
||||
|
||||
# We're forced to subclass the RequestHandler class so that we can work around
|
||||
# some bugs in Keep-Alive handling and also enabled it by default
|
||||
class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||
@@ -106,60 +89,6 @@ class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||
if self.close_connection == 1:
|
||||
self.connection.shutdown(1)
|
||||
|
||||
class HTTPUnixConnection(HTTPConnection):
|
||||
def connect(self):
|
||||
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
self.sock.connect(self.host)
|
||||
|
||||
class HTTPUnix(HTTP):
|
||||
_connection_class = HTTPUnixConnection
|
||||
|
||||
class UnixTransport(xmlrpclib.Transport):
|
||||
def request(self, host, handler, request_body, verbose=0):
|
||||
self.__handler = handler
|
||||
return xmlrpclib.Transport.request(self, host, '/RPC2',
|
||||
request_body, verbose)
|
||||
def make_connection(self, host):
|
||||
return HTTPUnix(self.__handler)
|
||||
|
||||
|
||||
# See _marshalled_dispatch below.
|
||||
def conv_string(x):
|
||||
if isinstance(x, StringTypes):
|
||||
s = string.replace(x, "'", r"\047")
|
||||
exec "s = '" + s + "'"
|
||||
return s
|
||||
else:
|
||||
return x
|
||||
|
||||
|
||||
class ServerProxy(xmlrpclib.ServerProxy):
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
||||
allow_none=1):
|
||||
if transport == None:
|
||||
(protocol, rest) = uri.split(':', 1)
|
||||
if protocol == 'httpu':
|
||||
uri = 'http:' + rest
|
||||
transport = UnixTransport()
|
||||
elif protocol == 'ssh':
|
||||
global ssh_enabled
|
||||
if ssh_enabled:
|
||||
(transport, uri) = SSHTransport.getHTTPURI(uri)
|
||||
else:
|
||||
raise ValueError(
|
||||
"SSH transport not supported on Python <2.4.")
|
||||
xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
|
||||
verbose, allow_none)
|
||||
|
||||
def __request(self, methodname, params):
|
||||
response = xmlrpclib.ServerProxy.__request(self, methodname, params)
|
||||
|
||||
if isinstance(response, tuple):
|
||||
return tuple([conv_string(x) for x in response])
|
||||
else:
|
||||
return conv_string(response)
|
||||
|
||||
|
||||
# This is a base XML-RPC server for TCP. It sets allow_reuse_address to
|
||||
# true, and has an improved marshaller that logs and serializes exceptions.
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ from xen.xend.XendAuthSessions import instance as auth_manager
|
||||
from xen.xend.XendError import *
|
||||
from xen.xend.XendClient import ERROR_INVALID_DOMAIN
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendNetwork import XendNetwork
|
||||
from xen.xend.XendTask import XendTask
|
||||
from xen.xend.XendPIFMetrics import XendPIFMetrics
|
||||
from xen.xend.XendVMMetrics import XendVMMetrics
|
||||
|
||||
from xen.xend.XendAPIConstants import *
|
||||
@@ -436,6 +438,12 @@ class XendAPI(object):
|
||||
'debug' : valid_debug,
|
||||
}
|
||||
|
||||
autoplug_classes = {
|
||||
'network' : XendNetwork,
|
||||
'VM_metrics' : XendVMMetrics,
|
||||
'PIF_metrics' : XendPIFMetrics,
|
||||
}
|
||||
|
||||
# Cheat methods
|
||||
# -------------
|
||||
# Methods that have a trivial implementation for all classes.
|
||||
@@ -457,6 +465,40 @@ class XendAPI(object):
|
||||
setattr(cls, get_by_uuid, _get_by_uuid)
|
||||
setattr(cls, get_uuid, _get_uuid)
|
||||
|
||||
|
||||
# Autoplugging classes
|
||||
# --------------------
|
||||
# These have all of their methods grabbed out from the implementation
|
||||
# class, and wrapped up to be compatible with the Xen-API.
|
||||
|
||||
for api_cls, impl_cls in autoplug_classes.items():
|
||||
def doit(n):
|
||||
getter = getattr(cls, '_%s_get' % api_cls)
|
||||
dot_n = '%s.%s' % (api_cls, n)
|
||||
full_n = '%s_%s' % (api_cls, n)
|
||||
if not hasattr(cls, full_n):
|
||||
f = getattr(impl_cls, n)
|
||||
argcounts[dot_n] = f.func_code.co_argcount + 1
|
||||
setattr(cls, full_n,
|
||||
lambda s, session, ref, *args: \
|
||||
xen_api_success( \
|
||||
f(getter(s, session, ref), *args)))
|
||||
|
||||
ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
|
||||
rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
|
||||
methods = getattr(cls, '%s_methods' % api_cls, [])
|
||||
funcs = getattr(cls, '%s_funcs' % api_cls, [])
|
||||
|
||||
for attr_name in ro_attrs + rw_attrs:
|
||||
doit('get_%s' % attr_name)
|
||||
for attr_name in rw_attrs + cls.Base_attr_rw:
|
||||
doit('set_%s' % attr_name)
|
||||
for method_name, return_type in methods + cls.Base_methods:
|
||||
doit('%s' % method_name)
|
||||
for func_name, return_type in funcs + cls.Base_funcs:
|
||||
doit('%s' % func_name)
|
||||
|
||||
|
||||
# Wrapping validators around XMLRPC calls
|
||||
# ---------------------------------------
|
||||
|
||||
@@ -466,7 +508,8 @@ class XendAPI(object):
|
||||
n_ = n.replace('.', '_')
|
||||
try:
|
||||
f = getattr(cls, n_)
|
||||
argcounts[n] = f.func_code.co_argcount - 1
|
||||
if n not in argcounts:
|
||||
argcounts[n] = f.func_code.co_argcount - 1
|
||||
|
||||
validators = takes_instance and validator and \
|
||||
[validator] or []
|
||||
@@ -516,7 +559,7 @@ class XendAPI(object):
|
||||
|
||||
Base_attr_ro = ['uuid']
|
||||
Base_attr_rw = []
|
||||
Base_methods = [('destroy', None), ('get_record', 'Struct')]
|
||||
Base_methods = [('get_record', 'Struct')]
|
||||
Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
|
||||
|
||||
# Xen API: Class Session
|
||||
@@ -916,59 +959,40 @@ class XendAPI(object):
|
||||
|
||||
network_attr_ro = ['VIFs', 'PIFs']
|
||||
network_attr_rw = ['name_label',
|
||||
'name_description']
|
||||
'name_description',
|
||||
'other_config']
|
||||
network_methods = [('add_to_other_config', None),
|
||||
('remove_from_other_config', None),
|
||||
('destroy', None)]
|
||||
network_funcs = [('create', None)]
|
||||
|
||||
network_funcs = [('create', 'network')]
|
||||
|
||||
def network_create(self, _, name_label, name_description):
|
||||
return xen_api_success(
|
||||
XendNode.instance().network_create(name_label, name_description))
|
||||
|
||||
def network_destroy(self, _, ref):
|
||||
return xen_api_success(XendNode.instance().network_destroy(ref))
|
||||
|
||||
def _get_network(self, ref):
|
||||
def _network_get(self, _, ref):
|
||||
return XendNode.instance().get_network(ref)
|
||||
|
||||
def network_get_all(self, _):
|
||||
return xen_api_success(XendNode.instance().get_network_refs())
|
||||
|
||||
def network_get_record(self, _, ref):
|
||||
return xen_api_success(
|
||||
XendNode.instance().get_network(ref).get_record())
|
||||
def network_create(self, _, record):
|
||||
return xen_api_success(XendNode.instance().network_create(record))
|
||||
|
||||
def network_get_name_label(self, _, ref):
|
||||
return xen_api_success(self._get_network(ref).name_label)
|
||||
def network_destroy(self, _, ref):
|
||||
return xen_api_success(XendNode.instance().network_destroy(ref))
|
||||
|
||||
def network_get_name_description(self, _, ref):
|
||||
return xen_api_success(self._get_network(ref).name_description)
|
||||
|
||||
def network_get_VIFs(self, _, ref):
|
||||
return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
|
||||
|
||||
def network_get_PIFs(self, session, ref):
|
||||
return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
|
||||
|
||||
def network_set_name_label(self, _, ref, val):
|
||||
return xen_api_success(self._get_network(ref).set_name_label(val))
|
||||
|
||||
def network_set_name_description(self, _, ref, val):
|
||||
return xen_api_success(self._get_network(ref).set_name_description(val))
|
||||
|
||||
# Xen API: Class PIF
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
PIF_attr_ro = ['metrics']
|
||||
PIF_attr_rw = ['device',
|
||||
'network',
|
||||
PIF_attr_ro = ['network',
|
||||
'host',
|
||||
'metrics']
|
||||
PIF_attr_rw = ['device',
|
||||
'MAC',
|
||||
'MTU',
|
||||
'VLAN']
|
||||
|
||||
PIF_attr_inst = PIF_attr_rw
|
||||
|
||||
PIF_methods = [('create_VLAN', 'int')]
|
||||
PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
|
||||
|
||||
def _get_PIF(self, ref):
|
||||
return XendNode.instance().pifs[ref]
|
||||
@@ -1049,21 +1073,9 @@ class XendAPI(object):
|
||||
def PIF_metrics_get_all(self, _):
|
||||
return xen_api_success(XendNode.instance().pif_metrics.keys())
|
||||
|
||||
def _PIF_metrics_get(self, ref):
|
||||
def _PIF_metrics_get(self, _, ref):
|
||||
return XendNode.instance().pif_metrics[ref]
|
||||
|
||||
def PIF_metrics_get_record(self, _, ref):
|
||||
return xen_api_success(self._PIF_metrics_get(ref).get_record())
|
||||
|
||||
def PIF_metrics_get_io_read_kbs(self, _, ref):
|
||||
return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
|
||||
|
||||
def PIF_metrics_get_io_write_kbs(self, _, ref):
|
||||
return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
|
||||
|
||||
def PIF_metrics_get_last_updated(self, _1, _2):
|
||||
return xen_api_success(now())
|
||||
|
||||
|
||||
# Xen API: Class VM
|
||||
# ----------------------------------------------------------------
|
||||
@@ -1131,7 +1143,8 @@ class XendAPI(object):
|
||||
('save', None),
|
||||
('set_memory_dynamic_max_live', None),
|
||||
('set_memory_dynamic_min_live', None),
|
||||
('send_trigger', None)]
|
||||
('send_trigger', None),
|
||||
('destroy', None)]
|
||||
|
||||
VM_funcs = [('create', 'VM'),
|
||||
('restore', None),
|
||||
@@ -1390,7 +1403,8 @@ class XendAPI(object):
|
||||
if key.startswith("cpumap"):
|
||||
vcpu = int(key[6:])
|
||||
try:
|
||||
xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
|
||||
cpus = map(int, value.split(","))
|
||||
xendom.domain_pincpu(xeninfo.getDomid(), vcpu, cpus)
|
||||
except Exception, ex:
|
||||
log.exception(ex)
|
||||
|
||||
@@ -1633,14 +1647,15 @@ class XendAPI(object):
|
||||
|
||||
def VM_send_sysrq(self, _, vm_ref, req):
|
||||
xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
|
||||
if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
|
||||
or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
|
||||
xeninfo.send_sysrq(req)
|
||||
return xen_api_success_void()
|
||||
else:
|
||||
return xen_api_error(
|
||||
['VM_BAD_POWER_STATE', vm_ref,
|
||||
XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
|
||||
XendDomain.POWER_STATE_NAMES[xeninfo.state]])
|
||||
xeninfo.send_sysrq(req)
|
||||
return xen_api_success_void()
|
||||
|
||||
|
||||
def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
|
||||
xendom = XendDomain.instance()
|
||||
@@ -1675,58 +1690,31 @@ class XendAPI(object):
|
||||
VM_metrics_attr_rw = []
|
||||
VM_metrics_methods = []
|
||||
|
||||
def _VM_metrics_get(self, ref):
|
||||
def VIF_metrics_get_all(self, session):
|
||||
return self.VIF_get_all(session)
|
||||
|
||||
def _VM_metrics_get(self, _, ref):
|
||||
return XendVMMetrics.get_by_uuid(ref)
|
||||
|
||||
def VM_metrics_get_all(self, _):
|
||||
return xen_api_success(XendVMMetrics.get_all())
|
||||
|
||||
def VM_metrics_get_record(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_record())
|
||||
|
||||
def VM_metrics_get_memory_actual(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
|
||||
|
||||
def VM_metrics_get_VCPUs_number(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
|
||||
|
||||
def VM_metrics_get_VCPUs_utilisation(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
|
||||
|
||||
def VM_metrics_get_VCPUs_CPU(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
|
||||
|
||||
def VM_metrics_get_VCPUs_flags(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
|
||||
|
||||
def VM_metrics_get_VCPUs_params(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
|
||||
|
||||
def VM_metrics_get_start_time(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_start_time())
|
||||
|
||||
def VM_metrics_get_state(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_state())
|
||||
|
||||
def VM_metrics_get_last_updated(self, _1, _2):
|
||||
return xen_api_success(now())
|
||||
|
||||
|
||||
# Xen API: Class VBD
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
VBD_attr_ro = ['metrics',
|
||||
'runtime_properties']
|
||||
VBD_attr_rw = ['VM',
|
||||
VBD_attr_ro = ['VM',
|
||||
'VDI',
|
||||
'device',
|
||||
'metrics',
|
||||
'runtime_properties']
|
||||
VBD_attr_rw = ['device',
|
||||
'bootable',
|
||||
'mode',
|
||||
'type']
|
||||
|
||||
VBD_attr_inst = VBD_attr_rw
|
||||
|
||||
VBD_methods = [('media_change', None)]
|
||||
VBD_methods = [('media_change', None), ('destroy', None)]
|
||||
VBD_funcs = [('create', 'VBD')]
|
||||
|
||||
# object methods
|
||||
@@ -1868,7 +1856,10 @@ class XendAPI(object):
|
||||
'io_write_kbs',
|
||||
'last_updated']
|
||||
VBD_metrics_attr_rw = []
|
||||
VBD_methods = []
|
||||
VBD_metrics_methods = []
|
||||
|
||||
def VBD_metrics_get_all(self, session):
|
||||
return self.VBD_get_all(session)
|
||||
|
||||
def VBD_metrics_get_record(self, _, ref):
|
||||
vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
|
||||
@@ -1893,16 +1884,17 @@ class XendAPI(object):
|
||||
# Xen API: Class VIF
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
VIF_attr_ro = ['metrics',
|
||||
VIF_attr_ro = ['network',
|
||||
'VM',
|
||||
'metrics',
|
||||
'runtime_properties']
|
||||
VIF_attr_rw = ['device',
|
||||
'network',
|
||||
'VM',
|
||||
'MAC',
|
||||
'MTU']
|
||||
|
||||
VIF_attr_inst = VIF_attr_rw
|
||||
|
||||
VIF_methods = [('destroy', None)]
|
||||
VIF_funcs = [('create', 'VIF')]
|
||||
|
||||
|
||||
@@ -1960,10 +1952,10 @@ class XendAPI(object):
|
||||
return xen_api_success(vif_ref)
|
||||
|
||||
def VIF_get_VM(self, session, vif_ref):
|
||||
xendom = XendDomain.instance()
|
||||
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
|
||||
xendom = XendDomain.instance()
|
||||
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
|
||||
return xen_api_success(vm.get_uuid())
|
||||
|
||||
|
||||
def VIF_get_MTU(self, session, vif_ref):
|
||||
return self._VIF_get(vif_ref, 'MTU')
|
||||
|
||||
@@ -2008,7 +2000,7 @@ class XendAPI(object):
|
||||
'io_write_kbs',
|
||||
'last_updated']
|
||||
VIF_metrics_attr_rw = []
|
||||
VIF_methods = []
|
||||
VIF_metrics_methods = []
|
||||
|
||||
def VIF_metrics_get_record(self, _, ref):
|
||||
vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
|
||||
@@ -2044,7 +2036,7 @@ class XendAPI(object):
|
||||
'other_config']
|
||||
VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
|
||||
|
||||
VDI_methods = [('snapshot', 'VDI')]
|
||||
VDI_methods = [('snapshot', 'VDI'), ('destroy', None)]
|
||||
VDI_funcs = [('create', 'VDI'),
|
||||
('get_by_name_label', 'Set(VDI)')]
|
||||
|
||||
@@ -2161,6 +2153,7 @@ class XendAPI(object):
|
||||
|
||||
VTPM_attr_inst = VTPM_attr_rw
|
||||
|
||||
VTPM_methods = [('destroy', None)]
|
||||
VTPM_funcs = [('create', 'VTPM')]
|
||||
|
||||
# object methods
|
||||
@@ -2319,7 +2312,7 @@ class XendAPI(object):
|
||||
'name_label',
|
||||
'name_description']
|
||||
|
||||
SR_methods = [('clone', 'SR')]
|
||||
SR_methods = [('clone', 'SR'), ('destroy', None)]
|
||||
SR_funcs = [('get_by_name_label', 'Set(SR)'),
|
||||
('get_by_uuid', 'SR')]
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
|
||||
#============================================================================
|
||||
|
||||
from xen.util.xmlrpclib2 import ServerProxy
|
||||
from xen.util.xmlrpcclient import ServerProxy
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ class XendConfig(dict):
|
||||
'actions_after_reboot': 'restart',
|
||||
'actions_after_crash': 'restart',
|
||||
'actions_after_suspend': '',
|
||||
'is_template': False,
|
||||
'is_a_template': False,
|
||||
'is_control_domain': False,
|
||||
'features': '',
|
||||
'PV_bootloader': '',
|
||||
@@ -452,7 +452,10 @@ class XendConfig(dict):
|
||||
for key, typ in XENAPI_CFG_TYPES.items():
|
||||
val = sxp.child_value(sxp_cfg, key)
|
||||
if val is not None:
|
||||
cfg[key] = typ(val)
|
||||
try:
|
||||
cfg[key] = typ(val)
|
||||
except (ValueError, TypeError), e:
|
||||
log.warn('Unable to convert type value for key: %s' % key)
|
||||
|
||||
# Convert deprecated options to current equivalents.
|
||||
|
||||
@@ -845,6 +848,8 @@ class XendConfig(dict):
|
||||
sxpr.append([name, s])
|
||||
|
||||
for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
|
||||
if legacy in ('cpus'): # skip this
|
||||
continue
|
||||
if self.has_key(xenapi) and self[xenapi] not in (None, []):
|
||||
if type(self[xenapi]) == bool:
|
||||
# convert booleans to ints before making an sxp item
|
||||
@@ -858,7 +863,7 @@ class XendConfig(dict):
|
||||
sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
|
||||
|
||||
for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
|
||||
if legacy in ('domid', 'uuid'): # skip these
|
||||
if legacy in ('domid', 'uuid', 'cpus'): # skip these
|
||||
continue
|
||||
if self.has_key(legacy) and self[legacy] not in (None, []):
|
||||
sxpr.append([legacy, self[legacy]])
|
||||
|
||||
@@ -569,6 +569,26 @@ class XendDomain:
|
||||
finally:
|
||||
self.domains_lock.release()
|
||||
|
||||
def autostart_domains(self):
|
||||
""" Autostart managed domains that are marked as such. """
|
||||
|
||||
need_starting = []
|
||||
|
||||
self.domains_lock.acquire()
|
||||
try:
|
||||
for dom_uuid, dom in self.managed_domains.items():
|
||||
if dom and dom.state == DOM_STATE_HALTED:
|
||||
on_xend_start = dom.info.get('on_xend_start', 'ignore')
|
||||
auto_power_on = dom.info.get('auto_power_on', False)
|
||||
should_start = (on_xend_start == 'start') or auto_power_on
|
||||
if should_start:
|
||||
need_starting.append(dom_uuid)
|
||||
finally:
|
||||
self.domains_lock.release()
|
||||
|
||||
for dom_uuid in need_starting:
|
||||
self.domain_start(dom_uuid, False)
|
||||
|
||||
def cleanup_domains(self):
|
||||
"""Clean up domains that are marked as autostop.
|
||||
Should be called when Xend goes down. This is currently
|
||||
|
||||
@@ -152,8 +152,9 @@ def recreate(info, priv):
|
||||
try:
|
||||
vmpath = xstransact.Read(dompath, "vm")
|
||||
if not vmpath:
|
||||
log.warn('/local/domain/%d/vm is missing. recreate is '
|
||||
'confused, trying our best to recover' % domid)
|
||||
if not priv:
|
||||
log.warn('/local/domain/%d/vm is missing. recreate is '
|
||||
'confused, trying our best to recover' % domid)
|
||||
needs_reinitialising = True
|
||||
raise XendError('reinit')
|
||||
|
||||
@@ -2354,7 +2355,8 @@ class XendDomainInfo:
|
||||
if not dev_uuid:
|
||||
raise XendError('Failed to create device')
|
||||
|
||||
if self.state == XEN_API_VM_POWER_STATE_RUNNING:
|
||||
if self.state == XEN_API_VM_POWER_STATE_RUNNING \
|
||||
or self.state == XEN_API_VM_POWER_STATE_PAUSED:
|
||||
|
||||
_, config = self.info['devices'][dev_uuid]
|
||||
dev_control = self.getDeviceController('vif')
|
||||
|
||||
@@ -62,6 +62,7 @@ if 'TRACE' not in logging.__dict__:
|
||||
# Work around a bug in Python's inspect module: findsource is supposed to
|
||||
# raise IOError if it fails, with other functions in that module coping
|
||||
# with that, but some people are seeing IndexError raised from there.
|
||||
# This is Python bug 1628987. http://python.org/sf/1628987.
|
||||
if hasattr(inspect, 'findsource'):
|
||||
real_findsource = getattr(inspect, 'findsource')
|
||||
def findsource(*args, **kwargs):
|
||||
|
||||
@@ -24,8 +24,8 @@ import re
|
||||
"""Monitoring thread to keep track of Xend statistics. """
|
||||
|
||||
VBD_SYSFS_PATH = '/sys/devices/xen-backend/'
|
||||
VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_req'
|
||||
VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_req'
|
||||
VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_sect'
|
||||
VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_sect'
|
||||
VBD_DOMAIN_RE = r'vbd-(?P<domid>\d+)-(?P<devid>\d+)$'
|
||||
|
||||
NET_PROCFS_PATH = '/proc/net/dev'
|
||||
@@ -51,14 +51,9 @@ VIF_DOMAIN_RE = re.compile(r'vif(?P<domid>\d+)\.(?P<iface>\d+):\s*' +
|
||||
PROC_NET_DEV_RE)
|
||||
PIF_RE = re.compile(r'^\s*(?P<iface>peth\d+):\s*' + PROC_NET_DEV_RE)
|
||||
|
||||
# The VBD transfer figures are in "requests" where we don't
|
||||
# really know how many bytes per requests. For now we make
|
||||
# up a number roughly could be.
|
||||
VBD_ROUGH_BYTES_PER_REQUEST = 1024 * 8 * 4
|
||||
|
||||
# Interval to poll xc, sysfs and proc
|
||||
POLL_INTERVAL = 2.0
|
||||
|
||||
SECTOR_SIZE = 512
|
||||
class XendMonitor(threading.Thread):
|
||||
"""Monitors VCPU, VBD, VIF and PIF statistics for Xen API.
|
||||
|
||||
@@ -186,9 +181,8 @@ class XendMonitor(threading.Thread):
|
||||
usage_at = time.time()
|
||||
rd_stat = int(open(rd_stat_path).readline().strip())
|
||||
wr_stat = int(open(wr_stat_path).readline().strip())
|
||||
rd_stat *= VBD_ROUGH_BYTES_PER_REQUEST
|
||||
wr_stat *= VBD_ROUGH_BYTES_PER_REQUEST
|
||||
|
||||
rd_stat *= SECTOR_SIZE
|
||||
wr_stat *= SECTOR_SIZE
|
||||
if domid not in stats:
|
||||
stats[domid] = {}
|
||||
|
||||
|
||||
@@ -28,10 +28,17 @@ from XendLogging import log
|
||||
IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
|
||||
|
||||
class XendNetwork:
|
||||
def __init__(self, uuid, name, description):
|
||||
def __init__(self, uuid, record):
|
||||
self.uuid = uuid
|
||||
self.name_label = name
|
||||
self.name_description = description
|
||||
self.name_label = record.get('name_label', '')
|
||||
self.name_description = record.get('name_description', '')
|
||||
self.other_config = record.get('other_config', {})
|
||||
|
||||
def get_name_label(self):
|
||||
return self.name_label
|
||||
|
||||
def get_name_description(self):
|
||||
return self.name_description
|
||||
|
||||
def set_name_label(self, new_name):
|
||||
self.name_label = new_name
|
||||
@@ -41,7 +48,7 @@ class XendNetwork:
|
||||
self.name_description = new_desc
|
||||
XendNode.instance().save_networks()
|
||||
|
||||
def get_VIF_UUIDs(self):
|
||||
def get_VIFs(self):
|
||||
result = []
|
||||
vms = XendDomain.instance().get_all_vms()
|
||||
for vm in vms:
|
||||
@@ -52,17 +59,37 @@ class XendNetwork:
|
||||
result.append(vif)
|
||||
return result
|
||||
|
||||
def get_PIF_UUIDs(self):
|
||||
def get_PIFs(self):
|
||||
return [x.uuid for x in XendNode.instance().pifs.values()
|
||||
if x.network == self]
|
||||
|
||||
def get_record(self, transient = True):
|
||||
def get_other_config(self):
|
||||
return self.other_config
|
||||
|
||||
def set_other_config(self, value):
|
||||
self.other_config = value
|
||||
XendNode.instance().save_networks()
|
||||
|
||||
def add_to_other_config(self, key, value):
|
||||
self.other_config[key] = value
|
||||
XendNode.instance().save_networks()
|
||||
|
||||
def remove_from_other_config(self, key):
|
||||
if key in self.other_config:
|
||||
del self.other_config[key]
|
||||
XendNode.instance().save_networks()
|
||||
|
||||
def get_record(self):
|
||||
return self.get_record_internal(True)
|
||||
|
||||
def get_record_internal(self, transient):
|
||||
result = {
|
||||
'uuid': self.uuid,
|
||||
'name_label': self.name_label,
|
||||
'name_description': self.name_description,
|
||||
'other_config' : self.other_config,
|
||||
}
|
||||
if transient:
|
||||
result['VIFs'] = self.get_VIF_UUIDs()
|
||||
result['PIFs'] = self.get_PIF_UUIDs()
|
||||
result['VIFs'] = self.get_VIFs()
|
||||
result['PIFs'] = self.get_PIFs()
|
||||
return result
|
||||
@@ -141,11 +141,9 @@ class XendNode:
|
||||
saved_networks = self.state_store.load_state('network')
|
||||
if saved_networks:
|
||||
for net_uuid, network in saved_networks.items():
|
||||
self.network_create(network.get('name_label'),
|
||||
network.get('name_description', ''),
|
||||
False, net_uuid)
|
||||
self.network_create(network, False, net_uuid)
|
||||
else:
|
||||
self.network_create('net0', '', False)
|
||||
self.network_create({'name_label' : 'net0' }, False)
|
||||
|
||||
# initialise PIFs
|
||||
saved_pifs = self.state_store.load_state('pif')
|
||||
@@ -199,12 +197,10 @@ class XendNode:
|
||||
|
||||
|
||||
|
||||
def network_create(self, name_label, name_description, persist = True,
|
||||
net_uuid = None):
|
||||
def network_create(self, record, persist = True, net_uuid = None):
|
||||
if net_uuid is None:
|
||||
net_uuid = uuid.createString()
|
||||
self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
|
||||
name_description)
|
||||
self.networks[net_uuid] = XendNetwork(net_uuid, record)
|
||||
if persist:
|
||||
self.save_networks()
|
||||
return net_uuid
|
||||
@@ -280,7 +276,7 @@ class XendNode:
|
||||
self.state_store.save_state('pif', pif_records)
|
||||
|
||||
def save_networks(self):
|
||||
net_records = dict([(k, v.get_record(transient = False))
|
||||
net_records = dict([(k, v.get_record_internal(False))
|
||||
for k, v in self.networks.items()])
|
||||
self.state_store.save_state('network', net_records)
|
||||
|
||||
|
||||
@@ -165,7 +165,13 @@ class XendOptions:
|
||||
|
||||
def get_xend_tcp_xmlrpc_server_address(self):
|
||||
return self.get_config_string("xend-tcp-xmlrpc-server-address",
|
||||
self.xend_tcp_xmlrpc_server_address_default)
|
||||
self.xend_tcp_xmlrpc_server_address_default)
|
||||
|
||||
def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
|
||||
return self.get_config_string("xend-tcp-xmlrpc-server-ssl-key-file")
|
||||
|
||||
def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
|
||||
return self.get_config_string("xend-tcp-xmlrpc-server-ssl-cert-file")
|
||||
|
||||
def get_xend_unix_xmlrpc_server(self):
|
||||
return self.get_config_bool("xend-unix-xmlrpc-server",
|
||||
|
||||
@@ -39,11 +39,13 @@ class XendPIFMetrics:
|
||||
return pifs_util[pifname][n]
|
||||
return 0.0
|
||||
|
||||
def get_record(self):
|
||||
def get_last_updated(self):
|
||||
import xen.xend.XendAPI as XendAPI
|
||||
return XendAPI.now()
|
||||
|
||||
def get_record(self):
|
||||
return {'uuid' : self.uuid,
|
||||
'PIF' : self.pif.uuid,
|
||||
'io_read_kbs' : self.get_io_read_kbs(),
|
||||
'io_write_kbs' : self.get_io_write_kbs(),
|
||||
'last_updated' : XendAPI.now(),
|
||||
'last_updated' : self.get_last_updated(),
|
||||
}
|
||||
@@ -126,6 +126,13 @@ class XendStateStore:
|
||||
if val_name not in cls_dict:
|
||||
cls_dict[val_name] = {}
|
||||
cls_dict[val_name][val_uuid] = None
|
||||
elif val_type == '':
|
||||
# dictionary
|
||||
k = val_elem.getAttribute('key').encode('utf8')
|
||||
v = val_elem.getAttribute('value').encode('utf8')
|
||||
if val_name not in cls_dict:
|
||||
cls_dict[val_name] = {}
|
||||
cls_dict[val_name][k] = v
|
||||
elif val_type == 'string':
|
||||
cls_dict[val_name] = val_text.encode('utf8')
|
||||
elif val_type == 'float':
|
||||
@@ -197,7 +204,11 @@ class XendStateStore:
|
||||
if type(val) == dict:
|
||||
for val_uuid in val.keys():
|
||||
val_node = doc.createElement(key)
|
||||
val_node.setAttribute('uuid', val_uuid)
|
||||
if key == 'other_config':
|
||||
val_node.setAttribute('key', str(val_uuid))
|
||||
val_node.setAttribute('value', str(val[val_uuid]))
|
||||
else:
|
||||
val_node.setAttribute('uuid', val_uuid)
|
||||
node.appendChild(val_node)
|
||||
elif type(val) in (list, tuple):
|
||||
for val_uuid in val:
|
||||
|
||||
@@ -92,7 +92,7 @@ class XendVMMetrics:
|
||||
set_flag('blocked')
|
||||
set_flag('online')
|
||||
set_flag('running')
|
||||
vcpus_flags[i] = ",".join(flags)
|
||||
vcpus_flags[i] = flags
|
||||
return vcpus_flags
|
||||
else:
|
||||
return {}
|
||||
@@ -115,7 +115,7 @@ class XendVMMetrics:
|
||||
addState("dying")
|
||||
addState("crashed")
|
||||
addState("shutdown")
|
||||
return ",".join(states)
|
||||
return states
|
||||
except Exception, err:
|
||||
# ignore missing domain
|
||||
log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, str(err))
|
||||
@@ -140,8 +140,11 @@ class XendVMMetrics:
|
||||
def get_start_time(self):
|
||||
return self.xend_domain_instance.info.get("start_time", -1)
|
||||
|
||||
def get_record(self):
|
||||
def get_last_updated(self):
|
||||
import xen.xend.XendAPI as XendAPI
|
||||
return XendAPI.now()
|
||||
|
||||
def get_record(self):
|
||||
return { 'uuid' : self.uuid,
|
||||
'memory_actual' : self.get_memory_actual(),
|
||||
'VCPUs_number' : self.get_VCPUs_number(),
|
||||
@@ -151,5 +154,5 @@ class XendVMMetrics:
|
||||
'VCPUs_params' : self.get_VCPUs_params(),
|
||||
'start_time' : self.get_start_time(),
|
||||
'state' : self.get_state(),
|
||||
'last_updated' : XendAPI.now(),
|
||||
'last_updated' : self.get_last_updated(),
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2007 XenSource Inc.
|
||||
#============================================================================
|
||||
|
||||
|
||||
"""
|
||||
HTTPS wrapper for an XML-RPC server interface. Requires PyOpenSSL (Debian
|
||||
package python-pyopenssl).
|
||||
"""
|
||||
|
||||
import socket
|
||||
|
||||
from OpenSSL import SSL
|
||||
|
||||
from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
|
||||
|
||||
|
||||
class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
|
||||
def setup(self):
|
||||
self.connection = self.request
|
||||
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
|
||||
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
|
||||
|
||||
#
|
||||
# Taken from pyOpenSSL-0.6 examples (public-domain)
|
||||
#
|
||||
|
||||
class SSLWrapper:
|
||||
"""
|
||||
"""
|
||||
def __init__(self, conn):
|
||||
"""
|
||||
Connection is not yet a new-style class,
|
||||
so I'm making a proxy instead of subclassing.
|
||||
"""
|
||||
self.__dict__["conn"] = conn
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.__dict__["conn"], name)
|
||||
def __setattr__(self, name, value):
|
||||
setattr(self.__dict__["conn"], name, value)
|
||||
|
||||
def close(self):
|
||||
self.shutdown()
|
||||
return self.__dict__["conn"].close()
|
||||
|
||||
def shutdown(self, how=1):
|
||||
"""
|
||||
SimpleXMLRpcServer.doPOST calls shutdown(1),
|
||||
and Connection.shutdown() doesn't take
|
||||
an argument. So we just discard the argument.
|
||||
"""
|
||||
# Block until the shutdown is complete
|
||||
self.__dict__["conn"].shutdown()
|
||||
self.__dict__["conn"].shutdown()
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
This is the other part of the shutdown() workaround.
|
||||
Since servers create new sockets, we have to infect
|
||||
them with our magic. :)
|
||||
"""
|
||||
c, a = self.__dict__["conn"].accept()
|
||||
return (SSLWrapper(c), a)
|
||||
|
||||
#
|
||||
# End of pyOpenSSL-0.6 example code.
|
||||
#
|
||||
|
||||
class SSLXMLRPCServer(TCPXMLRPCServer):
|
||||
def __init__(self, addr, allowed, xenapi, logRequests = 1,
|
||||
ssl_key_file = None, ssl_cert_file = None):
|
||||
|
||||
TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
|
||||
SSLXMLRPCRequestHandler, logRequests)
|
||||
|
||||
if not ssl_key_file or not ssl_cert_file:
|
||||
raise ValueError("SSLXMLRPCServer requires ssl_key_file "
|
||||
"and ssl_cert_file to be set.")
|
||||
|
||||
# make a SSL socket
|
||||
ctx = SSL.Context(SSL.SSLv23_METHOD)
|
||||
ctx.set_options(SSL.OP_NO_SSLv2)
|
||||
ctx.use_privatekey_file (ssl_key_file)
|
||||
ctx.use_certificate_file(ssl_cert_file)
|
||||
self.socket = SSLWrapper(SSL.Connection(ctx,
|
||||
socket.socket(self.address_family,
|
||||
self.socket_type)))
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
@@ -52,6 +52,7 @@ from xen.xend import XendNode, XendOptions, XendAPI
|
||||
from xen.xend import Vifctl
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendClient import XEN_API_SOCKET
|
||||
from xen.xend.XendDomain import instance as xenddomain
|
||||
from xen.web.SrvDir import SrvDir
|
||||
|
||||
from SrvRoot import SrvRoot
|
||||
@@ -72,7 +73,7 @@ class XendServers:
|
||||
def add(self, server):
|
||||
self.servers.append(server)
|
||||
|
||||
def cleanup(self, signum = 0, frame = None):
|
||||
def cleanup(self, signum = 0, frame = None, reloading = False):
|
||||
log.debug("SrvServer.cleanup()")
|
||||
self.cleaningUp = True
|
||||
for server in self.servers:
|
||||
@@ -80,12 +81,18 @@ class XendServers:
|
||||
server.shutdown()
|
||||
except:
|
||||
pass
|
||||
|
||||
# clean up domains for those that have on_xend_stop
|
||||
if not reloading:
|
||||
xenddomain().cleanup_domains()
|
||||
|
||||
self.running = False
|
||||
|
||||
|
||||
def reloadConfig(self, signum = 0, frame = None):
|
||||
log.debug("SrvServer.reloadConfig()")
|
||||
self.reloadingConfig = True
|
||||
self.cleanup(signum, frame)
|
||||
self.cleanup(signum, frame, reloading = True)
|
||||
|
||||
def start(self, status):
|
||||
# Running the network script will spawn another process, which takes
|
||||
@@ -144,6 +151,12 @@ class XendServers:
|
||||
status.close()
|
||||
status = None
|
||||
|
||||
# Reaching this point means we can auto start domains
|
||||
try:
|
||||
xenddomain().autostart_domains()
|
||||
except Exception, e:
|
||||
log.exception("Failed while autostarting domains")
|
||||
|
||||
# loop to keep main thread alive until it receives a SIGTERM
|
||||
self.running = True
|
||||
while self.running:
|
||||
@@ -172,33 +185,49 @@ def _loadConfig(servers, root, reload):
|
||||
api_cfg = xoptions.get_xen_api_server()
|
||||
if api_cfg:
|
||||
try:
|
||||
addrs = [(str(x[0]).split(':'),
|
||||
len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
|
||||
len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
|
||||
or None)
|
||||
for x in api_cfg]
|
||||
for addrport, auth, allowed in addrs:
|
||||
if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
|
||||
log.error('Xen-API server configuration %s is invalid, ' +
|
||||
'as %s is not a valid authentication type.',
|
||||
api_cfg, auth)
|
||||
break
|
||||
for server_cfg in api_cfg:
|
||||
# Parse the xen-api-server config
|
||||
|
||||
host = 'localhost'
|
||||
port = 0
|
||||
use_tcp = False
|
||||
ssl_key_file = None
|
||||
ssl_cert_file = None
|
||||
auth_method = XendAPI.AUTH_NONE
|
||||
hosts_allowed = None
|
||||
|
||||
host_addr = server_cfg[0].split(':', 1)
|
||||
if len(host_addr) == 1 and host_addr[0].lower() == 'unix':
|
||||
use_tcp = False
|
||||
elif len(host_addr) == 1:
|
||||
use_tcp = True
|
||||
port = int(host_addr[0])
|
||||
elif len(host_addr) == 2:
|
||||
use_tcp = True
|
||||
host = str(host_addr[0])
|
||||
port = int(host_addr[1])
|
||||
|
||||
if len(server_cfg) > 1:
|
||||
if server_cfg[1] in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
|
||||
auth_method = server_cfg[1]
|
||||
|
||||
if len(server_cfg) > 2:
|
||||
hosts_allowed = server_cfg[2] or None
|
||||
|
||||
|
||||
if len(server_cfg) > 4:
|
||||
# SSL key and cert file
|
||||
ssl_key_file = server_cfg[3]
|
||||
ssl_cert_file = server_cfg[4]
|
||||
|
||||
|
||||
servers.add(XMLRPCServer(auth_method, True, use_tcp = use_tcp,
|
||||
ssl_key_file = ssl_key_file,
|
||||
ssl_cert_file = ssl_cert_file,
|
||||
host = host, port = port,
|
||||
path = XEN_API_SOCKET,
|
||||
hosts_allowed = hosts_allowed))
|
||||
|
||||
if len(addrport) == 1:
|
||||
if addrport[0] == 'unix':
|
||||
servers.add(XMLRPCServer(auth, True,
|
||||
path = XEN_API_SOCKET,
|
||||
hosts_allowed = allowed))
|
||||
else:
|
||||
servers.add(
|
||||
XMLRPCServer(auth, True, True, '',
|
||||
int(addrport[0]),
|
||||
hosts_allowed = allowed))
|
||||
else:
|
||||
addr, port = addrport
|
||||
servers.add(XMLRPCServer(auth, True, True, addr,
|
||||
int(port),
|
||||
hosts_allowed = allowed))
|
||||
except (ValueError, TypeError), exn:
|
||||
log.exception('Xen API Server init failed')
|
||||
log.error('Xen-API server configuration %s is invalid.', api_cfg)
|
||||
@@ -206,8 +235,17 @@ def _loadConfig(servers, root, reload):
|
||||
if xoptions.get_xend_tcp_xmlrpc_server():
|
||||
addr = xoptions.get_xend_tcp_xmlrpc_server_address()
|
||||
port = xoptions.get_xend_tcp_xmlrpc_server_port()
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
|
||||
host = addr, port = port))
|
||||
ssl_key_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_key_file()
|
||||
ssl_cert_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_cert_file()
|
||||
|
||||
if ssl_key_file and ssl_cert_file:
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
|
||||
ssl_key_file = ssl_key_file,
|
||||
ssl_cert_file = ssl_cert_file,
|
||||
host = addr, port = port))
|
||||
else:
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
|
||||
host = addr, port = port))
|
||||
|
||||
if xoptions.get_xend_unix_xmlrpc_server():
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
|
||||
|
||||
@@ -21,6 +21,11 @@ import socket
|
||||
import types
|
||||
import xmlrpclib
|
||||
from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
|
||||
try:
|
||||
from SSLXMLRPCServer import SSLXMLRPCServer
|
||||
ssl_enabled = True
|
||||
except ImportError:
|
||||
ssl_enabled = False
|
||||
|
||||
from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
|
||||
from xen.xend import XendLogging, XendDmesg
|
||||
@@ -87,14 +92,20 @@ methods = ['device_create', 'device_configure',
|
||||
exclude = ['domain_create', 'domain_restore']
|
||||
|
||||
class XMLRPCServer:
|
||||
def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
|
||||
port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
|
||||
def __init__(self, auth, use_xenapi, use_tcp = False,
|
||||
ssl_key_file = None, ssl_cert_file = None,
|
||||
host = "localhost", port = 8006, path = XML_RPC_SOCKET,
|
||||
hosts_allowed = None):
|
||||
|
||||
self.use_tcp = use_tcp
|
||||
self.port = port
|
||||
self.host = host
|
||||
self.path = path
|
||||
self.hosts_allowed = hosts_allowed
|
||||
|
||||
self.ssl_key_file = ssl_key_file
|
||||
self.ssl_cert_file = ssl_cert_file
|
||||
|
||||
self.ready = False
|
||||
self.running = True
|
||||
self.auth = auth
|
||||
@@ -107,14 +118,33 @@ class XMLRPCServer:
|
||||
|
||||
try:
|
||||
if self.use_tcp:
|
||||
log.info("Opening TCP XML-RPC server on %s%d%s",
|
||||
using_ssl = self.ssl_key_file and self.ssl_cert_file
|
||||
|
||||
log.info("Opening %s XML-RPC server on %s%d%s",
|
||||
using_ssl and 'HTTPS' or 'TCP',
|
||||
self.host and '%s:' % self.host or
|
||||
'all interfaces, port ',
|
||||
self.port, authmsg)
|
||||
self.server = TCPXMLRPCServer((self.host, self.port),
|
||||
self.hosts_allowed,
|
||||
self.xenapi is not None,
|
||||
logRequests = False)
|
||||
|
||||
if not ssl_enabled:
|
||||
raise ValueError("pyOpenSSL not installed. "
|
||||
"Unable to start HTTPS XML-RPC server")
|
||||
|
||||
if using_ssl:
|
||||
self.server = SSLXMLRPCServer(
|
||||
(self.host, self.port),
|
||||
self.hosts_allowed,
|
||||
self.xenapi is not None,
|
||||
logRequests = False,
|
||||
ssl_key_file = self.ssl_key_file,
|
||||
ssl_cert_file = self.ssl_cert_file)
|
||||
else:
|
||||
self.server = TCPXMLRPCServer(
|
||||
(self.host, self.port),
|
||||
self.hosts_allowed,
|
||||
self.xenapi is not None,
|
||||
logRequests = False)
|
||||
|
||||
else:
|
||||
log.info("Opening Unix domain socket XML-RPC server on %s%s",
|
||||
self.path, authmsg)
|
||||
@@ -126,7 +156,12 @@ class XMLRPCServer:
|
||||
ready = True
|
||||
running = False
|
||||
return
|
||||
|
||||
except Exception, e:
|
||||
log.exception('Cannot start server: %s!', e)
|
||||
ready = True
|
||||
running = False
|
||||
return
|
||||
|
||||
# Register Xen API Functions
|
||||
# -------------------------------------------------------------------
|
||||
# exportable functions are ones that do not begin with '_'
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2006 XenSource Inc.
|
||||
# Copyright (C) 2006-2007 XenSource Inc.
|
||||
#============================================================================
|
||||
#
|
||||
# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
|
||||
@@ -47,7 +47,7 @@
|
||||
import gettext
|
||||
import xmlrpclib
|
||||
|
||||
import xen.util.xmlrpclib2
|
||||
import xen.util.xmlrpcclient as xmlrpcclient
|
||||
|
||||
|
||||
translation = gettext.translation('xen-xm', fallback = True)
|
||||
@@ -85,7 +85,7 @@ class Failure(Exception):
|
||||
_RECONNECT_AND_RETRY = (lambda _ : ())
|
||||
|
||||
|
||||
class Session(xen.util.xmlrpclib2.ServerProxy):
|
||||
class Session(xmlrpcclient.ServerProxy):
|
||||
"""A server proxy and session manager for communicating with Xend using
|
||||
the Xen-API.
|
||||
|
||||
@@ -104,14 +104,16 @@ class Session(xen.util.xmlrpclib2.ServerProxy):
|
||||
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
||||
allow_none=1):
|
||||
xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
|
||||
encoding, verbose,
|
||||
allow_none)
|
||||
xmlrpcclient.ServerProxy.__init__(self, uri, transport, encoding,
|
||||
verbose, allow_none)
|
||||
self._session = None
|
||||
self.last_login_method = None
|
||||
self.last_login_params = None
|
||||
|
||||
|
||||
def getSession(self):
|
||||
return self._session
|
||||
|
||||
def xenapi_request(self, methodname, params):
|
||||
if methodname.startswith('login'):
|
||||
self._login(methodname, params)
|
||||
@@ -150,7 +152,7 @@ class Session(xen.util.xmlrpclib2.ServerProxy):
|
||||
elif name.startswith('login'):
|
||||
return lambda *params: self._login(name, params)
|
||||
else:
|
||||
return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
|
||||
return xmlrpcclient.ServerProxy.__getattr__(self, name)
|
||||
|
||||
|
||||
def _parse_result(result):
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
<!ELEMENT other_config EMPTY>
|
||||
<!ATTLIST other_config key CDATA #REQUIRED
|
||||
value CDATA #REQUIRED>
|
||||
value CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT qos_algorithm_param EMPTY>
|
||||
<!ATTLIST qos_algorithm_param key CDATA #REQUIRED
|
||||
|
||||
@@ -104,6 +104,11 @@ gopts.opt('xmldryrun', short='x',
|
||||
use="XML dry run - prints the resulting configuration in XML but "
|
||||
"does not create the domain.")
|
||||
|
||||
gopts.opt('skipdtd', short='s',
|
||||
fn=set_true, default=0,
|
||||
use="Skip DTD checking - skips checks on XML before creating. "
|
||||
" Experimental. Can decrease create time." )
|
||||
|
||||
gopts.opt('paused', short='p',
|
||||
fn=set_true, default=0,
|
||||
use='Leave the domain paused after it is created.')
|
||||
@@ -1098,6 +1103,8 @@ def parseCommandLine(argv):
|
||||
if not gopts.vals.xauthority:
|
||||
gopts.vals.xauthority = get_xauthority()
|
||||
|
||||
gopts.is_xml = False
|
||||
|
||||
# Process remaining args as config variables.
|
||||
for arg in args:
|
||||
if '=' in arg:
|
||||
@@ -1106,11 +1113,16 @@ def parseCommandLine(argv):
|
||||
if gopts.vals.config:
|
||||
config = gopts.vals.config
|
||||
else:
|
||||
gopts.load_defconfig()
|
||||
preprocess(gopts.vals)
|
||||
if not gopts.getopt('name') and gopts.getopt('defconfig'):
|
||||
gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
|
||||
config = make_config(gopts.vals)
|
||||
try:
|
||||
gopts.load_defconfig()
|
||||
preprocess(gopts.vals)
|
||||
if not gopts.getopt('name') and gopts.getopt('defconfig'):
|
||||
gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
|
||||
config = make_config(gopts.vals)
|
||||
except XMLFileError, ex:
|
||||
XMLFile = ex.getFile()
|
||||
gopts.is_xml = True
|
||||
config = ex.getFile()
|
||||
|
||||
return (gopts, config)
|
||||
|
||||
@@ -1233,6 +1245,8 @@ def help():
|
||||
return str(gopts)
|
||||
|
||||
def main(argv):
|
||||
is_xml = False
|
||||
|
||||
try:
|
||||
(opts, config) = parseCommandLine(argv)
|
||||
except StandardError, ex:
|
||||
@@ -1241,23 +1255,24 @@ def main(argv):
|
||||
if not opts:
|
||||
return
|
||||
|
||||
if type(config) == str:
|
||||
try:
|
||||
config = sxp.parse(file(config))[0]
|
||||
except IOError, exn:
|
||||
raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
|
||||
if not opts.is_xml:
|
||||
if type(config) == str:
|
||||
try:
|
||||
config = sxp.parse(file(config))[0]
|
||||
except IOError, exn:
|
||||
raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
from xen.xm.xenapi_create import sxp2xml
|
||||
sxp2xml_inst = sxp2xml()
|
||||
doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
from xen.xm.xenapi_create import sxp2xml
|
||||
sxp2xml_inst = sxp2xml()
|
||||
doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
|
||||
if opts.vals.dryrun and not opts.is_xml:
|
||||
SXPPrettyPrint.prettyprint(config)
|
||||
|
||||
if opts.vals.dryrun:
|
||||
SXPPrettyPrint.prettyprint(config)
|
||||
|
||||
if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
|
||||
from xml.dom.ext import PrettyPrint as XMLPrettyPrint
|
||||
XMLPrettyPrint(doc)
|
||||
if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
|
||||
from xml.dom.ext import PrettyPrint as XMLPrettyPrint
|
||||
XMLPrettyPrint(doc)
|
||||
|
||||
if opts.vals.dryrun or opts.vals.xmldryrun:
|
||||
return
|
||||
@@ -1268,10 +1283,15 @@ def main(argv):
|
||||
if serverType == SERVER_XEN_API:
|
||||
from xen.xm.xenapi_create import xenapi_create
|
||||
xenapi_create_inst = xenapi_create()
|
||||
vm_refs = xenapi_create_inst.create(document = doc)
|
||||
if opts.is_xml:
|
||||
vm_refs = xenapi_create_inst.create(filename = config,
|
||||
skipdtd = opts.vals.skipdtd)
|
||||
else:
|
||||
vm_refs = xenapi_create_inst.create(document = doc,
|
||||
skipdtd = opts.vals.skipdtd)
|
||||
|
||||
map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
|
||||
else:
|
||||
elif not opts.is_xml:
|
||||
if not create_security_check(config):
|
||||
raise security.ACMError(
|
||||
'Security Configuration prevents domain from starting')
|
||||
|
||||
+17
-18
@@ -49,7 +49,7 @@ from xen.xend.XendConstants import *
|
||||
|
||||
from xen.xm.opts import OptionError, Opts, wrap, set_true
|
||||
from xen.xm import console
|
||||
from xen.util.xmlrpclib2 import ServerProxy
|
||||
from xen.util.xmlrpcclient import ServerProxy
|
||||
|
||||
import XenAPI
|
||||
|
||||
@@ -722,7 +722,7 @@ def getDomains(domain_names, state, full = 0):
|
||||
states = ('running', 'blocked', 'paused', 'shutdown',
|
||||
'crashed', 'dying')
|
||||
def state_on_off(state):
|
||||
if dom_metrics['state'].find(state) > -1:
|
||||
if state in dom_metrics['state']:
|
||||
return state[0]
|
||||
else:
|
||||
return "-"
|
||||
@@ -850,7 +850,8 @@ def parse_doms_info(info):
|
||||
|
||||
def check_sched_type(sched):
|
||||
if serverType == SERVER_XEN_API:
|
||||
current = server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
|
||||
current = server.xenapi.host.get_sched_policy(
|
||||
server.xenapi.session.get_this_host(server.getSession()))
|
||||
else:
|
||||
current = 'unknown'
|
||||
for x in server.xend.node.info()[1:]:
|
||||
@@ -952,12 +953,10 @@ def xm_vcpu_list(args):
|
||||
['name', vm_records[vm_ref]['name_label']],
|
||||
['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
|
||||
|
||||
|
||||
|
||||
for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
|
||||
def chk_flag(flag):
|
||||
return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
|
||||
.find(flag) > -1 and 1 or 0
|
||||
return flag in vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
|
||||
and 1 or 0
|
||||
|
||||
vcpu_info = ['vcpu',
|
||||
['number',
|
||||
@@ -1044,7 +1043,7 @@ def xm_vcpu_list(args):
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
nr_cpus = len(server.xenapi.host.get_host_CPUs(
|
||||
server.xenapi.session.get_this_host()))
|
||||
server.xenapi.session.get_this_host(server.getSession())))
|
||||
else:
|
||||
for x in server.xend.node.info()[1:]:
|
||||
if len(x) > 1 and x[0] == 'nr_cpus':
|
||||
@@ -1260,8 +1259,9 @@ def xm_vcpu_pin(args):
|
||||
cpumap = cpu_make_map(args[2])
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
cpumap = map(str, cpumap)
|
||||
server.xenapi.VM.add_to_VCPUs_params_live(
|
||||
get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
|
||||
get_single_vm(dom), "cpumap%i" % int(vcpu), ",".join(cpumap))
|
||||
else:
|
||||
server.xend.domain.pincpu(dom, vcpu, cpumap)
|
||||
|
||||
@@ -1509,7 +1509,7 @@ def xm_info(args):
|
||||
# Need to fake out old style xm info as people rely on parsing it
|
||||
|
||||
host_record = server.xenapi.host.get_record(
|
||||
server.xenapi.session.get_this_host())
|
||||
server.xenapi.session.get_this_host(server.getSession()))
|
||||
|
||||
host_cpu_records = map(server.xenapi.host_cpu.get_record, host_record["host_CPUs"])
|
||||
|
||||
@@ -1686,7 +1686,7 @@ def xm_debug_keys(args):
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.host.send_debug_keys(
|
||||
server.xenapi.session.get_this_host(),
|
||||
server.xenapi.session.get_this_host(server.getSession()),
|
||||
keys)
|
||||
else:
|
||||
server.xend.node.send_debug_keys(keys)
|
||||
@@ -1715,7 +1715,7 @@ def xm_dmesg(args):
|
||||
usage('dmesg')
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
host = server.xenapi.session.get_this_host()
|
||||
host = server.xenapi.session.get_this_host(server.getSession())
|
||||
if use_clear:
|
||||
print server.xenapi.host.dmesg_clear(host),
|
||||
else:
|
||||
@@ -1731,7 +1731,7 @@ def xm_log(args):
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
print server.xenapi.host.get_log(
|
||||
server.xenapi.session.get_this_host())
|
||||
server.xenapi.session.get_this_host(server.getSession()))
|
||||
else:
|
||||
print server.xend.node.log()
|
||||
|
||||
@@ -2371,11 +2371,10 @@ def _run_cmd(cmd, cmd_name, args):
|
||||
if isinstance(e, security.ACMError):
|
||||
err(str(e))
|
||||
return False, 1
|
||||
else:
|
||||
print "Unexpected error:", sys.exc_info()[0]
|
||||
print
|
||||
print "Please report to xen-devel@lists.xensource.com"
|
||||
raise
|
||||
print "Unexpected error:", sys.exc_info()[0]
|
||||
print
|
||||
print "Please report to xen-devel@lists.xensource.com"
|
||||
raise
|
||||
|
||||
return False, 1
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import os.path
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
|
||||
def _line_wrap(text, width = 70):
|
||||
lines = []
|
||||
current_line = ''
|
||||
@@ -60,6 +62,15 @@ class OptionError(Exception):
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
class XMLFileError(Exception):
|
||||
"""Thrown is input is an XML File"""
|
||||
def __init__(self, XMLFile):
|
||||
self.XMLFile = XMLFile
|
||||
def __str__(self):
|
||||
return "XMLFileError: %s" % self.XMLFile
|
||||
def getFile(self):
|
||||
return self.XMLFile
|
||||
|
||||
class Opt:
|
||||
"""An individual option.
|
||||
"""
|
||||
@@ -492,6 +503,14 @@ class Opts:
|
||||
p = os.path.join(os.path.curdir, p)
|
||||
if os.path.exists(p):
|
||||
self.info('Using config file "%s".' % p)
|
||||
|
||||
f = open(p)
|
||||
is_xml = (f.read(1) == '<')
|
||||
f.close()
|
||||
|
||||
if is_xml:
|
||||
raise XMLFileError(p)
|
||||
|
||||
self.load(p, help)
|
||||
break
|
||||
else:
|
||||
|
||||
@@ -75,15 +75,20 @@ class xenapi_create:
|
||||
|
||||
self.dtd = "/usr/lib/python/xen/xm/create.dtd"
|
||||
|
||||
def create(self, filename=None, document=None):
|
||||
def create(self, filename=None, document=None, skipdtd=False):
|
||||
"""
|
||||
Create a domain from an XML file or DOM tree
|
||||
"""
|
||||
if skipdtd:
|
||||
print "Skipping DTD checks. Dangerous!"
|
||||
|
||||
if filename is not None:
|
||||
self.check_dtd(file)
|
||||
document = parse(file)
|
||||
if not skipdtd:
|
||||
self.check_dtd(filename)
|
||||
document = parse(filename)
|
||||
elif document is not None:
|
||||
self.check_dom_against_dtd(document)
|
||||
if not skipdtd:
|
||||
self.check_dom_against_dtd(document)
|
||||
|
||||
self.check_doc(document)
|
||||
|
||||
|
||||
@@ -10,5 +10,5 @@ from XmTestLib import *
|
||||
status, output = traceCommand("xm destroy 0")
|
||||
if status == 0:
|
||||
FAIL("xm destroy returned bad status, expected non 0, status is: %i" % status)
|
||||
elif not re.search("Error", output):
|
||||
elif not re.search("Error", output, re.I):
|
||||
FAIL("xm destroy returned bad output, expected Error:, output is: %s" % output)
|
||||
+15
-9
@@ -62,6 +62,7 @@ int
|
||||
do_acm_set_policy(void *buf, u32 buf_size)
|
||||
{
|
||||
struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
|
||||
uint32_t offset, length;
|
||||
/* some sanity checking */
|
||||
if ((be32_to_cpu(pol->magic) != ACM_MAGIC) ||
|
||||
(buf_size != be32_to_cpu(pol->len)) ||
|
||||
@@ -92,22 +93,27 @@ do_acm_set_policy(void *buf, u32 buf_size)
|
||||
/* get bin_policy lock and rewrite policy (release old one) */
|
||||
write_lock(&acm_bin_pol_rwlock);
|
||||
|
||||
offset = be32_to_cpu(pol->policy_reference_offset);
|
||||
length = be32_to_cpu(pol->primary_buffer_offset) - offset;
|
||||
|
||||
/* set label reference name */
|
||||
if (acm_set_policy_reference(buf + be32_to_cpu(pol->policy_reference_offset),
|
||||
be32_to_cpu(pol->primary_buffer_offset) -
|
||||
be32_to_cpu(pol->policy_reference_offset)))
|
||||
if ( (offset + length) > buf_size ||
|
||||
acm_set_policy_reference(buf + offset, length))
|
||||
goto error_lock_free;
|
||||
|
||||
/* set primary policy data */
|
||||
if (acm_primary_ops->set_binary_policy(buf + be32_to_cpu(pol->primary_buffer_offset),
|
||||
be32_to_cpu(pol->secondary_buffer_offset) -
|
||||
be32_to_cpu(pol->primary_buffer_offset)))
|
||||
offset = be32_to_cpu(pol->primary_buffer_offset);
|
||||
length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
|
||||
|
||||
if ( (offset + length) > buf_size ||
|
||||
acm_primary_ops->set_binary_policy(buf + offset, length))
|
||||
goto error_lock_free;
|
||||
|
||||
/* set secondary policy data */
|
||||
if (acm_secondary_ops->set_binary_policy(buf + be32_to_cpu(pol->secondary_buffer_offset),
|
||||
be32_to_cpu(pol->len) -
|
||||
be32_to_cpu(pol->secondary_buffer_offset)))
|
||||
offset = be32_to_cpu(pol->secondary_buffer_offset);
|
||||
length = be32_to_cpu(pol->len) - offset;
|
||||
if ( (offset + length) > buf_size ||
|
||||
acm_secondary_ops->set_binary_policy(buf + offset, length))
|
||||
goto error_lock_free;
|
||||
|
||||
write_unlock(&acm_bin_pol_rwlock);
|
||||
|
||||
@@ -223,10 +223,11 @@ void foo(void)
|
||||
|
||||
#ifdef PERF_COUNTERS
|
||||
BLANK();
|
||||
DEFINE(RECOVER_TO_PAGE_FAULT_PERFC_OFS, offsetof (struct perfcounter, recover_to_page_fault));
|
||||
DEFINE(RECOVER_TO_BREAK_FAULT_PERFC_OFS, offsetof (struct perfcounter, recover_to_break_fault));
|
||||
DEFINE(FAST_HYPERPRIVOP_PERFC_OFS, offsetof (struct perfcounter, fast_hyperprivop));
|
||||
DEFINE(FAST_REFLECT_PERFC_OFS, offsetof (struct perfcounter, fast_reflect));
|
||||
DEFINE(IA64_PERFC_recover_to_page_fault, PERFC_recover_to_page_fault);
|
||||
DEFINE(IA64_PERFC_recover_to_break_fault, PERFC_recover_to_break_fault);
|
||||
DEFINE(IA64_PERFC_fast_vhpt_translate, PERFC_fast_vhpt_translate);
|
||||
DEFINE(IA64_PERFC_fast_hyperprivop, PERFC_fast_hyperprivop);
|
||||
DEFINE(IA64_PERFC_fast_reflect, PERFC_fast_reflect);
|
||||
#endif
|
||||
|
||||
BLANK();
|
||||
|
||||
@@ -113,7 +113,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
|
||||
unsigned long saved_tpr;
|
||||
|
||||
#ifdef XEN
|
||||
perfc_incrc(irqs);
|
||||
perfc_incr(irqs);
|
||||
#endif
|
||||
#if IRQ_DEBUG
|
||||
#ifdef XEN
|
||||
|
||||
@@ -396,16 +396,6 @@ ia64_log_queue(int sal_info_type, int virq)
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
#ifdef XEN
|
||||
/**
|
||||
* Copy from linux/include/asm-generic/bug.h
|
||||
*/
|
||||
#define WARN_ON(condition) do { \
|
||||
if (unlikely((condition)!=0)) { \
|
||||
printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
|
||||
dump_stack(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Copy from linux/kernel/irq/manage.c
|
||||
*
|
||||
|
||||
@@ -148,7 +148,7 @@ handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
|
||||
unsigned long ops;
|
||||
|
||||
#ifdef XEN
|
||||
perfc_incrc(ipis);
|
||||
perfc_incr(ipis);
|
||||
#endif
|
||||
mb(); /* Order interrupt and bit testing. */
|
||||
while ((ops = xchg(pending_ipis, 0)) != 0) {
|
||||
|
||||
@@ -37,7 +37,7 @@ pal_emul(struct vcpu *vcpu)
|
||||
vcpu_get_gr_nat(vcpu, 30, &gr30);
|
||||
vcpu_get_gr_nat(vcpu, 31, &gr31);
|
||||
|
||||
perfc_incrc(vmx_pal_emul);
|
||||
perfc_incr(vmx_pal_emul);
|
||||
result = xen_pal_emulator(gr28, gr29, gr30, gr31);
|
||||
|
||||
vcpu_set_gr(vcpu, 8, result.status, 0);
|
||||
|
||||
@@ -151,7 +151,7 @@ vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long is
|
||||
struct domain *d = current->domain;
|
||||
struct vcpu *v = current;
|
||||
|
||||
perfc_incrc(vmx_ia64_handle_break);
|
||||
perfc_incr(vmx_ia64_handle_break);
|
||||
#ifdef CRASH_DEBUG
|
||||
if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
|
||||
IS_VMM_ADDRESS(regs->cr_iip)) {
|
||||
|
||||
@@ -1401,159 +1401,159 @@ if ( (cause == 0xff && opcode == 0x1e000000000) || cause == 0 ) {
|
||||
|
||||
switch(cause) {
|
||||
case EVENT_RSM:
|
||||
perfc_incrc(vmx_rsm);
|
||||
perfc_incr(vmx_rsm);
|
||||
status=vmx_emul_rsm(vcpu, inst);
|
||||
break;
|
||||
case EVENT_SSM:
|
||||
perfc_incrc(vmx_ssm);
|
||||
perfc_incr(vmx_ssm);
|
||||
status=vmx_emul_ssm(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_PSR:
|
||||
perfc_incrc(vmx_mov_to_psr);
|
||||
perfc_incr(vmx_mov_to_psr);
|
||||
status=vmx_emul_mov_to_psr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_PSR:
|
||||
perfc_incrc(vmx_mov_from_psr);
|
||||
perfc_incr(vmx_mov_from_psr);
|
||||
status=vmx_emul_mov_from_psr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_CR:
|
||||
perfc_incrc(vmx_mov_from_cr);
|
||||
perfc_incr(vmx_mov_from_cr);
|
||||
status=vmx_emul_mov_from_cr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_CR:
|
||||
perfc_incrc(vmx_mov_to_cr);
|
||||
perfc_incr(vmx_mov_to_cr);
|
||||
status=vmx_emul_mov_to_cr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_BSW_0:
|
||||
perfc_incrc(vmx_bsw0);
|
||||
perfc_incr(vmx_bsw0);
|
||||
status=vmx_emul_bsw0(vcpu, inst);
|
||||
break;
|
||||
case EVENT_BSW_1:
|
||||
perfc_incrc(vmx_bsw1);
|
||||
perfc_incr(vmx_bsw1);
|
||||
status=vmx_emul_bsw1(vcpu, inst);
|
||||
break;
|
||||
case EVENT_COVER:
|
||||
perfc_incrc(vmx_cover);
|
||||
perfc_incr(vmx_cover);
|
||||
status=vmx_emul_cover(vcpu, inst);
|
||||
break;
|
||||
case EVENT_RFI:
|
||||
perfc_incrc(vmx_rfi);
|
||||
perfc_incr(vmx_rfi);
|
||||
status=vmx_emul_rfi(vcpu, inst);
|
||||
break;
|
||||
case EVENT_ITR_D:
|
||||
perfc_incrc(vmx_itr_d);
|
||||
perfc_incr(vmx_itr_d);
|
||||
status=vmx_emul_itr_d(vcpu, inst);
|
||||
break;
|
||||
case EVENT_ITR_I:
|
||||
perfc_incrc(vmx_itr_i);
|
||||
perfc_incr(vmx_itr_i);
|
||||
status=vmx_emul_itr_i(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTR_D:
|
||||
perfc_incrc(vmx_ptr_d);
|
||||
perfc_incr(vmx_ptr_d);
|
||||
status=vmx_emul_ptr_d(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTR_I:
|
||||
perfc_incrc(vmx_ptr_i);
|
||||
perfc_incr(vmx_ptr_i);
|
||||
status=vmx_emul_ptr_i(vcpu, inst);
|
||||
break;
|
||||
case EVENT_ITC_D:
|
||||
perfc_incrc(vmx_itc_d);
|
||||
perfc_incr(vmx_itc_d);
|
||||
status=vmx_emul_itc_d(vcpu, inst);
|
||||
break;
|
||||
case EVENT_ITC_I:
|
||||
perfc_incrc(vmx_itc_i);
|
||||
perfc_incr(vmx_itc_i);
|
||||
status=vmx_emul_itc_i(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTC_L:
|
||||
perfc_incrc(vmx_ptc_l);
|
||||
perfc_incr(vmx_ptc_l);
|
||||
status=vmx_emul_ptc_l(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTC_G:
|
||||
perfc_incrc(vmx_ptc_g);
|
||||
perfc_incr(vmx_ptc_g);
|
||||
status=vmx_emul_ptc_g(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTC_GA:
|
||||
perfc_incrc(vmx_ptc_ga);
|
||||
perfc_incr(vmx_ptc_ga);
|
||||
status=vmx_emul_ptc_ga(vcpu, inst);
|
||||
break;
|
||||
case EVENT_PTC_E:
|
||||
perfc_incrc(vmx_ptc_e);
|
||||
perfc_incr(vmx_ptc_e);
|
||||
status=vmx_emul_ptc_e(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_RR:
|
||||
perfc_incrc(vmx_mov_to_rr);
|
||||
perfc_incr(vmx_mov_to_rr);
|
||||
status=vmx_emul_mov_to_rr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_RR:
|
||||
perfc_incrc(vmx_mov_from_rr);
|
||||
perfc_incr(vmx_mov_from_rr);
|
||||
status=vmx_emul_mov_from_rr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_THASH:
|
||||
perfc_incrc(vmx_thash);
|
||||
perfc_incr(vmx_thash);
|
||||
status=vmx_emul_thash(vcpu, inst);
|
||||
break;
|
||||
case EVENT_TTAG:
|
||||
perfc_incrc(vmx_ttag);
|
||||
perfc_incr(vmx_ttag);
|
||||
status=vmx_emul_ttag(vcpu, inst);
|
||||
break;
|
||||
case EVENT_TPA:
|
||||
perfc_incrc(vmx_tpa);
|
||||
perfc_incr(vmx_tpa);
|
||||
status=vmx_emul_tpa(vcpu, inst);
|
||||
break;
|
||||
case EVENT_TAK:
|
||||
perfc_incrc(vmx_tak);
|
||||
perfc_incr(vmx_tak);
|
||||
status=vmx_emul_tak(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_AR_IMM:
|
||||
perfc_incrc(vmx_mov_to_ar_imm);
|
||||
perfc_incr(vmx_mov_to_ar_imm);
|
||||
status=vmx_emul_mov_to_ar_imm(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_AR:
|
||||
perfc_incrc(vmx_mov_to_ar_reg);
|
||||
perfc_incr(vmx_mov_to_ar_reg);
|
||||
status=vmx_emul_mov_to_ar_reg(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_AR:
|
||||
perfc_incrc(vmx_mov_from_ar_reg);
|
||||
perfc_incr(vmx_mov_from_ar_reg);
|
||||
status=vmx_emul_mov_from_ar_reg(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_DBR:
|
||||
perfc_incrc(vmx_mov_to_dbr);
|
||||
perfc_incr(vmx_mov_to_dbr);
|
||||
status=vmx_emul_mov_to_dbr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_IBR:
|
||||
perfc_incrc(vmx_mov_to_ibr);
|
||||
perfc_incr(vmx_mov_to_ibr);
|
||||
status=vmx_emul_mov_to_ibr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_PMC:
|
||||
perfc_incrc(vmx_mov_to_pmc);
|
||||
perfc_incr(vmx_mov_to_pmc);
|
||||
status=vmx_emul_mov_to_pmc(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_PMD:
|
||||
perfc_incrc(vmx_mov_to_pmd);
|
||||
perfc_incr(vmx_mov_to_pmd);
|
||||
status=vmx_emul_mov_to_pmd(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_TO_PKR:
|
||||
perfc_incrc(vmx_mov_to_pkr);
|
||||
perfc_incr(vmx_mov_to_pkr);
|
||||
status=vmx_emul_mov_to_pkr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_DBR:
|
||||
perfc_incrc(vmx_mov_from_dbr);
|
||||
perfc_incr(vmx_mov_from_dbr);
|
||||
status=vmx_emul_mov_from_dbr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_IBR:
|
||||
perfc_incrc(vmx_mov_from_ibr);
|
||||
perfc_incr(vmx_mov_from_ibr);
|
||||
status=vmx_emul_mov_from_ibr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_PMC:
|
||||
perfc_incrc(vmx_mov_from_pmc);
|
||||
perfc_incr(vmx_mov_from_pmc);
|
||||
status=vmx_emul_mov_from_pmc(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_PKR:
|
||||
perfc_incrc(vmx_mov_from_pkr);
|
||||
perfc_incr(vmx_mov_from_pkr);
|
||||
status=vmx_emul_mov_from_pkr(vcpu, inst);
|
||||
break;
|
||||
case EVENT_MOV_FROM_CPUID:
|
||||
perfc_incrc(vmx_mov_from_cpuid);
|
||||
perfc_incr(vmx_mov_from_cpuid);
|
||||
status=vmx_emul_mov_from_cpuid(vcpu, inst);
|
||||
break;
|
||||
case EVENT_VMSW:
|
||||
|
||||
@@ -372,7 +372,7 @@ do_dom0vp_op(unsigned long cmd,
|
||||
} else {
|
||||
ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
|
||||
}
|
||||
perfc_incrc(dom0vp_phystomach);
|
||||
perfc_incr(dom0vp_phystomach);
|
||||
break;
|
||||
case IA64_DOM0VP_machtophys:
|
||||
if (!mfn_valid(arg0)) {
|
||||
@@ -380,7 +380,7 @@ do_dom0vp_op(unsigned long cmd,
|
||||
break;
|
||||
}
|
||||
ret = get_gpfn_from_mfn(arg0);
|
||||
perfc_incrc(dom0vp_machtophys);
|
||||
perfc_incr(dom0vp_machtophys);
|
||||
break;
|
||||
case IA64_DOM0VP_zap_physmap:
|
||||
ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
|
||||
|
||||
@@ -131,11 +131,11 @@ static void flush_vtlb_for_context_switch(struct vcpu* prev, struct vcpu* next)
|
||||
if (vhpt_is_flushed || NEED_FLUSH(__get_cpu_var(tlbflush_time),
|
||||
last_tlbflush_timestamp)) {
|
||||
local_flush_tlb_all();
|
||||
perfc_incrc(tlbflush_clock_cswitch_purge);
|
||||
perfc_incr(tlbflush_clock_cswitch_purge);
|
||||
} else {
|
||||
perfc_incrc(tlbflush_clock_cswitch_skip);
|
||||
perfc_incr(tlbflush_clock_cswitch_skip);
|
||||
}
|
||||
perfc_incrc(flush_vtlb_for_context_switch);
|
||||
perfc_incr(flush_vtlb_for_context_switch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ static int handle_lazy_cover(struct vcpu *v, struct pt_regs *regs)
|
||||
if (!PSCB(v, interrupt_collection_enabled)) {
|
||||
PSCB(v, ifs) = regs->cr_ifs;
|
||||
regs->cr_ifs = 0;
|
||||
perfc_incrc(lazy_cover);
|
||||
perfc_incr(lazy_cover);
|
||||
return 1; // retry same instruction with cr.ifs off
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -161,7 +161,7 @@ ia64_hypercall(struct pt_regs *regs)
|
||||
if (regs->r28 == PAL_HALT_LIGHT) {
|
||||
if (vcpu_deliverable_interrupts(v) ||
|
||||
event_pending(v)) {
|
||||
perfc_incrc(idle_when_pending);
|
||||
perfc_incr(idle_when_pending);
|
||||
vcpu_pend_unspecified_interrupt(v);
|
||||
//printk("idle w/int#%d pending!\n",pi);
|
||||
//this shouldn't happen, but it apparently does quite a bit! so don't
|
||||
@@ -170,7 +170,7 @@ ia64_hypercall(struct pt_regs *regs)
|
||||
//as deliver_pending_interrupt is called on the way out and will deliver it
|
||||
}
|
||||
else {
|
||||
perfc_incrc(pal_halt_light);
|
||||
perfc_incr(pal_halt_light);
|
||||
migrate_timer(&v->arch.hlt_timer,
|
||||
v->processor);
|
||||
set_timer(&v->arch.hlt_timer,
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
# define FAST_HYPERPRIVOPS
|
||||
# ifdef PERF_COUNTERS
|
||||
# define FAST_HYPERPRIVOP_CNT
|
||||
# define FAST_HYPERPRIVOP_PERFC(N) \
|
||||
(perfcounters + FAST_HYPERPRIVOP_PERFC_OFS + (4 * N))
|
||||
# define FAST_HYPERPRIVOP_PERFC(N) PERFC(fast_hyperprivop + N)
|
||||
# define FAST_REFLECT_CNT
|
||||
# endif
|
||||
|
||||
@@ -364,7 +363,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
|
||||
mov rp=r29;;
|
||||
mov cr.itm=r26;; // ensure next tick
|
||||
#ifdef FAST_REFLECT_CNT
|
||||
movl r20=perfcounters+FAST_REFLECT_PERFC_OFS+((0x3000>>8)*4);;
|
||||
movl r20=PERFC(fast_reflect + (0x3000>>8));;
|
||||
ld4 r21=[r20];;
|
||||
adds r21=1,r21;;
|
||||
st4 [r20]=r21;;
|
||||
@@ -597,7 +596,7 @@ END(fast_break_reflect)
|
||||
// r31 == pr
|
||||
ENTRY(fast_reflect)
|
||||
#ifdef FAST_REFLECT_CNT
|
||||
movl r22=perfcounters+FAST_REFLECT_PERFC_OFS;
|
||||
movl r22=PERFC(fast_reflect);
|
||||
shr r23=r20,8-2;;
|
||||
add r22=r22,r23;;
|
||||
ld4 r21=[r22];;
|
||||
@@ -938,7 +937,7 @@ fast_tlb_no_tr_match:
|
||||
(p7) br.cond.spnt.few page_not_present;;
|
||||
|
||||
#ifdef FAST_REFLECT_CNT
|
||||
movl r21=perfcounter+FAST_VHPT_TRANSLATE_PERFC_OFS;;
|
||||
movl r21=PERFC(fast_vhpt_translate);;
|
||||
ld4 r22=[r21];;
|
||||
adds r22=1,r22;;
|
||||
st4 [r21]=r22;;
|
||||
@@ -968,7 +967,7 @@ END(fast_tlb_miss_reflect)
|
||||
// we get here if fast_insert fails (e.g. due to metaphysical lookup)
|
||||
ENTRY(recover_and_page_fault)
|
||||
#ifdef PERF_COUNTERS
|
||||
movl r21=perfcounters + RECOVER_TO_PAGE_FAULT_PERFC_OFS;;
|
||||
movl r21=PERFC(recover_to_page_fault);;
|
||||
ld4 r22=[r21];;
|
||||
adds r22=1,r22;;
|
||||
st4 [r21]=r22;;
|
||||
@@ -1832,7 +1831,7 @@ END(hyper_ptc_ga)
|
||||
// recovery block for hyper_itc metaphysical memory lookup
|
||||
ENTRY(recover_and_dispatch_break_fault)
|
||||
#ifdef PERF_COUNTERS
|
||||
movl r21=perfcounters + RECOVER_TO_BREAK_FAULT_PERFC_OFS;;
|
||||
movl r21=PERFC(recover_to_break_fault);;
|
||||
ld4 r22=[r21];;
|
||||
adds r22=1,r22;;
|
||||
st4 [r21]=r22;;
|
||||
|
||||
+13
-13
@@ -1131,7 +1131,7 @@ assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
|
||||
domain_put_page(d, mpaddr, pte, old_pte, 1);
|
||||
}
|
||||
}
|
||||
perfc_incrc(assign_domain_page_replace);
|
||||
perfc_incr(assign_domain_page_replace);
|
||||
}
|
||||
|
||||
// caller must get_page(new_page) before
|
||||
@@ -1207,7 +1207,7 @@ assign_domain_page_cmpxchg_rel(struct domain* d, unsigned long mpaddr,
|
||||
}
|
||||
|
||||
domain_page_flush_and_put(d, mpaddr, pte, old_pte, old_page);
|
||||
perfc_incrc(assign_domain_pge_cmpxchg_rel);
|
||||
perfc_incr(assign_domain_pge_cmpxchg_rel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1266,7 +1266,7 @@ zap_domain_page_one(struct domain *d, unsigned long mpaddr,
|
||||
|
||||
BUG_ON(clear_PGC_allocate && (page_get_owner(page) == NULL));
|
||||
domain_put_page(d, mpaddr, pte, old_pte, clear_PGC_allocate);
|
||||
perfc_incrc(zap_dcomain_page_one);
|
||||
perfc_incr(zap_dcomain_page_one);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
@@ -1279,7 +1279,7 @@ dom0vp_zap_physmap(struct domain *d, unsigned long gpfn,
|
||||
}
|
||||
|
||||
zap_domain_page_one(d, gpfn << PAGE_SHIFT, 1, INVALID_MFN);
|
||||
perfc_incrc(dom0vp_zap_physmap);
|
||||
perfc_incr(dom0vp_zap_physmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1333,7 +1333,7 @@ __dom0vp_add_physmap(struct domain* d, unsigned long gpfn,
|
||||
get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
|
||||
assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
|
||||
//don't update p2m table because this page belongs to rd, not d.
|
||||
perfc_incrc(dom0vp_add_physmap);
|
||||
perfc_incr(dom0vp_add_physmap);
|
||||
out1:
|
||||
put_domain(rd);
|
||||
return error;
|
||||
@@ -1503,7 +1503,7 @@ create_grant_host_mapping(unsigned long gpaddr,
|
||||
#endif
|
||||
((flags & GNTMAP_readonly) ?
|
||||
ASSIGN_readonly : ASSIGN_writable));
|
||||
perfc_incrc(create_grant_host_mapping);
|
||||
perfc_incr(create_grant_host_mapping);
|
||||
return GNTST_okay;
|
||||
}
|
||||
|
||||
@@ -1568,7 +1568,7 @@ destroy_grant_host_mapping(unsigned long gpaddr,
|
||||
BUG_ON(pte_pgc_allocated(old_pte));
|
||||
domain_page_flush_and_put(d, gpaddr, pte, old_pte, page);
|
||||
|
||||
perfc_incrc(destroy_grant_host_mapping);
|
||||
perfc_incr(destroy_grant_host_mapping);
|
||||
return GNTST_okay;
|
||||
}
|
||||
|
||||
@@ -1629,7 +1629,7 @@ steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
|
||||
free_domheap_page(new);
|
||||
return -1;
|
||||
}
|
||||
perfc_incrc(steal_page_refcount);
|
||||
perfc_incr(steal_page_refcount);
|
||||
}
|
||||
|
||||
spin_lock(&d->page_alloc_lock);
|
||||
@@ -1693,7 +1693,7 @@ steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
|
||||
list_del(&page->list);
|
||||
|
||||
spin_unlock(&d->page_alloc_lock);
|
||||
perfc_incrc(steal_page);
|
||||
perfc_incr(steal_page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1710,7 +1710,7 @@ guest_physmap_add_page(struct domain *d, unsigned long gpfn,
|
||||
|
||||
//BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
|
||||
|
||||
perfc_incrc(guest_physmap_add_page);
|
||||
perfc_incr(guest_physmap_add_page);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1719,7 +1719,7 @@ guest_physmap_remove_page(struct domain *d, unsigned long gpfn,
|
||||
{
|
||||
BUG_ON(mfn == 0);//XXX
|
||||
zap_domain_page_one(d, gpfn << PAGE_SHIFT, 0, mfn);
|
||||
perfc_incrc(guest_physmap_remove_page);
|
||||
perfc_incr(guest_physmap_remove_page);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1799,7 +1799,7 @@ domain_page_flush_and_put(struct domain* d, unsigned long mpaddr,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
perfc_incrc(domain_page_flush_and_put);
|
||||
perfc_incr(domain_page_flush_and_put);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1996,7 +1996,7 @@ int get_page_type(struct page_info *page, u32 type)
|
||||
|
||||
if ( unlikely(!cpus_empty(mask)) )
|
||||
{
|
||||
perfc_incrc(need_flush_tlb_flush);
|
||||
perfc_incr(need_flush_tlb_flush);
|
||||
flush_tlb_mask(mask);
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -641,15 +641,15 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
if (inst.M29.x3 != 0)
|
||||
break;
|
||||
if (inst.M30.x4 == 8 && inst.M30.x2 == 2) {
|
||||
perfc_incrc(mov_to_ar_imm);
|
||||
perfc_incr(mov_to_ar_imm);
|
||||
return priv_mov_to_ar_imm(vcpu, inst);
|
||||
}
|
||||
if (inst.M44.x4 == 6) {
|
||||
perfc_incrc(ssm);
|
||||
perfc_incr(ssm);
|
||||
return priv_ssm(vcpu, inst);
|
||||
}
|
||||
if (inst.M44.x4 == 7) {
|
||||
perfc_incrc(rsm);
|
||||
perfc_incr(rsm);
|
||||
return priv_rsm(vcpu, inst);
|
||||
}
|
||||
break;
|
||||
@@ -658,9 +658,9 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
x6 = inst.M29.x6;
|
||||
if (x6 == 0x2a) {
|
||||
if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
|
||||
perfc_incrc(mov_from_ar); // privified mov from kr
|
||||
perfc_incr(mov_from_ar); // privified mov from kr
|
||||
else
|
||||
perfc_incrc(mov_to_ar_reg);
|
||||
perfc_incr(mov_to_ar_reg);
|
||||
return priv_mov_to_ar_reg(vcpu, inst);
|
||||
}
|
||||
if (inst.M29.x3 != 0)
|
||||
@@ -676,9 +676,9 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
}
|
||||
}
|
||||
if (privify_en && x6 == 52 && inst.M28.r3 > 63)
|
||||
perfc_incrc(fc);
|
||||
perfc_incr(fc);
|
||||
else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
|
||||
perfc_incrc(cpuid);
|
||||
perfc_incr(cpuid);
|
||||
else
|
||||
perfc_incra(misc_privop, x6);
|
||||
return (*pfunc) (vcpu, inst);
|
||||
@@ -688,23 +688,23 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
break;
|
||||
if (inst.B8.x6 == 0x08) {
|
||||
IA64FAULT fault;
|
||||
perfc_incrc(rfi);
|
||||
perfc_incr(rfi);
|
||||
fault = priv_rfi(vcpu, inst);
|
||||
if (fault == IA64_NO_FAULT)
|
||||
fault = IA64_RFI_IN_PROGRESS;
|
||||
return fault;
|
||||
}
|
||||
if (inst.B8.x6 == 0x0c) {
|
||||
perfc_incrc(bsw0);
|
||||
perfc_incr(bsw0);
|
||||
return priv_bsw0(vcpu, inst);
|
||||
}
|
||||
if (inst.B8.x6 == 0x0d) {
|
||||
perfc_incrc(bsw1);
|
||||
perfc_incr(bsw1);
|
||||
return priv_bsw1(vcpu, inst);
|
||||
}
|
||||
if (inst.B8.x6 == 0x0) {
|
||||
// break instr for privified cover
|
||||
perfc_incrc(cover);
|
||||
perfc_incr(cover);
|
||||
return priv_cover(vcpu, inst);
|
||||
}
|
||||
break;
|
||||
@@ -713,7 +713,7 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
break;
|
||||
#if 0
|
||||
if (inst.I26.x6 == 0 && inst.I26.x3 == 0) {
|
||||
perfc_incrc(cover);
|
||||
perfc_incr(cover);
|
||||
return priv_cover(vcpu, inst);
|
||||
}
|
||||
#endif
|
||||
@@ -721,13 +721,13 @@ static IA64FAULT priv_handle_op(VCPU * vcpu, REGS * regs, int privlvl)
|
||||
break; // I26.x3 == I27.x3
|
||||
if (inst.I26.x6 == 0x2a) {
|
||||
if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
|
||||
perfc_incrc(mov_from_ar); // privified mov from kr
|
||||
perfc_incr(mov_from_ar); // privified mov from kr
|
||||
else
|
||||
perfc_incrc(mov_to_ar_reg);
|
||||
perfc_incr(mov_to_ar_reg);
|
||||
return priv_mov_to_ar_reg(vcpu, inst);
|
||||
}
|
||||
if (inst.I27.x6 == 0x0a) {
|
||||
perfc_incrc(mov_to_ar_imm);
|
||||
perfc_incr(mov_to_ar_imm);
|
||||
return priv_mov_to_ar_imm(vcpu, inst);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -10,48 +10,39 @@ struct privop_addr_count {
|
||||
unsigned long addr[PRIVOP_COUNT_NADDRS];
|
||||
unsigned int count[PRIVOP_COUNT_NADDRS];
|
||||
unsigned int overflow;
|
||||
atomic_t *perfc_addr;
|
||||
atomic_t *perfc_count;
|
||||
atomic_t *perfc_overflow;
|
||||
};
|
||||
|
||||
#undef PERFCOUNTER
|
||||
struct privop_addr_info {
|
||||
enum perfcounter perfc_addr;
|
||||
enum perfcounter perfc_count;
|
||||
enum perfcounter perfc_overflow;
|
||||
};
|
||||
|
||||
#define PERFCOUNTER(var, name)
|
||||
|
||||
#undef PERFCOUNTER_CPU
|
||||
#define PERFCOUNTER_CPU(var, name)
|
||||
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
#define PERFCOUNTER_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFSTATUS
|
||||
#define PERFSTATUS(var, name)
|
||||
|
||||
#undef PERFSTATUS_CPU
|
||||
#define PERFSTATUS_CPU(var, name)
|
||||
|
||||
#undef PERFSTATUS_ARRAY
|
||||
#define PERFSTATUS_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
#define PERFPRIVOPADDR(name) \
|
||||
{ \
|
||||
{ 0 }, { 0 }, 0, \
|
||||
perfcounters.privop_addr_##name##_addr, \
|
||||
perfcounters.privop_addr_##name##_count, \
|
||||
perfcounters.privop_addr_##name##_overflow \
|
||||
PERFC_privop_addr_##name##_addr, \
|
||||
PERFC_privop_addr_##name##_count, \
|
||||
PERFC_privop_addr_##name##_overflow \
|
||||
},
|
||||
|
||||
static struct privop_addr_count privop_addr_counter[] = {
|
||||
static const struct privop_addr_info privop_addr_info[] = {
|
||||
#include <asm/perfc_defn.h>
|
||||
};
|
||||
|
||||
#define PRIVOP_COUNT_NINSTS \
|
||||
(sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
|
||||
(sizeof(privop_addr_info) / sizeof(privop_addr_info[0]))
|
||||
|
||||
static DEFINE_PER_CPU(struct privop_addr_count[PRIVOP_COUNT_NINSTS], privop_addr_counter);
|
||||
|
||||
void privop_count_addr(unsigned long iip, enum privop_inst inst)
|
||||
{
|
||||
struct privop_addr_count *v = &privop_addr_counter[inst];
|
||||
struct privop_addr_count *v = this_cpu(privop_addr_counter) + inst;
|
||||
int i;
|
||||
|
||||
if (inst >= PRIVOP_COUNT_NINSTS)
|
||||
@@ -72,31 +63,44 @@ void privop_count_addr(unsigned long iip, enum privop_inst inst)
|
||||
|
||||
void gather_privop_addrs(void)
|
||||
{
|
||||
int i, j;
|
||||
atomic_t *v;
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
|
||||
/* Note: addresses are truncated! */
|
||||
v = privop_addr_counter[i].perfc_addr;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
atomic_set(&v[j], privop_addr_counter[i].addr[j]);
|
||||
unsigned int cpu;
|
||||
|
||||
v = privop_addr_counter[i].perfc_count;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
atomic_set(&v[j], privop_addr_counter[i].count[j]);
|
||||
for_each_cpu ( cpu ) {
|
||||
perfc_t *perfcounters = per_cpu(perfcounters, cpu);
|
||||
struct privop_addr_count *s = per_cpu(privop_addr_counter, cpu);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, s++) {
|
||||
perfc_t *d;
|
||||
|
||||
/* Note: addresses are truncated! */
|
||||
d = perfcounters + privop_addr_info[i].perfc_addr;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
d[j] = s->addr[j];
|
||||
|
||||
d = perfcounters + privop_addr_info[i].perfc_count;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
d[j] = s->count[j];
|
||||
|
||||
atomic_set(privop_addr_counter[i].perfc_overflow,
|
||||
privop_addr_counter[i].overflow);
|
||||
perfcounters[privop_addr_info[i].perfc_overflow] =
|
||||
s->overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset_privop_addrs(void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
|
||||
struct privop_addr_count *v = &privop_addr_counter[i];
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
v->addr[j] = v->count[j] = 0;
|
||||
v->overflow = 0;
|
||||
unsigned int cpu;
|
||||
|
||||
for_each_cpu ( cpu ) {
|
||||
struct privop_addr_count *v = per_cpu(privop_addr_counter, cpu);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, v++) {
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
v->addr[j] = v->count[j] = 0;
|
||||
v->overflow = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -216,14 +216,14 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
TLB_TRACK_RET_T ret = TLB_TRACK_NOT_FOUND;
|
||||
|
||||
#if 0 /* this is done at vcpu_tlb_track_insert_or_dirty() */
|
||||
perfc_incrc(tlb_track_iod);
|
||||
perfc_incr(tlb_track_iod);
|
||||
if (!pte_tlb_tracking(old_pte)) {
|
||||
perfc_incrc(tlb_track_iod_not_tracked);
|
||||
perfc_incr(tlb_track_iod_not_tracked);
|
||||
return TLB_TRACK_NOT_TRACKED;
|
||||
}
|
||||
#endif
|
||||
if (pte_tlb_inserted_many(old_pte)) {
|
||||
perfc_incrc(tlb_track_iod_tracked_many);
|
||||
perfc_incr(tlb_track_iod_tracked_many);
|
||||
return TLB_TRACK_MANY;
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
if (entry->vaddr == vaddr && entry->rid == rid) {
|
||||
// tlb_track_printd("TLB_TRACK_FOUND\n");
|
||||
ret = TLB_TRACK_FOUND;
|
||||
perfc_incrc(tlb_track_iod_found);
|
||||
perfc_incr(tlb_track_iod_found);
|
||||
#ifdef CONFIG_TLB_TRACK_CNT
|
||||
entry->cnt++;
|
||||
if (entry->cnt > TLB_TRACK_CNT_FORCE_MANY) {
|
||||
@@ -276,7 +276,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
*/
|
||||
// tlb_track_entry_printf(entry);
|
||||
// tlb_track_printd("cnt = %ld\n", entry->cnt);
|
||||
perfc_incrc(tlb_track_iod_force_many);
|
||||
perfc_incr(tlb_track_iod_force_many);
|
||||
goto force_many;
|
||||
}
|
||||
#endif
|
||||
@@ -294,14 +294,14 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
if (pte_val(ret_pte) != pte_val(old_pte)) {
|
||||
// tlb_track_printd("TLB_TRACK_AGAIN\n");
|
||||
ret = TLB_TRACK_AGAIN;
|
||||
perfc_incrc(tlb_track_iod_again);
|
||||
perfc_incr(tlb_track_iod_again);
|
||||
} else {
|
||||
// tlb_track_printd("TLB_TRACK_MANY del entry 0x%p\n",
|
||||
// entry);
|
||||
ret = TLB_TRACK_MANY;
|
||||
list_del(&entry->list);
|
||||
// tlb_track_entry_printf(entry);
|
||||
perfc_incrc(tlb_track_iod_tracked_many_del);
|
||||
perfc_incr(tlb_track_iod_tracked_many_del);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
*/
|
||||
// tlb_track_printd("TLB_TRACK_AGAIN\n");
|
||||
ret = TLB_TRACK_AGAIN;
|
||||
perfc_incrc(tlb_track_iod_again);
|
||||
perfc_incr(tlb_track_iod_again);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
/* Other thread else removed the tlb_track_entry after we got old_pte
|
||||
before we got spin lock. */
|
||||
ret = TLB_TRACK_AGAIN;
|
||||
perfc_incrc(tlb_track_iod_again);
|
||||
perfc_incr(tlb_track_iod_again);
|
||||
goto out;
|
||||
}
|
||||
if (new_entry == NULL && bit_to_be_set == _PAGE_TLB_INSERTED) {
|
||||
@@ -334,10 +334,10 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
/* entry can't be allocated.
|
||||
fall down into full flush mode. */
|
||||
bit_to_be_set |= _PAGE_TLB_INSERTED_MANY;
|
||||
perfc_incrc(tlb_track_iod_new_failed);
|
||||
perfc_incr(tlb_track_iod_new_failed);
|
||||
}
|
||||
// tlb_track_printd("new_entry 0x%p\n", new_entry);
|
||||
perfc_incrc(tlb_track_iod_new_entry);
|
||||
perfc_incr(tlb_track_iod_new_entry);
|
||||
goto again;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
if (tlb_track_pte_zapped(old_pte, ret_pte)) {
|
||||
// tlb_track_printd("zapped TLB_TRACK_AGAIN\n");
|
||||
ret = TLB_TRACK_AGAIN;
|
||||
perfc_incrc(tlb_track_iod_again);
|
||||
perfc_incr(tlb_track_iod_again);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
// tlb_track_printd("iserted TLB_TRACK_MANY\n");
|
||||
BUG_ON(!pte_tlb_inserted(ret_pte));
|
||||
ret = TLB_TRACK_MANY;
|
||||
perfc_incrc(tlb_track_iod_new_many);
|
||||
perfc_incr(tlb_track_iod_new_many);
|
||||
goto out;
|
||||
}
|
||||
BUG_ON(pte_tlb_inserted(ret_pte));
|
||||
@@ -381,7 +381,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
#ifdef CONFIG_TLB_TRACK_CNT
|
||||
entry->cnt = 0;
|
||||
#endif
|
||||
perfc_incrc(tlb_track_iod_insert);
|
||||
perfc_incr(tlb_track_iod_insert);
|
||||
// tlb_track_entry_printf(entry);
|
||||
} else {
|
||||
goto out;
|
||||
@@ -392,7 +392,7 @@ tlb_track_insert_or_dirty(struct tlb_track* tlb_track, struct mm_struct* mm,
|
||||
cpu_set(v->processor, entry->pcpu_dirty_mask);
|
||||
BUG_ON(v->vcpu_id >= NR_CPUS);
|
||||
vcpu_set(v->vcpu_id, entry->vcpu_dirty_mask);
|
||||
perfc_incrc(tlb_track_iod_dirtied);
|
||||
perfc_incr(tlb_track_iod_dirtied);
|
||||
|
||||
out:
|
||||
spin_unlock(&tlb_track->hash_lock);
|
||||
@@ -432,19 +432,19 @@ tlb_track_search_and_remove(struct tlb_track* tlb_track,
|
||||
struct list_head* head = tlb_track_hash_head(tlb_track, ptep);
|
||||
struct tlb_track_entry* entry;
|
||||
|
||||
perfc_incrc(tlb_track_sar);
|
||||
perfc_incr(tlb_track_sar);
|
||||
if (!pte_tlb_tracking(old_pte)) {
|
||||
perfc_incrc(tlb_track_sar_not_tracked);
|
||||
perfc_incr(tlb_track_sar_not_tracked);
|
||||
return TLB_TRACK_NOT_TRACKED;
|
||||
}
|
||||
if (!pte_tlb_inserted(old_pte)) {
|
||||
BUG_ON(pte_tlb_inserted_many(old_pte));
|
||||
perfc_incrc(tlb_track_sar_not_found);
|
||||
perfc_incr(tlb_track_sar_not_found);
|
||||
return TLB_TRACK_NOT_FOUND;
|
||||
}
|
||||
if (pte_tlb_inserted_many(old_pte)) {
|
||||
BUG_ON(!pte_tlb_inserted(old_pte));
|
||||
perfc_incrc(tlb_track_sar_many);
|
||||
perfc_incr(tlb_track_sar_many);
|
||||
return TLB_TRACK_MANY;
|
||||
}
|
||||
|
||||
@@ -475,14 +475,14 @@ tlb_track_search_and_remove(struct tlb_track* tlb_track,
|
||||
pte_tlb_inserted(current_pte))) {
|
||||
BUG_ON(pte_tlb_inserted_many(current_pte));
|
||||
spin_unlock(&tlb_track->hash_lock);
|
||||
perfc_incrc(tlb_track_sar_many);
|
||||
perfc_incr(tlb_track_sar_many);
|
||||
return TLB_TRACK_MANY;
|
||||
}
|
||||
|
||||
list_del(&entry->list);
|
||||
spin_unlock(&tlb_track->hash_lock);
|
||||
*entryp = entry;
|
||||
perfc_incrc(tlb_track_sar_found);
|
||||
perfc_incr(tlb_track_sar_found);
|
||||
// tlb_track_entry_printf(entry);
|
||||
#ifdef CONFIG_TLB_TRACK_CNT
|
||||
// tlb_track_printd("cnt = %ld\n", entry->cnt);
|
||||
|
||||
@@ -1616,7 +1616,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u64 address, BOOLEAN is_data,
|
||||
*pteval = (address & _PAGE_PPN_MASK) |
|
||||
__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
|
||||
*itir = PAGE_SHIFT << 2;
|
||||
perfc_incrc(phys_translate);
|
||||
perfc_incr(phys_translate);
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
} else if (!region && warn_region0_address) {
|
||||
@@ -1637,7 +1637,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u64 address, BOOLEAN is_data,
|
||||
if (trp != NULL) {
|
||||
*pteval = trp->pte.val;
|
||||
*itir = trp->itir;
|
||||
perfc_incrc(tr_translate);
|
||||
perfc_incr(tr_translate);
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
}
|
||||
@@ -1647,7 +1647,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u64 address, BOOLEAN is_data,
|
||||
if (trp != NULL) {
|
||||
*pteval = trp->pte.val;
|
||||
*itir = trp->itir;
|
||||
perfc_incrc(tr_translate);
|
||||
perfc_incr(tr_translate);
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
}
|
||||
@@ -1660,7 +1660,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u64 address, BOOLEAN is_data,
|
||||
&& vcpu_match_tr_entry_no_p(trp, address, rid)) {
|
||||
*pteval = pte.val;
|
||||
*itir = trp->itir;
|
||||
perfc_incrc(dtlb_translate);
|
||||
perfc_incr(dtlb_translate);
|
||||
return IA64_USE_TLB;
|
||||
}
|
||||
|
||||
@@ -1709,7 +1709,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u64 address, BOOLEAN is_data,
|
||||
out:
|
||||
*itir = rr & RR_PS_MASK;
|
||||
*pteval = pte.val;
|
||||
perfc_incrc(vhpt_translate);
|
||||
perfc_incr(vhpt_translate);
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -48,14 +48,14 @@ local_vhpt_flush(void)
|
||||
/* this must be after flush */
|
||||
tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
|
||||
flush_time);
|
||||
perfc_incrc(local_vhpt_flush);
|
||||
perfc_incr(local_vhpt_flush);
|
||||
}
|
||||
|
||||
void
|
||||
vcpu_vhpt_flush(struct vcpu* v)
|
||||
{
|
||||
__vhpt_flush(vcpu_vhpt_maddr(v));
|
||||
perfc_incrc(vcpu_vhpt_flush);
|
||||
perfc_incr(vcpu_vhpt_flush);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,7 +248,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v)
|
||||
not running on this processor. There is currently no easy way to
|
||||
check this. */
|
||||
|
||||
perfc_incrc(vcpu_flush_vtlb_all);
|
||||
perfc_incr(vcpu_flush_vtlb_all);
|
||||
}
|
||||
|
||||
static void __vcpu_flush_vtlb_all(void *vcpu)
|
||||
@@ -280,7 +280,7 @@ void domain_flush_vtlb_all(struct domain* d)
|
||||
__vcpu_flush_vtlb_all,
|
||||
v, 1, 1);
|
||||
}
|
||||
perfc_incrc(domain_flush_vtlb_all);
|
||||
perfc_incr(domain_flush_vtlb_all);
|
||||
}
|
||||
|
||||
// Callers may need to call smp_mb() before/after calling this.
|
||||
@@ -322,7 +322,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr, u64 log_range)
|
||||
vadr, 1UL << log_range);
|
||||
ia64_ptcl(vadr, log_range << 2);
|
||||
ia64_srlz_i();
|
||||
perfc_incrc(vcpu_flush_tlb_vhpt_range);
|
||||
perfc_incr(vcpu_flush_tlb_vhpt_range);
|
||||
}
|
||||
|
||||
void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
|
||||
@@ -361,7 +361,7 @@ void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
|
||||
|
||||
/* ptc.ga */
|
||||
platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT);
|
||||
perfc_incrc(domain_flush_vtlb_range);
|
||||
perfc_incr(domain_flush_vtlb_range);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_IA64_TLB_TRACK
|
||||
@@ -391,11 +391,11 @@ __domain_flush_vtlb_track_entry(struct domain* d,
|
||||
*/
|
||||
vcpu_get_rr(current, VRN7 << VRN_SHIFT, &rr7_rid);
|
||||
if (likely(rr7_rid == entry->rid)) {
|
||||
perfc_incrc(tlb_track_use_rr7);
|
||||
perfc_incr(tlb_track_use_rr7);
|
||||
} else {
|
||||
swap_rr0 = 1;
|
||||
vaddr = (vaddr << 3) >> 3;// force vrn0
|
||||
perfc_incrc(tlb_track_swap_rr0);
|
||||
perfc_incr(tlb_track_swap_rr0);
|
||||
}
|
||||
|
||||
// tlb_track_entry_printf(entry);
|
||||
@@ -435,18 +435,18 @@ __domain_flush_vtlb_track_entry(struct domain* d,
|
||||
/* ptc.ga */
|
||||
if (local_purge) {
|
||||
ia64_ptcl(vaddr, PAGE_SHIFT << 2);
|
||||
perfc_incrc(domain_flush_vtlb_local);
|
||||
perfc_incr(domain_flush_vtlb_local);
|
||||
} else {
|
||||
/* ptc.ga has release semantics. */
|
||||
platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE,
|
||||
PAGE_SHIFT);
|
||||
perfc_incrc(domain_flush_vtlb_global);
|
||||
perfc_incr(domain_flush_vtlb_global);
|
||||
}
|
||||
|
||||
if (swap_rr0) {
|
||||
vcpu_set_rr(current, 0, old_rid);
|
||||
}
|
||||
perfc_incrc(domain_flush_vtlb_track_entry);
|
||||
perfc_incr(domain_flush_vtlb_track_entry);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -512,7 +512,7 @@ void gather_vhpt_stats(void)
|
||||
for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
|
||||
if (!(v->ti_tag & INVALID_TI_TAG))
|
||||
vhpt_valid++;
|
||||
perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
|
||||
per_cpu(perfcounters, cpu)[PERFC_vhpt_valid_entries] = vhpt_valid;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -205,21 +205,6 @@ void show_backtrace_regs(struct cpu_user_regs *regs)
|
||||
console_end_sync();
|
||||
}
|
||||
|
||||
void __warn(char *file, int line)
|
||||
{
|
||||
ulong sp;
|
||||
ulong lr;
|
||||
|
||||
console_start_sync();
|
||||
printk("WARN at %s:%d\n", file, line);
|
||||
|
||||
sp = (ulong)__builtin_frame_address(0);
|
||||
lr = (ulong)__builtin_return_address(0);
|
||||
backtrace(sp, lr, lr);
|
||||
|
||||
console_end_sync();
|
||||
}
|
||||
|
||||
void dump_execution_state(void)
|
||||
{
|
||||
struct cpu_user_regs *regs = guest_cpu_user_regs();
|
||||
|
||||
@@ -261,7 +261,7 @@ int get_page_type(struct page_info *page, unsigned long type)
|
||||
|
||||
if ( unlikely(!cpus_empty(mask)) )
|
||||
{
|
||||
perfc_incrc(need_flush_tlb_flush);
|
||||
perfc_incr(need_flush_tlb_flush);
|
||||
flush_tlb_mask(mask);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,4 @@ HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/svm/*.h)
|
||||
HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
|
||||
|
||||
# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
|
||||
ifneq ($(call cc-ver,$(CC),0x030400),y)
|
||||
$(error Xen requires at least gcc-3.4)
|
||||
endif
|
||||
$(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
|
||||
+1
-1
@@ -1076,7 +1076,7 @@ int reprogram_timer(s_time_t timeout)
|
||||
fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
|
||||
{
|
||||
ack_APIC_irq();
|
||||
perfc_incrc(apic_timer);
|
||||
perfc_incr(apic_timer);
|
||||
raise_softirq(TIMER_SOFTIRQ);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ search_pre_exception_table(struct cpu_user_regs *regs)
|
||||
if ( fixup )
|
||||
{
|
||||
dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
|
||||
perfc_incrc(exception_fixed);
|
||||
perfc_incr(exception_fixed);
|
||||
}
|
||||
return fixup;
|
||||
}
|
||||
+24
-4
@@ -292,7 +292,11 @@ extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs *re
|
||||
static inline void set_eflags_CF(int size, unsigned long v1,
|
||||
unsigned long v2, struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned long mask = (1 << (8 * size)) - 1;
|
||||
unsigned long mask;
|
||||
|
||||
ASSERT((size <= sizeof(mask)) && (size > 0));
|
||||
|
||||
mask = ~0UL >> (8 * (sizeof(mask) - size));
|
||||
|
||||
if ((v1 & mask) > (v2 & mask))
|
||||
regs->eflags |= X86_EFLAGS_CF;
|
||||
@@ -303,7 +307,13 @@ static inline void set_eflags_CF(int size, unsigned long v1,
|
||||
static inline void set_eflags_OF(int size, unsigned long v1,
|
||||
unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
|
||||
{
|
||||
if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
|
||||
unsigned long mask;
|
||||
|
||||
ASSERT((size <= sizeof(mask)) && (size > 0));
|
||||
|
||||
mask = ~0UL >> (8 * (sizeof(mask) - size));
|
||||
|
||||
if ((v3 ^ v2) & (v3 ^ v1) & mask)
|
||||
regs->eflags |= X86_EFLAGS_OF;
|
||||
}
|
||||
|
||||
@@ -317,7 +327,11 @@ static inline void set_eflags_AF(int size, unsigned long v1,
|
||||
static inline void set_eflags_ZF(int size, unsigned long v1,
|
||||
struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned long mask = (1 << (8 * size)) - 1;
|
||||
unsigned long mask;
|
||||
|
||||
ASSERT((size <= sizeof(mask)) && (size > 0));
|
||||
|
||||
mask = ~0UL >> (8 * (sizeof(mask) - size));
|
||||
|
||||
if ((v1 & mask) == 0)
|
||||
regs->eflags |= X86_EFLAGS_ZF;
|
||||
@@ -326,7 +340,13 @@ static inline void set_eflags_ZF(int size, unsigned long v1,
|
||||
static inline void set_eflags_SF(int size, unsigned long v1,
|
||||
struct cpu_user_regs *regs)
|
||||
{
|
||||
if (v1 & (1 << ((8 * size) - 1)))
|
||||
unsigned long mask;
|
||||
|
||||
ASSERT((size <= sizeof(mask)) && (size > 0));
|
||||
|
||||
mask = ~0UL >> (8 * (sizeof(mask) - size));
|
||||
|
||||
if (v1 & mask)
|
||||
regs->eflags |= X86_EFLAGS_SF;
|
||||
}
|
||||
|
||||
|
||||
+61
-73
@@ -64,88 +64,76 @@ asmlinkage void svm_intr_assist(void)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
struct periodic_time *pt;
|
||||
int intr_type = APIC_DM_EXTINT;
|
||||
int intr_vector = -1;
|
||||
int re_injecting = 0;
|
||||
|
||||
/* Check if an Injection is active */
|
||||
/* Previous Interrupt delivery caused this Intercept? */
|
||||
if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
|
||||
{
|
||||
v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
|
||||
vmcb->exitintinfo.bytes = 0;
|
||||
re_injecting = 1;
|
||||
}
|
||||
|
||||
/* Previous interrupt still pending? */
|
||||
if ( vmcb->vintr.fields.irq )
|
||||
{
|
||||
intr_vector = vmcb->vintr.fields.vector;
|
||||
vmcb->vintr.bytes = 0;
|
||||
re_injecting = 1;
|
||||
}
|
||||
/* Pending IRQ saved at last VMExit? */
|
||||
else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
|
||||
{
|
||||
intr_vector = v->arch.hvm_svm.saved_irq_vector;
|
||||
v->arch.hvm_svm.saved_irq_vector = -1;
|
||||
re_injecting = 1;
|
||||
}
|
||||
/* Now let's check for newer interrrupts */
|
||||
else
|
||||
{
|
||||
pt_update_irq(v);
|
||||
|
||||
hvm_set_callback_irq_level();
|
||||
|
||||
if ( cpu_has_pending_irq(v) )
|
||||
{
|
||||
/*
|
||||
* Create a 'fake' virtual interrupt on to intercept as soon
|
||||
* as the guest _can_ take interrupts. Do not obtain the next
|
||||
* interrupt from the vlapic/pic if unable to inject.
|
||||
*/
|
||||
if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )
|
||||
{
|
||||
vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
|
||||
HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
|
||||
svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
|
||||
return;
|
||||
}
|
||||
intr_vector = cpu_get_interrupt(v, &intr_type);
|
||||
}
|
||||
}
|
||||
|
||||
/* have we got an interrupt to inject? */
|
||||
if ( intr_vector < 0 )
|
||||
/*
|
||||
* Do not deliver a virtual interrupt (vintr) if an exception is pending.
|
||||
* This is because the delivery of the exception can arbitrarily delay
|
||||
* the injection of the vintr (for example, if the exception is handled
|
||||
* via an interrupt gate, hence zeroing RFLAGS.IF). In the meantime the
|
||||
* vTPR can be modified upwards and we can end up delivering the vintr
|
||||
* when it is not in fact valid to do so (because we do not re-check the
|
||||
* vTPR value). Moreover, the guest will be able to see the updated
|
||||
* APIC/PIC state (as if the interrupt had been acknowledged) yet will not
|
||||
* have actually received the interrupt. This could confuse the guest!
|
||||
*/
|
||||
if ( vmcb->eventinj.fields.v )
|
||||
return;
|
||||
|
||||
switch ( intr_type )
|
||||
/*
|
||||
* Previous Interrupt delivery caused this intercept?
|
||||
* This will happen if the injection is latched by the processor (hence
|
||||
* clearing vintr.fields.irq) but then subsequently a fault occurs (e.g.,
|
||||
* due to lack of shadow mapping of guest IDT or guest-kernel stack).
|
||||
*
|
||||
* NB. Exceptions that fault during delivery are lost. This needs to be
|
||||
* fixed but we'll usually get away with it since faults are usually
|
||||
* idempotent. But this isn't the case for e.g. software interrupts!
|
||||
*/
|
||||
if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
|
||||
{
|
||||
case APIC_DM_EXTINT:
|
||||
case APIC_DM_FIXED:
|
||||
case APIC_DM_LOWEST:
|
||||
/* Re-injecting a PIT interruptt? */
|
||||
if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) )
|
||||
++pt->pending_intr_nr;
|
||||
/* let's inject this interrupt */
|
||||
if (re_injecting)
|
||||
HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
|
||||
else
|
||||
HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
|
||||
intr_vector = vmcb->exitintinfo.fields.vector;
|
||||
vmcb->exitintinfo.bytes = 0;
|
||||
HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
|
||||
svm_inject_extint(v, intr_vector);
|
||||
break;
|
||||
case APIC_DM_SMI:
|
||||
case APIC_DM_NMI:
|
||||
case APIC_DM_INIT:
|
||||
case APIC_DM_STARTUP:
|
||||
default:
|
||||
printk("Unsupported interrupt type: %d\n", intr_type);
|
||||
BUG();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Previous interrupt still pending? This occurs if we return from VMRUN
|
||||
* very early in the entry-to-guest process. Usually this is because an
|
||||
* external physical interrupt was pending when we executed VMRUN.
|
||||
*/
|
||||
if ( vmcb->vintr.fields.irq )
|
||||
return;
|
||||
|
||||
/* Crank the handle on interrupt state and check for new interrrupts. */
|
||||
pt_update_irq(v);
|
||||
hvm_set_callback_irq_level();
|
||||
if ( !cpu_has_pending_irq(v) )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Create a 'fake' virtual interrupt on to intercept as soon as the
|
||||
* guest _can_ take interrupts. Do not obtain the next interrupt from
|
||||
* the vlapic/pic if unable to inject.
|
||||
*/
|
||||
if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )
|
||||
{
|
||||
vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
|
||||
HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
|
||||
svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Okay, we can deliver the interrupt: grab it and update PIC state. */
|
||||
intr_vector = cpu_get_interrupt(v, &intr_type);
|
||||
BUG_ON(intr_vector < 0);
|
||||
|
||||
HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
|
||||
svm_inject_extint(v, intr_vector);
|
||||
|
||||
pt_intr_post(v, intr_vector, intr_type);
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -64,8 +64,8 @@ extern void svm_dump_inst(unsigned long eip);
|
||||
extern int svm_dbg_on;
|
||||
void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
|
||||
|
||||
static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
|
||||
struct cpu_user_regs *regs);
|
||||
static int svm_reset_to_realmode(struct vcpu *v,
|
||||
struct cpu_user_regs *regs);
|
||||
|
||||
/* va of hardware host save area */
|
||||
static void *hsa[NR_CPUS] __read_mostly;
|
||||
@@ -749,19 +749,21 @@ static void svm_init_ap_context(
|
||||
struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
|
||||
{
|
||||
struct vcpu *v;
|
||||
struct vmcb_struct *vmcb;
|
||||
cpu_user_regs_t *regs;
|
||||
u16 cs_sel;
|
||||
|
||||
/* We know this is safe because hvm_bringup_ap() does it */
|
||||
v = current->domain->vcpu[vcpuid];
|
||||
vmcb = v->arch.hvm_svm.vmcb;
|
||||
regs = &v->arch.guest_context.user_regs;
|
||||
|
||||
memset(ctxt, 0, sizeof(*ctxt));
|
||||
|
||||
/*
|
||||
* We execute the trampoline code in real mode. The trampoline vector
|
||||
* passed to us is page alligned and is the physicall frame number for
|
||||
* the code. We will execute this code in real mode.
|
||||
* passed to us is page alligned and is the physical frame number for
|
||||
* the code. We will execute this code in real mode.
|
||||
*/
|
||||
cs_sel = trampoline_vector << 8;
|
||||
ctxt->user_regs.eip = 0x0;
|
||||
@@ -771,11 +773,11 @@ static void svm_init_ap_context(
|
||||
* This is the launch of an AP; set state so that we begin executing
|
||||
* the trampoline code in real-mode.
|
||||
*/
|
||||
svm_do_vmmcall_reset_to_realmode(v, regs);
|
||||
svm_reset_to_realmode(v, regs);
|
||||
/* Adjust the vmcb's hidden register state. */
|
||||
v->arch.hvm_svm.vmcb->rip = 0;
|
||||
v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
|
||||
v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
|
||||
vmcb->rip = 0;
|
||||
vmcb->cs.sel = cs_sel;
|
||||
vmcb->cs.base = (cs_sel << 4);
|
||||
}
|
||||
|
||||
static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
|
||||
@@ -961,8 +963,6 @@ static int svm_vcpu_initialise(struct vcpu *v)
|
||||
v->arch.ctxt_switch_from = svm_ctxt_switch_from;
|
||||
v->arch.ctxt_switch_to = svm_ctxt_switch_to;
|
||||
|
||||
v->arch.hvm_svm.saved_irq_vector = -1;
|
||||
|
||||
v->arch.hvm_svm.launch_core = -1;
|
||||
|
||||
if ( (rc = svm_create_vmcb(v)) != 0 )
|
||||
@@ -2494,8 +2494,8 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
|
||||
*
|
||||
* returns 0 on success, non-zero otherwise
|
||||
*/
|
||||
static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
|
||||
struct cpu_user_regs *regs)
|
||||
static int svm_reset_to_realmode(struct vcpu *v,
|
||||
struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vmcb_struct *vmcb;
|
||||
|
||||
|
||||
@@ -203,6 +203,7 @@ static int construct_vmcb(struct vcpu *v)
|
||||
vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
|
||||
vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_PG;
|
||||
vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
|
||||
vmcb->cr4 = arch_svm->cpu_shadow_cr4 = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -89,7 +89,7 @@ static void update_tpr_threshold(struct vlapic *vlapic)
|
||||
asmlinkage void vmx_intr_assist(void)
|
||||
{
|
||||
int intr_type = 0;
|
||||
int highest_vector;
|
||||
int intr_vector;
|
||||
unsigned long eflags;
|
||||
struct vcpu *v = current;
|
||||
unsigned int idtv_info_field;
|
||||
@@ -106,8 +106,9 @@ asmlinkage void vmx_intr_assist(void)
|
||||
|
||||
if ( unlikely(v->arch.hvm_vmx.vector_injected) )
|
||||
{
|
||||
v->arch.hvm_vmx.vector_injected=0;
|
||||
if (unlikely(has_ext_irq)) enable_irq_window(v);
|
||||
v->arch.hvm_vmx.vector_injected = 0;
|
||||
if ( unlikely(has_ext_irq) )
|
||||
enable_irq_window(v);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +133,6 @@ asmlinkage void vmx_intr_assist(void)
|
||||
enable_irq_window(v);
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,30 +154,13 @@ asmlinkage void vmx_intr_assist(void)
|
||||
return;
|
||||
}
|
||||
|
||||
highest_vector = cpu_get_interrupt(v, &intr_type);
|
||||
if ( highest_vector < 0 )
|
||||
return;
|
||||
intr_vector = cpu_get_interrupt(v, &intr_type);
|
||||
BUG_ON(intr_vector < 0);
|
||||
|
||||
switch ( intr_type )
|
||||
{
|
||||
case APIC_DM_EXTINT:
|
||||
case APIC_DM_FIXED:
|
||||
case APIC_DM_LOWEST:
|
||||
HVMTRACE_2D(INJ_VIRQ, v, highest_vector, /*fake=*/ 0);
|
||||
vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
|
||||
break;
|
||||
HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
|
||||
vmx_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
|
||||
|
||||
case APIC_DM_SMI:
|
||||
case APIC_DM_NMI:
|
||||
case APIC_DM_INIT:
|
||||
case APIC_DM_STARTUP:
|
||||
default:
|
||||
printk("Unsupported interrupt type\n");
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
pt_intr_post(v, highest_vector, intr_type);
|
||||
pt_intr_post(v, intr_vector, intr_type);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ asmlinkage void do_IRQ(struct cpu_user_regs *regs)
|
||||
irq_desc_t *desc = &irq_desc[vector];
|
||||
struct irqaction *action;
|
||||
|
||||
perfc_incrc(irqs);
|
||||
perfc_incr(irqs);
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
desc->handler->ack(vector);
|
||||
|
||||
+21
-13
@@ -1726,7 +1726,7 @@ int get_page_type(struct page_info *page, unsigned long type)
|
||||
(!shadow_mode_enabled(page_get_owner(page)) ||
|
||||
((nx & PGT_type_mask) == PGT_writable_page)) )
|
||||
{
|
||||
perfc_incrc(need_flush_tlb_flush);
|
||||
perfc_incr(need_flush_tlb_flush);
|
||||
flush_tlb_mask(mask);
|
||||
}
|
||||
|
||||
@@ -1969,6 +1969,8 @@ int do_mmuext_op(
|
||||
if ( unlikely(!guest_handle_is_null(pdone)) )
|
||||
(void)copy_from_guest(&done, pdone, 1);
|
||||
}
|
||||
else
|
||||
perfc_incr(calls_to_mmuext_op);
|
||||
|
||||
if ( unlikely(!guest_handle_okay(uops, count)) )
|
||||
{
|
||||
@@ -2223,6 +2225,8 @@ int do_mmuext_op(
|
||||
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
perfc_add(num_mmuext_ops, i);
|
||||
|
||||
out:
|
||||
/* Add incremental work we have done to the @done output parameter. */
|
||||
if ( unlikely(!guest_handle_is_null(pdone)) )
|
||||
@@ -2257,6 +2261,8 @@ int do_mmu_update(
|
||||
if ( unlikely(!guest_handle_is_null(pdone)) )
|
||||
(void)copy_from_guest(&done, pdone, 1);
|
||||
}
|
||||
else
|
||||
perfc_incr(calls_to_mmu_update);
|
||||
|
||||
if ( unlikely(!guest_handle_okay(ureqs, count)) )
|
||||
{
|
||||
@@ -2273,9 +2279,6 @@ int do_mmu_update(
|
||||
domain_mmap_cache_init(&mapcache);
|
||||
domain_mmap_cache_init(&sh_mapcache);
|
||||
|
||||
perfc_incrc(calls_to_mmu_update);
|
||||
perfc_addc(num_page_updates, count);
|
||||
|
||||
LOCK_BIGLOCK(d);
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
@@ -2431,13 +2434,15 @@ int do_mmu_update(
|
||||
guest_handle_add_offset(ureqs, 1);
|
||||
}
|
||||
|
||||
domain_mmap_cache_destroy(&mapcache);
|
||||
domain_mmap_cache_destroy(&sh_mapcache);
|
||||
|
||||
process_deferred_ops();
|
||||
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
domain_mmap_cache_destroy(&mapcache);
|
||||
domain_mmap_cache_destroy(&sh_mapcache);
|
||||
|
||||
perfc_add(num_page_updates, i);
|
||||
|
||||
out:
|
||||
/* Add incremental work we have done to the @done output parameter. */
|
||||
if ( unlikely(!guest_handle_is_null(pdone)) )
|
||||
@@ -2724,7 +2729,7 @@ int do_update_va_mapping(unsigned long va, u64 val64,
|
||||
cpumask_t pmask;
|
||||
int rc = 0;
|
||||
|
||||
perfc_incrc(calls_to_update_va);
|
||||
perfc_incr(calls_to_update_va);
|
||||
|
||||
if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) )
|
||||
return -EINVAL;
|
||||
@@ -2740,6 +2745,10 @@ int do_update_va_mapping(unsigned long va, u64 val64,
|
||||
guest_unmap_l1e(v, pl1e);
|
||||
pl1e = NULL;
|
||||
|
||||
process_deferred_ops();
|
||||
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
switch ( flags & UVMF_FLUSHTYPE_MASK )
|
||||
{
|
||||
case UVMF_TLB_FLUSH:
|
||||
@@ -2785,10 +2794,6 @@ int do_update_va_mapping(unsigned long va, u64 val64,
|
||||
break;
|
||||
}
|
||||
|
||||
process_deferred_ops();
|
||||
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2806,6 +2811,9 @@ int do_update_va_mapping_otherdomain(unsigned long va, u64 val64,
|
||||
|
||||
rc = do_update_va_mapping(va, val64, flags);
|
||||
|
||||
BUG_ON(this_cpu(percpu_mm_info).deferred_ops);
|
||||
process_deferred_ops(); /* only to clear foreigndom */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3378,7 +3386,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
|
||||
goto bail;
|
||||
|
||||
UNLOCK_BIGLOCK(d);
|
||||
perfc_incrc(ptwr_emulations);
|
||||
perfc_incr(ptwr_emulations);
|
||||
return EXCRET_fault_fixed;
|
||||
|
||||
bail:
|
||||
|
||||
@@ -135,6 +135,7 @@ void hap_free_p2m_page(struct domain *d, struct page_info *pg)
|
||||
HAP_ERROR("Odd p2m page count c=%#x t=%"PRtype_info"\n",
|
||||
pg->count_info, pg->u.inuse.type_info);
|
||||
}
|
||||
pg->count_info = 0;
|
||||
/* Free should not decrement domain's total allocation, since
|
||||
* these pages were allocated without an owner. */
|
||||
page_set_owner(pg, NULL);
|
||||
@@ -182,6 +183,7 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
|
||||
list_del(&sp->list);
|
||||
d->arch.paging.hap.free_pages -= 1;
|
||||
d->arch.paging.hap.total_pages -= 1;
|
||||
sp->count_info = 0;
|
||||
free_domheap_pages(sp, 0);
|
||||
}
|
||||
|
||||
@@ -367,17 +369,7 @@ void hap_destroy_monitor_table(struct vcpu* v, mfn_t mmfn)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
|
||||
#if CONFIG_PAGING_LEVELS == 4
|
||||
/* Need to destroy the l3 monitor page in slot 0 too */
|
||||
{
|
||||
mfn_t m3mfn;
|
||||
l4_pgentry_t *l4e = hap_map_domain_page(mmfn);
|
||||
ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT);
|
||||
m3mfn = _mfn(l4e_get_pfn(l4e[0]));
|
||||
hap_free(d, m3mfn);
|
||||
hap_unmap_domain_page(l4e);
|
||||
}
|
||||
#elif CONFIG_PAGING_LEVELS == 3
|
||||
#if CONFIG_PAGING_LEVELS == 3
|
||||
/* Need to destroy the l2 monitor page in slot 4 too */
|
||||
{
|
||||
l3_pgentry_t *l3e = hap_map_domain_page(mmfn);
|
||||
@@ -632,10 +624,6 @@ void hap_update_paging_modes(struct vcpu *v)
|
||||
|
||||
v->arch.paging.translate_enabled = !!hvm_paging_enabled(v);
|
||||
|
||||
/* use p2m map */
|
||||
v->arch.guest_table =
|
||||
pagetable_from_pfn(pagetable_get_pfn(d->arch.phys_table));
|
||||
|
||||
if ( pagetable_is_null(v->arch.monitor_table) ) {
|
||||
mfn_t mmfn = hap_make_monitor_table(v);
|
||||
v->arch.monitor_table = pagetable_from_mfn(mmfn);
|
||||
|
||||
@@ -276,7 +276,7 @@ hvm_emulate_write(enum x86_segment seg,
|
||||
|
||||
/* How many emulations could we save if we unshadowed on stack writes? */
|
||||
if ( seg == x86_seg_ss )
|
||||
perfc_incrc(shadow_fault_emulate_stack);
|
||||
perfc_incr(shadow_fault_emulate_stack);
|
||||
|
||||
rc = hvm_translate_linear_addr(
|
||||
seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
|
||||
@@ -804,7 +804,7 @@ void shadow_prealloc(struct domain *d, unsigned int order)
|
||||
ASSERT(v != NULL); /* Shouldn't have enabled shadows if we've no vcpus */
|
||||
|
||||
/* Stage one: walk the list of pinned pages, unpinning them */
|
||||
perfc_incrc(shadow_prealloc_1);
|
||||
perfc_incr(shadow_prealloc_1);
|
||||
list_for_each_backwards_safe(l, t, &d->arch.paging.shadow.pinned_shadows)
|
||||
{
|
||||
sp = list_entry(l, struct shadow_page_info, list);
|
||||
@@ -820,7 +820,7 @@ void shadow_prealloc(struct domain *d, unsigned int order)
|
||||
/* Stage two: all shadow pages are in use in hierarchies that are
|
||||
* loaded in cr3 on some vcpu. Walk them, unhooking the non-Xen
|
||||
* mappings. */
|
||||
perfc_incrc(shadow_prealloc_2);
|
||||
perfc_incr(shadow_prealloc_2);
|
||||
|
||||
for_each_vcpu(d, v2)
|
||||
for ( i = 0 ; i < 4 ; i++ )
|
||||
@@ -929,7 +929,7 @@ mfn_t shadow_alloc(struct domain *d,
|
||||
ASSERT(shadow_locked_by_me(d));
|
||||
ASSERT(order <= SHADOW_MAX_ORDER);
|
||||
ASSERT(shadow_type != SH_type_none);
|
||||
perfc_incrc(shadow_alloc);
|
||||
perfc_incr(shadow_alloc);
|
||||
|
||||
/* Find smallest order which can satisfy the request. */
|
||||
for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
|
||||
@@ -967,7 +967,7 @@ mfn_t shadow_alloc(struct domain *d,
|
||||
tlbflush_filter(mask, sp[i].tlbflush_timestamp);
|
||||
if ( unlikely(!cpus_empty(mask)) )
|
||||
{
|
||||
perfc_incrc(shadow_alloc_tlbflush);
|
||||
perfc_incr(shadow_alloc_tlbflush);
|
||||
flush_tlb_mask(mask);
|
||||
}
|
||||
/* Now safe to clear the page for reuse */
|
||||
@@ -997,7 +997,7 @@ void shadow_free(struct domain *d, mfn_t smfn)
|
||||
int i;
|
||||
|
||||
ASSERT(shadow_locked_by_me(d));
|
||||
perfc_incrc(shadow_free);
|
||||
perfc_incr(shadow_free);
|
||||
|
||||
shadow_type = sp->type;
|
||||
ASSERT(shadow_type != SH_type_none);
|
||||
@@ -1406,7 +1406,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v, unsigned long n, unsigned int t)
|
||||
|
||||
sh_hash_audit(d);
|
||||
|
||||
perfc_incrc(shadow_hash_lookups);
|
||||
perfc_incr(shadow_hash_lookups);
|
||||
key = sh_hash(n, t);
|
||||
sh_hash_audit_bucket(d, key);
|
||||
|
||||
@@ -1434,7 +1434,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v, unsigned long n, unsigned int t)
|
||||
}
|
||||
else
|
||||
{
|
||||
perfc_incrc(shadow_hash_lookup_head);
|
||||
perfc_incr(shadow_hash_lookup_head);
|
||||
}
|
||||
return shadow_page_to_mfn(sp);
|
||||
}
|
||||
@@ -1442,7 +1442,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v, unsigned long n, unsigned int t)
|
||||
sp = sp->next_shadow;
|
||||
}
|
||||
|
||||
perfc_incrc(shadow_hash_lookup_miss);
|
||||
perfc_incr(shadow_hash_lookup_miss);
|
||||
return _mfn(INVALID_MFN);
|
||||
}
|
||||
|
||||
@@ -1460,7 +1460,7 @@ void shadow_hash_insert(struct vcpu *v, unsigned long n, unsigned int t,
|
||||
|
||||
sh_hash_audit(d);
|
||||
|
||||
perfc_incrc(shadow_hash_inserts);
|
||||
perfc_incr(shadow_hash_inserts);
|
||||
key = sh_hash(n, t);
|
||||
sh_hash_audit_bucket(d, key);
|
||||
|
||||
@@ -1486,7 +1486,7 @@ void shadow_hash_delete(struct vcpu *v, unsigned long n, unsigned int t,
|
||||
|
||||
sh_hash_audit(d);
|
||||
|
||||
perfc_incrc(shadow_hash_deletes);
|
||||
perfc_incr(shadow_hash_deletes);
|
||||
key = sh_hash(n, t);
|
||||
sh_hash_audit_bucket(d, key);
|
||||
|
||||
@@ -1713,7 +1713,7 @@ int sh_remove_write_access(struct vcpu *v, mfn_t gmfn,
|
||||
|| (pg->u.inuse.type_info & PGT_count_mask) == 0 )
|
||||
return 0;
|
||||
|
||||
perfc_incrc(shadow_writeable);
|
||||
perfc_incr(shadow_writeable);
|
||||
|
||||
/* If this isn't a "normal" writeable page, the domain is trying to
|
||||
* put pagetables in special memory of some kind. We can't allow that. */
|
||||
@@ -1735,7 +1735,7 @@ int sh_remove_write_access(struct vcpu *v, mfn_t gmfn,
|
||||
|
||||
#define GUESS(_a, _h) do { \
|
||||
if ( v->arch.paging.mode->shadow.guess_wrmap(v, (_a), gmfn) ) \
|
||||
perfc_incrc(shadow_writeable_h_ ## _h); \
|
||||
perfc_incr(shadow_writeable_h_ ## _h); \
|
||||
if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 ) \
|
||||
return 1; \
|
||||
} while (0)
|
||||
@@ -1808,7 +1808,7 @@ int sh_remove_write_access(struct vcpu *v, mfn_t gmfn,
|
||||
callbacks[shtype](v, last_smfn, gmfn);
|
||||
|
||||
if ( (pg->u.inuse.type_info & PGT_count_mask) != old_count )
|
||||
perfc_incrc(shadow_writeable_h_5);
|
||||
perfc_incr(shadow_writeable_h_5);
|
||||
}
|
||||
|
||||
if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 )
|
||||
@@ -1817,7 +1817,7 @@ int sh_remove_write_access(struct vcpu *v, mfn_t gmfn,
|
||||
#endif /* SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC */
|
||||
|
||||
/* Brute-force search of all the shadows, by walking the hash */
|
||||
perfc_incrc(shadow_writeable_bf);
|
||||
perfc_incr(shadow_writeable_bf);
|
||||
hash_foreach(v, callback_mask, callbacks, gmfn);
|
||||
|
||||
/* If that didn't catch the mapping, something is very wrong */
|
||||
@@ -1888,7 +1888,7 @@ int sh_remove_all_mappings(struct vcpu *v, mfn_t gmfn)
|
||||
| 1 << SH_type_fl1_64_shadow
|
||||
;
|
||||
|
||||
perfc_incrc(shadow_mappings);
|
||||
perfc_incr(shadow_mappings);
|
||||
if ( (page->count_info & PGC_count_mask) == 0 )
|
||||
return 0;
|
||||
|
||||
@@ -1903,7 +1903,7 @@ int sh_remove_all_mappings(struct vcpu *v, mfn_t gmfn)
|
||||
* Heuristics for finding the (probably) single mapping of this gmfn */
|
||||
|
||||
/* Brute-force search of all the shadows, by walking the hash */
|
||||
perfc_incrc(shadow_mappings_bf);
|
||||
perfc_incr(shadow_mappings_bf);
|
||||
hash_foreach(v, callback_mask, callbacks, gmfn);
|
||||
|
||||
/* If that didn't catch the mapping, something is very wrong */
|
||||
@@ -1992,9 +1992,9 @@ static int sh_remove_shadow_via_pointer(struct vcpu *v, mfn_t smfn)
|
||||
|
||||
sh_unmap_domain_page(vaddr);
|
||||
if ( rc )
|
||||
perfc_incrc(shadow_up_pointer);
|
||||
perfc_incr(shadow_up_pointer);
|
||||
else
|
||||
perfc_incrc(shadow_unshadow_bf);
|
||||
perfc_incr(shadow_unshadow_bf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -2093,7 +2093,7 @@ void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int fast, int all)
|
||||
}
|
||||
|
||||
/* Search for this shadow in all appropriate shadows */
|
||||
perfc_incrc(shadow_unshadow);
|
||||
perfc_incr(shadow_unshadow);
|
||||
sh_flags = pg->shadow_flags;
|
||||
|
||||
/* Lower-level shadows need to be excised from upper-level shadows.
|
||||
|
||||
@@ -109,7 +109,7 @@ get_shadow_status(struct vcpu *v, mfn_t gmfn, u32 shadow_type)
|
||||
/* Look for shadows in the hash table */
|
||||
{
|
||||
mfn_t smfn = shadow_hash_lookup(v, mfn_x(gmfn), shadow_type);
|
||||
perfc_incrc(shadow_get_shadow_status);
|
||||
perfc_incr(shadow_get_shadow_status);
|
||||
return smfn;
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ guest_walk_tables(struct vcpu *v, unsigned long va, walk_t *gw, int guest_op)
|
||||
{
|
||||
ASSERT(!guest_op || shadow_locked_by_me(v->domain));
|
||||
|
||||
perfc_incrc(shadow_guest_walk);
|
||||
perfc_incr(shadow_guest_walk);
|
||||
memset(gw, 0, sizeof(*gw));
|
||||
gw->va = va;
|
||||
|
||||
@@ -448,14 +448,14 @@ static u32 guest_set_ad_bits(struct vcpu *v,
|
||||
== (_PAGE_DIRTY | _PAGE_ACCESSED) )
|
||||
return flags; /* Guest already has A and D bits set */
|
||||
flags |= _PAGE_DIRTY | _PAGE_ACCESSED;
|
||||
perfc_incrc(shadow_ad_update);
|
||||
perfc_incr(shadow_ad_update);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flags & _PAGE_ACCESSED )
|
||||
return flags; /* Guest already has A bit set */
|
||||
flags |= _PAGE_ACCESSED;
|
||||
perfc_incrc(shadow_a_update);
|
||||
perfc_incr(shadow_a_update);
|
||||
}
|
||||
|
||||
/* Set the bit(s) */
|
||||
@@ -863,7 +863,7 @@ shadow_write_entries(void *d, void *s, int entries, mfn_t mfn)
|
||||
* using map_domain_page() to get a writeable mapping if we need to. */
|
||||
if ( __copy_to_user(d, d, sizeof (unsigned long)) != 0 )
|
||||
{
|
||||
perfc_incrc(shadow_linear_map_failed);
|
||||
perfc_incr(shadow_linear_map_failed);
|
||||
map = sh_map_domain_page(mfn);
|
||||
ASSERT(map != NULL);
|
||||
dst = map + ((unsigned long)dst & (PAGE_SIZE - 1));
|
||||
@@ -925,7 +925,7 @@ shadow_get_page_from_l1e(shadow_l1e_t sl1e, struct domain *d)
|
||||
|
||||
if ( unlikely(!res) )
|
||||
{
|
||||
perfc_incrc(shadow_get_page_fail);
|
||||
perfc_incr(shadow_get_page_fail);
|
||||
SHADOW_PRINTK("failed: l1e=" SH_PRI_pte "\n");
|
||||
}
|
||||
|
||||
@@ -2198,7 +2198,7 @@ static int validate_gl4e(struct vcpu *v, void *new_ge, mfn_t sl4mfn, void *se)
|
||||
mfn_t sl3mfn = _mfn(INVALID_MFN);
|
||||
int result = 0;
|
||||
|
||||
perfc_incrc(shadow_validate_gl4e_calls);
|
||||
perfc_incr(shadow_validate_gl4e_calls);
|
||||
|
||||
if ( guest_l4e_get_flags(*new_gl4e) & _PAGE_PRESENT )
|
||||
{
|
||||
@@ -2250,7 +2250,7 @@ static int validate_gl3e(struct vcpu *v, void *new_ge, mfn_t sl3mfn, void *se)
|
||||
mfn_t sl2mfn = _mfn(INVALID_MFN);
|
||||
int result = 0;
|
||||
|
||||
perfc_incrc(shadow_validate_gl3e_calls);
|
||||
perfc_incr(shadow_validate_gl3e_calls);
|
||||
|
||||
if ( guest_l3e_get_flags(*new_gl3e) & _PAGE_PRESENT )
|
||||
{
|
||||
@@ -2277,7 +2277,7 @@ static int validate_gl2e(struct vcpu *v, void *new_ge, mfn_t sl2mfn, void *se)
|
||||
mfn_t sl1mfn = _mfn(INVALID_MFN);
|
||||
int result = 0;
|
||||
|
||||
perfc_incrc(shadow_validate_gl2e_calls);
|
||||
perfc_incr(shadow_validate_gl2e_calls);
|
||||
|
||||
if ( guest_l2e_get_flags(*new_gl2e) & _PAGE_PRESENT )
|
||||
{
|
||||
@@ -2363,7 +2363,7 @@ static int validate_gl1e(struct vcpu *v, void *new_ge, mfn_t sl1mfn, void *se)
|
||||
mfn_t gmfn;
|
||||
int result = 0, mmio;
|
||||
|
||||
perfc_incrc(shadow_validate_gl1e_calls);
|
||||
perfc_incr(shadow_validate_gl1e_calls);
|
||||
|
||||
gfn = guest_l1e_get_gfn(*new_gl1e);
|
||||
gmfn = vcpu_gfn_to_mfn(v, gfn);
|
||||
@@ -2523,7 +2523,7 @@ static inline void check_for_early_unshadow(struct vcpu *v, mfn_t gmfn)
|
||||
u32 flags = mfn_to_page(gmfn)->shadow_flags;
|
||||
if ( !(flags & (SHF_L2_32|SHF_L2_PAE|SHF_L2H_PAE|SHF_L4_64)) )
|
||||
{
|
||||
perfc_incrc(shadow_early_unshadow);
|
||||
perfc_incr(shadow_early_unshadow);
|
||||
sh_remove_shadows(v, gmfn, 0, 0 /* Slow, can fail to unshadow */ );
|
||||
}
|
||||
}
|
||||
@@ -2642,7 +2642,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
SHADOW_PRINTK("d:v=%u:%u va=%#lx err=%u\n",
|
||||
v->domain->domain_id, v->vcpu_id, va, regs->error_code);
|
||||
|
||||
perfc_incrc(shadow_fault);
|
||||
perfc_incr(shadow_fault);
|
||||
//
|
||||
// XXX: Need to think about eventually mapping superpages directly in the
|
||||
// shadow (when possible), as opposed to splintering them into a
|
||||
@@ -2670,7 +2670,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
ASSERT(regs->error_code & PFEC_page_present);
|
||||
regs->error_code ^= (PFEC_reserved_bit|PFEC_page_present);
|
||||
reset_early_unshadow(v);
|
||||
perfc_incrc(shadow_fault_fast_gnp);
|
||||
perfc_incr(shadow_fault_fast_gnp);
|
||||
SHADOW_PRINTK("fast path not-present\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -2688,7 +2688,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
<< PAGE_SHIFT)
|
||||
| (va & ~PAGE_MASK);
|
||||
}
|
||||
perfc_incrc(shadow_fault_fast_mmio);
|
||||
perfc_incr(shadow_fault_fast_mmio);
|
||||
SHADOW_PRINTK("fast path mmio %#"PRIpaddr"\n", gpa);
|
||||
reset_early_unshadow(v);
|
||||
handle_mmio(gpa);
|
||||
@@ -2699,7 +2699,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
/* This should be exceptionally rare: another vcpu has fixed
|
||||
* the tables between the fault and our reading the l1e.
|
||||
* Retry and let the hardware give us the right fault next time. */
|
||||
perfc_incrc(shadow_fault_fast_fail);
|
||||
perfc_incr(shadow_fault_fast_fail);
|
||||
SHADOW_PRINTK("fast path false alarm!\n");
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
@@ -2746,7 +2746,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
goto mmio;
|
||||
}
|
||||
|
||||
perfc_incrc(shadow_fault_bail_not_present);
|
||||
perfc_incr(shadow_fault_bail_not_present);
|
||||
goto not_a_shadow_fault;
|
||||
}
|
||||
|
||||
@@ -2761,7 +2761,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
!(accumulated_gflags & _PAGE_USER) )
|
||||
{
|
||||
/* illegal user-mode access to supervisor-only page */
|
||||
perfc_incrc(shadow_fault_bail_user_supervisor);
|
||||
perfc_incr(shadow_fault_bail_user_supervisor);
|
||||
goto not_a_shadow_fault;
|
||||
}
|
||||
|
||||
@@ -2772,7 +2772,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
{
|
||||
if ( unlikely(!(accumulated_gflags & _PAGE_RW)) )
|
||||
{
|
||||
perfc_incrc(shadow_fault_bail_ro_mapping);
|
||||
perfc_incr(shadow_fault_bail_ro_mapping);
|
||||
goto not_a_shadow_fault;
|
||||
}
|
||||
}
|
||||
@@ -2787,7 +2787,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
if ( accumulated_gflags & _PAGE_NX_BIT )
|
||||
{
|
||||
/* NX prevented this code fetch */
|
||||
perfc_incrc(shadow_fault_bail_nx);
|
||||
perfc_incr(shadow_fault_bail_nx);
|
||||
goto not_a_shadow_fault;
|
||||
}
|
||||
}
|
||||
@@ -2802,7 +2802,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
|
||||
if ( !mmio && !mfn_valid(gmfn) )
|
||||
{
|
||||
perfc_incrc(shadow_fault_bail_bad_gfn);
|
||||
perfc_incr(shadow_fault_bail_bad_gfn);
|
||||
SHADOW_PRINTK("BAD gfn=%"SH_PRI_gfn" gmfn=%"PRI_mfn"\n",
|
||||
gfn_x(gfn), mfn_x(gmfn));
|
||||
goto not_a_shadow_fault;
|
||||
@@ -2844,12 +2844,12 @@ static int sh_page_fault(struct vcpu *v,
|
||||
{
|
||||
if ( ft == ft_demand_write )
|
||||
{
|
||||
perfc_incrc(shadow_fault_emulate_write);
|
||||
perfc_incr(shadow_fault_emulate_write);
|
||||
goto emulate;
|
||||
}
|
||||
else if ( shadow_mode_trap_reads(d) && ft == ft_demand_read )
|
||||
{
|
||||
perfc_incrc(shadow_fault_emulate_read);
|
||||
perfc_incr(shadow_fault_emulate_read);
|
||||
goto emulate;
|
||||
}
|
||||
}
|
||||
@@ -2860,7 +2860,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
goto mmio;
|
||||
}
|
||||
|
||||
perfc_incrc(shadow_fault_fixed);
|
||||
perfc_incr(shadow_fault_fixed);
|
||||
d->arch.paging.shadow.fault_count++;
|
||||
reset_early_unshadow(v);
|
||||
|
||||
@@ -2920,7 +2920,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
{
|
||||
SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n",
|
||||
mfn_x(gmfn));
|
||||
perfc_incrc(shadow_fault_emulate_failed);
|
||||
perfc_incr(shadow_fault_emulate_failed);
|
||||
/* If this is actually a page table, then we have a bug, and need
|
||||
* to support more operations in the emulator. More likely,
|
||||
* though, this is a hint that this page should not be shadowed. */
|
||||
@@ -2935,7 +2935,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
mmio:
|
||||
if ( !guest_mode(regs) )
|
||||
goto not_a_shadow_fault;
|
||||
perfc_incrc(shadow_fault_mmio);
|
||||
perfc_incr(shadow_fault_mmio);
|
||||
sh_audit_gw(v, &gw);
|
||||
unmap_walk(v, &gw);
|
||||
SHADOW_PRINTK("mmio %#"PRIpaddr"\n", gpa);
|
||||
@@ -2964,7 +2964,7 @@ sh_invlpg(struct vcpu *v, unsigned long va)
|
||||
{
|
||||
shadow_l2e_t sl2e;
|
||||
|
||||
perfc_incrc(shadow_invlpg);
|
||||
perfc_incr(shadow_invlpg);
|
||||
|
||||
/* First check that we can safely read the shadow l2e. SMP/PAE linux can
|
||||
* run as high as 6% of invlpg calls where we haven't shadowed the l2
|
||||
@@ -2983,7 +2983,7 @@ sh_invlpg(struct vcpu *v, unsigned long va)
|
||||
+ shadow_l3_linear_offset(va)),
|
||||
sizeof (sl3e)) != 0 )
|
||||
{
|
||||
perfc_incrc(shadow_invlpg_fault);
|
||||
perfc_incr(shadow_invlpg_fault);
|
||||
return 0;
|
||||
}
|
||||
if ( (!shadow_l3e_get_flags(sl3e) & _PAGE_PRESENT) )
|
||||
@@ -3002,7 +3002,7 @@ sh_invlpg(struct vcpu *v, unsigned long va)
|
||||
sh_linear_l2_table(v) + shadow_l2_linear_offset(va),
|
||||
sizeof (sl2e)) != 0 )
|
||||
{
|
||||
perfc_incrc(shadow_invlpg_fault);
|
||||
perfc_incr(shadow_invlpg_fault);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -169,7 +169,7 @@ static unsigned long flush_va;
|
||||
fastcall void smp_invalidate_interrupt(void)
|
||||
{
|
||||
ack_APIC_irq();
|
||||
perfc_incrc(ipis);
|
||||
perfc_incr(ipis);
|
||||
irq_enter();
|
||||
if ( !__sync_lazy_execstate() )
|
||||
{
|
||||
@@ -329,7 +329,7 @@ void smp_send_stop(void)
|
||||
fastcall void smp_event_check_interrupt(struct cpu_user_regs *regs)
|
||||
{
|
||||
ack_APIC_irq();
|
||||
perfc_incrc(ipis);
|
||||
perfc_incr(ipis);
|
||||
}
|
||||
|
||||
fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs)
|
||||
@@ -338,7 +338,7 @@ fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs)
|
||||
void *info = call_data->info;
|
||||
|
||||
ack_APIC_irq();
|
||||
perfc_incrc(ipis);
|
||||
perfc_incr(ipis);
|
||||
|
||||
if ( !cpu_isset(smp_processor_id(), call_data->selected) )
|
||||
return;
|
||||
|
||||
+12
-10
@@ -670,14 +670,20 @@ static inline void version_update_end(u32 *version)
|
||||
(*version)++;
|
||||
}
|
||||
|
||||
static inline void __update_vcpu_system_time(struct vcpu *v)
|
||||
void update_vcpu_system_time(struct vcpu *v)
|
||||
{
|
||||
struct cpu_time *t;
|
||||
struct vcpu_time_info *u;
|
||||
|
||||
if ( v->vcpu_info == NULL )
|
||||
return;
|
||||
|
||||
t = &this_cpu(cpu_time);
|
||||
u = &vcpu_info(v, time);
|
||||
|
||||
if ( u->tsc_timestamp == t->local_tsc_stamp )
|
||||
return;
|
||||
|
||||
version_update_begin(&u->version);
|
||||
|
||||
u->tsc_timestamp = t->local_tsc_stamp;
|
||||
@@ -688,13 +694,6 @@ static inline void __update_vcpu_system_time(struct vcpu *v)
|
||||
version_update_end(&u->version);
|
||||
}
|
||||
|
||||
void update_vcpu_system_time(struct vcpu *v)
|
||||
{
|
||||
if ( vcpu_info(v, time.tsc_timestamp) !=
|
||||
this_cpu(cpu_time).local_tsc_stamp )
|
||||
__update_vcpu_system_time(v);
|
||||
}
|
||||
|
||||
void update_domain_wallclock_time(struct domain *d)
|
||||
{
|
||||
spin_lock(&wc_lock);
|
||||
@@ -771,9 +770,10 @@ static void local_time_calibration(void *unused)
|
||||
local_irq_enable();
|
||||
|
||||
#if 0
|
||||
printk("PRE%d: tsc=%lld stime=%lld master=%lld\n",
|
||||
printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n",
|
||||
smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime);
|
||||
printk("CUR%d: tsc=%lld stime=%lld master=%lld -> %lld\n",
|
||||
printk("CUR%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64
|
||||
" -> %"PRId64"\n",
|
||||
smp_processor_id(), curr_tsc, curr_local_stime, curr_master_stime,
|
||||
curr_master_stime - curr_local_stime);
|
||||
#endif
|
||||
@@ -855,6 +855,8 @@ static void local_time_calibration(void *unused)
|
||||
t->stime_local_stamp = curr_local_stime;
|
||||
t->stime_master_stamp = curr_master_stime;
|
||||
|
||||
update_vcpu_system_time(current);
|
||||
|
||||
out:
|
||||
set_timer(&t->calibration_timer, NOW() + EPOCH);
|
||||
|
||||
|
||||
+16
-10
@@ -637,29 +637,35 @@ asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
|
||||
memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) ||
|
||||
(bug.ret != 0xc2) )
|
||||
goto die;
|
||||
eip += sizeof(bug);
|
||||
|
||||
id = bug.id & 3;
|
||||
if ( id == BUGFRAME_rsvd )
|
||||
goto die;
|
||||
|
||||
if ( id == BUGFRAME_dump )
|
||||
{
|
||||
show_execution_state(regs);
|
||||
regs->eip += sizeof(bug);
|
||||
regs->eip = (unsigned long)eip;
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
|
||||
/* BUG() or ASSERT(): decode the filename pointer and line number. */
|
||||
ASSERT((id == BUGFRAME_bug) || (id == BUGFRAME_assert));
|
||||
eip += sizeof(bug);
|
||||
/* WARN, BUG or ASSERT: decode the filename pointer and line number. */
|
||||
if ( !is_kernel(eip) ||
|
||||
__copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
|
||||
memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
|
||||
goto die;
|
||||
eip += sizeof(bug_str);
|
||||
|
||||
filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
|
||||
lineno = bug.id >> 2;
|
||||
|
||||
if ( id == BUGFRAME_warn )
|
||||
{
|
||||
printk("Xen WARN at %.50s:%d\n", filename, lineno);
|
||||
show_execution_state(regs);
|
||||
regs->eip = (unsigned long)eip;
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
|
||||
if ( id == BUGFRAME_bug )
|
||||
{
|
||||
printk("Xen BUG at %.50s:%d\n", filename, lineno);
|
||||
@@ -668,13 +674,13 @@ asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
|
||||
panic("Xen BUG at %.50s:%d\n", filename, lineno);
|
||||
}
|
||||
|
||||
/* ASSERT(): decode the predicate string pointer. */
|
||||
/* ASSERT: decode the predicate string pointer. */
|
||||
ASSERT(id == BUGFRAME_assert);
|
||||
eip += sizeof(bug_str);
|
||||
if ( !is_kernel(eip) ||
|
||||
__copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
|
||||
memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
|
||||
goto die;
|
||||
eip += sizeof(bug_str);
|
||||
|
||||
predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
|
||||
printk("Assertion '%s' failed at %.50s:%d\n",
|
||||
@@ -950,7 +956,7 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
|
||||
|
||||
DEBUGGER_trap_entry(TRAP_page_fault, regs);
|
||||
|
||||
perfc_incrc(page_faults);
|
||||
perfc_incr(page_faults);
|
||||
|
||||
if ( unlikely((rc = fixup_page_fault(addr, regs)) != 0) )
|
||||
return rc;
|
||||
@@ -962,7 +968,7 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
|
||||
|
||||
if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
|
||||
{
|
||||
perfc_incrc(copy_user_faults);
|
||||
perfc_incr(copy_user_faults);
|
||||
regs->eip = fixup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -107,21 +107,11 @@ void __dummy__(void)
|
||||
BLANK();
|
||||
|
||||
#if PERF_COUNTERS
|
||||
OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
|
||||
OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
|
||||
DEFINE(PERFC_hypercalls, PERFC_hypercalls);
|
||||
DEFINE(PERFC_exceptions, PERFC_exceptions);
|
||||
BLANK();
|
||||
#endif
|
||||
|
||||
OFFSET(MULTICALL_op, struct multicall_entry, op);
|
||||
OFFSET(MULTICALL_arg0, struct multicall_entry, args[0]);
|
||||
OFFSET(MULTICALL_arg1, struct multicall_entry, args[1]);
|
||||
OFFSET(MULTICALL_arg2, struct multicall_entry, args[2]);
|
||||
OFFSET(MULTICALL_arg3, struct multicall_entry, args[3]);
|
||||
OFFSET(MULTICALL_arg4, struct multicall_entry, args[4]);
|
||||
OFFSET(MULTICALL_arg5, struct multicall_entry, args[5]);
|
||||
OFFSET(MULTICALL_result, struct multicall_entry, result);
|
||||
BLANK();
|
||||
|
||||
DEFINE(FIXMAP_apic_base, fix_to_virt(FIX_APIC_BASE));
|
||||
BLANK();
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ void *map_domain_page(unsigned long mfn)
|
||||
|
||||
ASSERT(!in_irq());
|
||||
|
||||
perfc_incrc(map_domain_page_count);
|
||||
perfc_incr(map_domain_page_count);
|
||||
|
||||
v = mapcache_current_vcpu();
|
||||
|
||||
@@ -76,7 +76,7 @@ void *map_domain_page(unsigned long mfn)
|
||||
cache->shadow_epoch[vcpu] = cache->epoch;
|
||||
if ( NEED_FLUSH(this_cpu(tlbflush_time), cache->tlbflush_timestamp) )
|
||||
{
|
||||
perfc_incrc(domain_page_tlb_flush);
|
||||
perfc_incr(domain_page_tlb_flush);
|
||||
local_flush_tlb();
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ void *map_domain_page(unsigned long mfn)
|
||||
}
|
||||
|
||||
/* /Second/, flush TLBs. */
|
||||
perfc_incrc(domain_page_tlb_flush);
|
||||
perfc_incr(domain_page_tlb_flush);
|
||||
local_flush_tlb();
|
||||
cache->shadow_epoch[vcpu] = ++cache->epoch;
|
||||
cache->tlbflush_timestamp = tlbflush_current_time();
|
||||
|
||||
@@ -173,7 +173,7 @@ ENTRY(hypercall)
|
||||
GET_CURRENT(%ebx)
|
||||
cmpl $NR_hypercalls,%eax
|
||||
jae bad_hypercall
|
||||
PERFC_INCR(PERFC_hypercalls, %eax)
|
||||
PERFC_INCR(PERFC_hypercalls, %eax, %ebx)
|
||||
#ifndef NDEBUG
|
||||
/* Create shadow parameters and corrupt those not used by this call. */
|
||||
pushl %eax
|
||||
@@ -429,7 +429,7 @@ handle_exception:
|
||||
movl %esp,%edx
|
||||
pushl %edx # push the cpu_user_regs pointer
|
||||
GET_CURRENT(%ebx)
|
||||
PERFC_INCR(PERFC_exceptions, %eax)
|
||||
PERFC_INCR(PERFC_exceptions, %eax, %ebx)
|
||||
call *exception_table(,%eax,4)
|
||||
addl $4,%esp
|
||||
movl UREGS_eflags(%esp),%eax
|
||||
|
||||
@@ -434,7 +434,7 @@ int gpf_emulate_4gb(struct cpu_user_regs *regs)
|
||||
goto fail;
|
||||
|
||||
/* Success! */
|
||||
perfc_incrc(seg_fixups);
|
||||
perfc_incr(seg_fixups);
|
||||
|
||||
/* If requested, give a callback on otherwise unused vector 15. */
|
||||
if ( VM_ASSIST(d->domain, VMASST_TYPE_4gb_segments_notify) )
|
||||
|
||||
@@ -121,30 +121,8 @@ void __dummy__(void)
|
||||
BLANK();
|
||||
|
||||
#if PERF_COUNTERS
|
||||
OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
|
||||
OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
|
||||
BLANK();
|
||||
#endif
|
||||
|
||||
OFFSET(MULTICALL_op, struct multicall_entry, op);
|
||||
OFFSET(MULTICALL_arg0, struct multicall_entry, args[0]);
|
||||
OFFSET(MULTICALL_arg1, struct multicall_entry, args[1]);
|
||||
OFFSET(MULTICALL_arg2, struct multicall_entry, args[2]);
|
||||
OFFSET(MULTICALL_arg3, struct multicall_entry, args[3]);
|
||||
OFFSET(MULTICALL_arg4, struct multicall_entry, args[4]);
|
||||
OFFSET(MULTICALL_arg5, struct multicall_entry, args[5]);
|
||||
OFFSET(MULTICALL_result, struct multicall_entry, result);
|
||||
BLANK();
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
OFFSET(COMPAT_MULTICALL_op, struct compat_multicall_entry, op);
|
||||
OFFSET(COMPAT_MULTICALL_arg0, struct compat_multicall_entry, args[0]);
|
||||
OFFSET(COMPAT_MULTICALL_arg1, struct compat_multicall_entry, args[1]);
|
||||
OFFSET(COMPAT_MULTICALL_arg2, struct compat_multicall_entry, args[2]);
|
||||
OFFSET(COMPAT_MULTICALL_arg3, struct compat_multicall_entry, args[3]);
|
||||
OFFSET(COMPAT_MULTICALL_arg4, struct compat_multicall_entry, args[4]);
|
||||
OFFSET(COMPAT_MULTICALL_arg5, struct compat_multicall_entry, args[5]);
|
||||
OFFSET(COMPAT_MULTICALL_result, struct compat_multicall_entry, result);
|
||||
DEFINE(PERFC_hypercalls, PERFC_hypercalls);
|
||||
DEFINE(PERFC_exceptions, PERFC_exceptions);
|
||||
BLANK();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ ENTRY(compat_hypercall)
|
||||
movl UREGS_rbx(%rsp),%edi /* Arg 1 */
|
||||
#endif
|
||||
leaq compat_hypercall_table(%rip),%r10
|
||||
PERFC_INCR(PERFC_hypercalls, %rax)
|
||||
PERFC_INCR(PERFC_hypercalls, %rax, %rbx)
|
||||
callq *(%r10,%rax,8)
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
|
||||
@@ -147,7 +147,7 @@ ENTRY(syscall_enter)
|
||||
pushq UREGS_rip+8(%rsp)
|
||||
#endif
|
||||
leaq hypercall_table(%rip),%r10
|
||||
PERFC_INCR(PERFC_hypercalls, %rax)
|
||||
PERFC_INCR(PERFC_hypercalls, %rax, %rbx)
|
||||
callq *(%r10,%rax,8)
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
@@ -396,7 +396,7 @@ handle_exception_saved:
|
||||
movl UREGS_entry_vector(%rsp),%eax
|
||||
leaq exception_table(%rip),%rdx
|
||||
GET_CURRENT(%rbx)
|
||||
PERFC_INCR(PERFC_exceptions, %rax)
|
||||
PERFC_INCR(PERFC_exceptions, %rax, %rbx)
|
||||
callq *(%rdx,%rax,8)
|
||||
testb $3,UREGS_cs(%rsp)
|
||||
jz restore_all_xen
|
||||
|
||||
@@ -1565,8 +1565,10 @@ x86_emulate(
|
||||
if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
|
||||
{
|
||||
dst.bytes = op_bytes = 8;
|
||||
if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
|
||||
&dst.val, 8, ctxt)) != 0 )
|
||||
if ( dst.type == OP_REG )
|
||||
dst.val = *dst.reg;
|
||||
else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
|
||||
&dst.val, 8, ctxt)) != 0 )
|
||||
goto done;
|
||||
}
|
||||
src.val = _regs.eip;
|
||||
@@ -1579,8 +1581,10 @@ x86_emulate(
|
||||
if ( mode_64bit() && (dst.bytes == 4) )
|
||||
{
|
||||
dst.bytes = 8;
|
||||
if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
|
||||
&dst.val, 8, ctxt)) != 0 )
|
||||
if ( dst.type == OP_REG )
|
||||
dst.val = *dst.reg;
|
||||
else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
|
||||
&dst.val, 8, ctxt)) != 0 )
|
||||
goto done;
|
||||
}
|
||||
if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
|
||||
|
||||
+3
-1
@@ -96,14 +96,16 @@ struct vcpu *alloc_vcpu(
|
||||
|
||||
v->domain = d;
|
||||
v->vcpu_id = vcpu_id;
|
||||
v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
|
||||
spin_lock_init(&v->pause_lock);
|
||||
|
||||
v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
|
||||
v->runstate.state_entry_time = NOW();
|
||||
|
||||
if ( !is_idle_domain(d) )
|
||||
{
|
||||
set_bit(_VCPUF_down, &v->vcpu_flags);
|
||||
v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
|
||||
}
|
||||
|
||||
if ( sched_init_vcpu(v, cpu_id) != 0 )
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <xen/event.h>
|
||||
#include <xen/multicall.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
@@ -69,14 +70,18 @@ do_multicall(
|
||||
guest_handle_add_offset(call_list, 1);
|
||||
}
|
||||
|
||||
perfc_incr(calls_to_multicall);
|
||||
perfc_add(calls_from_multicall, nr_calls);
|
||||
mcs->flags = 0;
|
||||
return 0;
|
||||
|
||||
fault:
|
||||
perfc_incr(calls_to_multicall);
|
||||
mcs->flags = 0;
|
||||
return -EFAULT;
|
||||
|
||||
preempted:
|
||||
perfc_add(calls_from_multicall, i);
|
||||
mcs->flags = 0;
|
||||
return hypercall_create_continuation(
|
||||
__HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
|
||||
|
||||
@@ -423,7 +423,7 @@ static struct page_info *alloc_heap_pages(
|
||||
|
||||
if ( unlikely(!cpus_empty(mask)) )
|
||||
{
|
||||
perfc_incrc(need_flush_tlb_flush);
|
||||
perfc_incr(need_flush_tlb_flush);
|
||||
flush_tlb_mask(mask);
|
||||
}
|
||||
|
||||
|
||||
+90
-79
@@ -10,81 +10,98 @@
|
||||
#include <public/sysctl.h>
|
||||
#include <asm/perfc.h>
|
||||
|
||||
#undef PERFCOUNTER
|
||||
#undef PERFCOUNTER_CPU
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
#undef PERFSTATUS
|
||||
#undef PERFSTATUS_CPU
|
||||
#undef PERFSTATUS_ARRAY
|
||||
#define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
|
||||
#define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
|
||||
#define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
|
||||
#define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
|
||||
#define PERFSTATUS_CPU( var, name ) { name, TYPE_S_CPU, 0 },
|
||||
#define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
|
||||
static struct {
|
||||
char *name;
|
||||
enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
|
||||
TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
|
||||
static const struct {
|
||||
const char *name;
|
||||
enum { TYPE_SINGLE, TYPE_ARRAY,
|
||||
TYPE_S_SINGLE, TYPE_S_ARRAY
|
||||
} type;
|
||||
int nr_elements;
|
||||
unsigned int nr_elements;
|
||||
} perfc_info[] = {
|
||||
#include <xen/perfc_defn.h>
|
||||
};
|
||||
|
||||
#define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
|
||||
|
||||
struct perfcounter perfcounters;
|
||||
DEFINE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);
|
||||
|
||||
void perfc_printall(unsigned char key)
|
||||
{
|
||||
unsigned int i, j, sum;
|
||||
unsigned int i, j;
|
||||
s_time_t now = NOW();
|
||||
atomic_t *counters = (atomic_t *)&perfcounters;
|
||||
|
||||
printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
|
||||
(u32)(now>>32), (u32)now);
|
||||
|
||||
for ( i = 0; i < NR_PERFCTRS; i++ )
|
||||
for ( i = j = 0; i < NR_PERFCTRS; i++ )
|
||||
{
|
||||
unsigned int k, cpu;
|
||||
unsigned long long sum = 0;
|
||||
|
||||
printk("%-32s ", perfc_info[i].name);
|
||||
switch ( perfc_info[i].type )
|
||||
{
|
||||
case TYPE_SINGLE:
|
||||
case TYPE_S_SINGLE:
|
||||
printk("TOTAL[%10d]", atomic_read(&counters[0]));
|
||||
counters += 1;
|
||||
break;
|
||||
case TYPE_CPU:
|
||||
case TYPE_S_CPU:
|
||||
sum = 0;
|
||||
for_each_online_cpu ( j )
|
||||
sum += atomic_read(&counters[j]);
|
||||
printk("TOTAL[%10u]", sum);
|
||||
if (sum)
|
||||
for_each_online_cpu ( cpu )
|
||||
sum += per_cpu(perfcounters, cpu)[j];
|
||||
printk("TOTAL[%12Lu]", sum);
|
||||
if ( sum )
|
||||
{
|
||||
for_each_online_cpu ( j )
|
||||
printk(" CPU%02d[%10d]", j, atomic_read(&counters[j]));
|
||||
k = 0;
|
||||
for_each_online_cpu ( cpu )
|
||||
{
|
||||
if ( k > 0 && (k % 4) == 0 )
|
||||
printk("\n%46s", "");
|
||||
printk(" CPU%02u[%10"PRIperfc"u]", cpu, per_cpu(perfcounters, cpu)[j]);
|
||||
++k;
|
||||
}
|
||||
}
|
||||
counters += NR_CPUS;
|
||||
++j;
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_S_ARRAY:
|
||||
for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
|
||||
sum += atomic_read(&counters[j]);
|
||||
printk("TOTAL[%10u]", sum);
|
||||
#ifdef PERF_ARRAYS
|
||||
for_each_online_cpu ( cpu )
|
||||
{
|
||||
perfc_t *counters = per_cpu(perfcounters, cpu) + j;
|
||||
|
||||
for ( k = 0; k < perfc_info[i].nr_elements; k++ )
|
||||
sum += counters[k];
|
||||
}
|
||||
printk("TOTAL[%12Lu]", sum);
|
||||
if (sum)
|
||||
{
|
||||
for ( j = 0; j < perfc_info[i].nr_elements; j++ )
|
||||
#ifdef PERF_ARRAYS
|
||||
for ( k = 0; k < perfc_info[i].nr_elements; k++ )
|
||||
{
|
||||
if ( (j % 4) == 0 )
|
||||
printk("\n ");
|
||||
printk(" ARR%02d[%10d]", j, atomic_read(&counters[j]));
|
||||
sum = 0;
|
||||
for_each_online_cpu ( cpu )
|
||||
sum += per_cpu(perfcounters, cpu)[j + k];
|
||||
if ( (k % 4) == 0 )
|
||||
printk("\n%16s", "");
|
||||
printk(" ARR%02u[%10Lu]", k, sum);
|
||||
}
|
||||
#else
|
||||
k = 0;
|
||||
for_each_online_cpu ( cpu )
|
||||
{
|
||||
perfc_t *counters = per_cpu(perfcounters, cpu) + j;
|
||||
unsigned int n;
|
||||
|
||||
sum = 0;
|
||||
for ( n = 0; n < perfc_info[i].nr_elements; n++ )
|
||||
sum += counters[n];
|
||||
if ( k > 0 && (k % 4) == 0 )
|
||||
printk("\n%46s", "");
|
||||
printk(" CPU%02u[%10Lu]", cpu, sum);
|
||||
++k;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
counters += j;
|
||||
}
|
||||
j += perfc_info[i].nr_elements;
|
||||
break;
|
||||
}
|
||||
printk("\n");
|
||||
@@ -97,7 +114,6 @@ void perfc_reset(unsigned char key)
|
||||
{
|
||||
unsigned int i, j;
|
||||
s_time_t now = NOW();
|
||||
atomic_t *counters = (atomic_t *)&perfcounters;
|
||||
|
||||
if ( key != '\0' )
|
||||
printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
|
||||
@@ -105,43 +121,39 @@ void perfc_reset(unsigned char key)
|
||||
|
||||
/* leave STATUS counters alone -- don't reset */
|
||||
|
||||
for ( i = 0; i < NR_PERFCTRS; i++ )
|
||||
for ( i = j = 0; i < NR_PERFCTRS; i++ )
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
switch ( perfc_info[i].type )
|
||||
{
|
||||
case TYPE_SINGLE:
|
||||
atomic_set(&counters[0],0);
|
||||
for_each_cpu ( cpu )
|
||||
per_cpu(perfcounters, cpu)[j] = 0;
|
||||
case TYPE_S_SINGLE:
|
||||
counters += 1;
|
||||
break;
|
||||
case TYPE_CPU:
|
||||
for ( j = 0; j < NR_CPUS; j++ )
|
||||
atomic_set(&counters[j],0);
|
||||
case TYPE_S_CPU:
|
||||
counters += NR_CPUS;
|
||||
++j;
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
for ( j = 0; j < perfc_info[i].nr_elements; j++ )
|
||||
atomic_set(&counters[j],0);
|
||||
for_each_cpu ( cpu )
|
||||
memset(per_cpu(perfcounters, cpu) + j, 0,
|
||||
perfc_info[i].nr_elements * sizeof(perfc_t));
|
||||
case TYPE_S_ARRAY:
|
||||
counters += perfc_info[i].nr_elements;
|
||||
j += perfc_info[i].nr_elements;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
arch_perfc_reset ();
|
||||
arch_perfc_reset();
|
||||
}
|
||||
|
||||
static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
|
||||
static xen_sysctl_perfc_val_t *perfc_vals;
|
||||
static int perfc_nbr_vals;
|
||||
static unsigned int perfc_nbr_vals;
|
||||
static int perfc_init = 0;
|
||||
static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
|
||||
XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int v = 0;
|
||||
atomic_t *counters = (atomic_t *)&perfcounters;
|
||||
unsigned int i, j, v;
|
||||
|
||||
/* We only copy the name and array-size information once. */
|
||||
if ( !perfc_init )
|
||||
@@ -154,11 +166,7 @@ static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
|
||||
{
|
||||
case TYPE_SINGLE:
|
||||
case TYPE_S_SINGLE:
|
||||
perfc_d[i].nr_vals = 1;
|
||||
break;
|
||||
case TYPE_CPU:
|
||||
case TYPE_S_CPU:
|
||||
perfc_d[i].nr_vals = num_online_cpus();
|
||||
perfc_d[i].nr_vals = num_possible_cpus();
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_S_ARRAY:
|
||||
@@ -181,26 +189,31 @@ static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
|
||||
arch_perfc_gather();
|
||||
|
||||
/* We gather the counts together every time. */
|
||||
for ( i = 0; i < NR_PERFCTRS; i++ )
|
||||
for ( i = j = v = 0; i < NR_PERFCTRS; i++ )
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
switch ( perfc_info[i].type )
|
||||
{
|
||||
case TYPE_SINGLE:
|
||||
case TYPE_S_SINGLE:
|
||||
perfc_vals[v++] = atomic_read(&counters[0]);
|
||||
counters += 1;
|
||||
break;
|
||||
case TYPE_CPU:
|
||||
case TYPE_S_CPU:
|
||||
for ( j = 0; j < perfc_d[i].nr_vals; j++ )
|
||||
perfc_vals[v++] = atomic_read(&counters[j]);
|
||||
counters += NR_CPUS;
|
||||
for_each_cpu ( cpu )
|
||||
perfc_vals[v++] = per_cpu(perfcounters, cpu)[j];
|
||||
++j;
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_S_ARRAY:
|
||||
for ( j = 0; j < perfc_d[i].nr_vals; j++ )
|
||||
perfc_vals[v++] = atomic_read(&counters[j]);
|
||||
counters += perfc_info[i].nr_elements;
|
||||
memset(perfc_vals + v, 0, perfc_d[i].nr_vals * sizeof(*perfc_vals));
|
||||
for_each_cpu ( cpu )
|
||||
{
|
||||
perfc_t *counters = per_cpu(perfcounters, cpu) + j;
|
||||
unsigned int k;
|
||||
|
||||
for ( k = 0; k < perfc_d[i].nr_vals; k++ )
|
||||
perfc_vals[v + k] += counters[k];
|
||||
}
|
||||
v += perfc_d[i].nr_vals;
|
||||
j += perfc_info[i].nr_elements;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -224,14 +237,12 @@ int perfc_control(xen_sysctl_perfc_op_t *pc)
|
||||
switch ( pc->cmd )
|
||||
{
|
||||
case XEN_SYSCTL_PERFCOP_reset:
|
||||
perfc_copy_info(pc->desc, pc->val);
|
||||
rc = perfc_copy_info(pc->desc, pc->val);
|
||||
perfc_reset(0);
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
case XEN_SYSCTL_PERFCOP_query:
|
||||
perfc_copy_info(pc->desc, pc->val);
|
||||
rc = 0;
|
||||
rc = perfc_copy_info(pc->desc, pc->val);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -606,7 +606,7 @@ static void schedule(void)
|
||||
ASSERT(!in_irq());
|
||||
ASSERT(this_cpu(mc_state).flags == 0);
|
||||
|
||||
perfc_incrc(sched_run);
|
||||
perfc_incr(sched_run);
|
||||
|
||||
sd = &this_cpu(schedule_data);
|
||||
|
||||
@@ -654,16 +654,13 @@ static void schedule(void)
|
||||
|
||||
spin_unlock_irq(&sd->schedule_lock);
|
||||
|
||||
perfc_incrc(sched_ctx);
|
||||
perfc_incr(sched_ctx);
|
||||
|
||||
stop_timer(&prev->periodic_timer);
|
||||
|
||||
/* Ensure that the domain has an up-to-date time base. */
|
||||
if ( !is_idle_vcpu(next) )
|
||||
{
|
||||
update_vcpu_system_time(next);
|
||||
vcpu_periodic_timer_work(next);
|
||||
}
|
||||
update_vcpu_system_time(next);
|
||||
vcpu_periodic_timer_work(next);
|
||||
|
||||
TRACE_4D(TRC_SCHED_SWITCH,
|
||||
prev->domain->domain_id, prev->vcpu_id,
|
||||
@@ -684,7 +681,7 @@ void context_saved(struct vcpu *prev)
|
||||
static void s_timer_fn(void *unused)
|
||||
{
|
||||
raise_softirq(SCHEDULE_SOFTIRQ);
|
||||
perfc_incrc(sched_irq);
|
||||
perfc_incr(sched_irq);
|
||||
}
|
||||
|
||||
/* Per-VCPU periodic timer function: sends a virtual timer interrupt. */
|
||||
|
||||
@@ -900,12 +900,18 @@ void panic(const char *fmt, ...)
|
||||
void __bug(char *file, int line)
|
||||
{
|
||||
console_start_sync();
|
||||
printk("BUG at %s:%d\n", file, line);
|
||||
printk("Xen BUG at %s:%d\n", file, line);
|
||||
dump_execution_state();
|
||||
panic("BUG at %s:%d\n", file, line);
|
||||
panic("Xen BUG at %s:%d\n", file, line);
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
void __warn(char *file, int line)
|
||||
{
|
||||
printk("Xen WARN at %s:%d\n", file, line);
|
||||
dump_execution_state();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
#define __IA64_BUG_H__
|
||||
|
||||
#define BUG() __bug(__FILE__, __LINE__)
|
||||
#define WARN() __warn(__FILE__, __LINE__)
|
||||
|
||||
#endif /* __IA64_BUG_H__ */
|
||||
@@ -116,4 +116,8 @@ name:
|
||||
# define dv_serialize_instruction
|
||||
#endif
|
||||
|
||||
#ifdef PERF_COUNTERS
|
||||
#define PERFC(n) (THIS_CPU(perfcounters) + (IA64_PERFC_ ## n) * 4)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_IA64_ASMMACRO_H */
|
||||
@@ -123,13 +123,6 @@ static inline void list_move(struct list_head *list, struct list_head *head)
|
||||
|
||||
#define move_irq(x)
|
||||
|
||||
#define WARN_ON(condition) do { \
|
||||
if (unlikely((condition)!=0)) { \
|
||||
printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
|
||||
dump_stack(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef nop
|
||||
#undef nop
|
||||
#endif
|
||||
|
||||
+108
-106
@@ -1,34 +1,34 @@
|
||||
/* This file is legitimately included multiple times. */
|
||||
|
||||
PERFCOUNTER_CPU(dtlb_translate, "dtlb hit")
|
||||
PERFCOUNTER(dtlb_translate, "dtlb hit")
|
||||
|
||||
PERFCOUNTER_CPU(tr_translate, "TR hit")
|
||||
PERFCOUNTER(tr_translate, "TR hit")
|
||||
|
||||
PERFCOUNTER_CPU(vhpt_translate, "virtual vhpt translation")
|
||||
PERFCOUNTER_CPU(fast_vhpt_translate, "virtual vhpt fast translation")
|
||||
PERFCOUNTER(vhpt_translate, "virtual vhpt translation")
|
||||
PERFCOUNTER(fast_vhpt_translate, "virtual vhpt fast translation")
|
||||
|
||||
PERFCOUNTER(recover_to_page_fault, "recoveries to page fault")
|
||||
PERFCOUNTER(recover_to_break_fault, "recoveries to break fault")
|
||||
|
||||
PERFCOUNTER_CPU(phys_translate, "metaphysical translation")
|
||||
PERFCOUNTER(phys_translate, "metaphysical translation")
|
||||
|
||||
PERFCOUNTER_CPU(idle_when_pending, "vcpu idle at event")
|
||||
PERFCOUNTER(idle_when_pending, "vcpu idle at event")
|
||||
|
||||
PERFCOUNTER_CPU(pal_halt_light, "calls to pal_halt_light")
|
||||
PERFCOUNTER(pal_halt_light, "calls to pal_halt_light")
|
||||
|
||||
PERFCOUNTER_CPU(lazy_cover, "lazy cover")
|
||||
PERFCOUNTER(lazy_cover, "lazy cover")
|
||||
|
||||
PERFCOUNTER_CPU(mov_to_ar_imm, "privop mov_to_ar_imm")
|
||||
PERFCOUNTER_CPU(mov_to_ar_reg, "privop mov_to_ar_reg")
|
||||
PERFCOUNTER_CPU(mov_from_ar, "privop privified-mov_from_ar")
|
||||
PERFCOUNTER_CPU(ssm, "privop ssm")
|
||||
PERFCOUNTER_CPU(rsm, "privop rsm")
|
||||
PERFCOUNTER_CPU(rfi, "privop rfi")
|
||||
PERFCOUNTER_CPU(bsw0, "privop bsw0")
|
||||
PERFCOUNTER_CPU(bsw1, "privop bsw1")
|
||||
PERFCOUNTER_CPU(cover, "privop cover")
|
||||
PERFCOUNTER_CPU(fc, "privop privified-fc")
|
||||
PERFCOUNTER_CPU(cpuid, "privop privified-cpuid")
|
||||
PERFCOUNTER(mov_to_ar_imm, "privop mov_to_ar_imm")
|
||||
PERFCOUNTER(mov_to_ar_reg, "privop mov_to_ar_reg")
|
||||
PERFCOUNTER(mov_from_ar, "privop privified-mov_from_ar")
|
||||
PERFCOUNTER(ssm, "privop ssm")
|
||||
PERFCOUNTER(rsm, "privop rsm")
|
||||
PERFCOUNTER(rfi, "privop rfi")
|
||||
PERFCOUNTER(bsw0, "privop bsw0")
|
||||
PERFCOUNTER(bsw1, "privop bsw1")
|
||||
PERFCOUNTER(cover, "privop cover")
|
||||
PERFCOUNTER(fc, "privop privified-fc")
|
||||
PERFCOUNTER(cpuid, "privop privified-cpuid")
|
||||
|
||||
PERFCOUNTER_ARRAY(mov_to_cr, "privop mov to cr", 128)
|
||||
PERFCOUNTER_ARRAY(mov_from_cr, "privop mov from cr", 128)
|
||||
@@ -36,45 +36,45 @@ PERFCOUNTER_ARRAY(mov_from_cr, "privop mov from cr", 128)
|
||||
PERFCOUNTER_ARRAY(misc_privop, "privop misc", 64)
|
||||
|
||||
// privileged instructions to fall into vmx_entry
|
||||
PERFCOUNTER_CPU(vmx_rsm, "vmx privop rsm")
|
||||
PERFCOUNTER_CPU(vmx_ssm, "vmx privop ssm")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_psr, "vmx privop mov_to_psr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_psr, "vmx privop mov_from_psr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_cr, "vmx privop mov_from_cr")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_cr, "vmx privop mov_to_cr")
|
||||
PERFCOUNTER_CPU(vmx_bsw0, "vmx privop bsw0")
|
||||
PERFCOUNTER_CPU(vmx_bsw1, "vmx privop bsw1")
|
||||
PERFCOUNTER_CPU(vmx_cover, "vmx privop cover")
|
||||
PERFCOUNTER_CPU(vmx_rfi, "vmx privop rfi")
|
||||
PERFCOUNTER_CPU(vmx_itr_d, "vmx privop itr_d")
|
||||
PERFCOUNTER_CPU(vmx_itr_i, "vmx privop itr_i")
|
||||
PERFCOUNTER_CPU(vmx_ptr_d, "vmx privop ptr_d")
|
||||
PERFCOUNTER_CPU(vmx_ptr_i, "vmx privop ptr_i")
|
||||
PERFCOUNTER_CPU(vmx_itc_d, "vmx privop itc_d")
|
||||
PERFCOUNTER_CPU(vmx_itc_i, "vmx privop itc_i")
|
||||
PERFCOUNTER_CPU(vmx_ptc_l, "vmx privop ptc_l")
|
||||
PERFCOUNTER_CPU(vmx_ptc_g, "vmx privop ptc_g")
|
||||
PERFCOUNTER_CPU(vmx_ptc_ga, "vmx privop ptc_ga")
|
||||
PERFCOUNTER_CPU(vmx_ptc_e, "vmx privop ptc_e")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_rr, "vmx privop mov_to_rr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_rr, "vmx privop mov_from_rr")
|
||||
PERFCOUNTER_CPU(vmx_thash, "vmx privop thash")
|
||||
PERFCOUNTER_CPU(vmx_ttag, "vmx privop ttag")
|
||||
PERFCOUNTER_CPU(vmx_tpa, "vmx privop tpa")
|
||||
PERFCOUNTER_CPU(vmx_tak, "vmx privop tak")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_ar_imm, "vmx privop mov_to_ar_imm")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_ar_reg, "vmx privop mov_to_ar_reg")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_ar_reg, "vmx privop mov_from_ar_reg")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_dbr, "vmx privop mov_to_dbr")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_ibr, "vmx privop mov_to_ibr")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_pmc, "vmx privop mov_to_pmc")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_pmd, "vmx privop mov_to_pmd")
|
||||
PERFCOUNTER_CPU(vmx_mov_to_pkr, "vmx privop mov_to_pkr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_dbr, "vmx privop mov_from_dbr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_ibr, "vmx privop mov_from_ibr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_pmc, "vmx privop mov_from_pmc")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_pkr, "vmx privop mov_from_pkr")
|
||||
PERFCOUNTER_CPU(vmx_mov_from_cpuid, "vmx privop mov_from_cpuid")
|
||||
PERFCOUNTER(vmx_rsm, "vmx privop rsm")
|
||||
PERFCOUNTER(vmx_ssm, "vmx privop ssm")
|
||||
PERFCOUNTER(vmx_mov_to_psr, "vmx privop mov_to_psr")
|
||||
PERFCOUNTER(vmx_mov_from_psr, "vmx privop mov_from_psr")
|
||||
PERFCOUNTER(vmx_mov_from_cr, "vmx privop mov_from_cr")
|
||||
PERFCOUNTER(vmx_mov_to_cr, "vmx privop mov_to_cr")
|
||||
PERFCOUNTER(vmx_bsw0, "vmx privop bsw0")
|
||||
PERFCOUNTER(vmx_bsw1, "vmx privop bsw1")
|
||||
PERFCOUNTER(vmx_cover, "vmx privop cover")
|
||||
PERFCOUNTER(vmx_rfi, "vmx privop rfi")
|
||||
PERFCOUNTER(vmx_itr_d, "vmx privop itr_d")
|
||||
PERFCOUNTER(vmx_itr_i, "vmx privop itr_i")
|
||||
PERFCOUNTER(vmx_ptr_d, "vmx privop ptr_d")
|
||||
PERFCOUNTER(vmx_ptr_i, "vmx privop ptr_i")
|
||||
PERFCOUNTER(vmx_itc_d, "vmx privop itc_d")
|
||||
PERFCOUNTER(vmx_itc_i, "vmx privop itc_i")
|
||||
PERFCOUNTER(vmx_ptc_l, "vmx privop ptc_l")
|
||||
PERFCOUNTER(vmx_ptc_g, "vmx privop ptc_g")
|
||||
PERFCOUNTER(vmx_ptc_ga, "vmx privop ptc_ga")
|
||||
PERFCOUNTER(vmx_ptc_e, "vmx privop ptc_e")
|
||||
PERFCOUNTER(vmx_mov_to_rr, "vmx privop mov_to_rr")
|
||||
PERFCOUNTER(vmx_mov_from_rr, "vmx privop mov_from_rr")
|
||||
PERFCOUNTER(vmx_thash, "vmx privop thash")
|
||||
PERFCOUNTER(vmx_ttag, "vmx privop ttag")
|
||||
PERFCOUNTER(vmx_tpa, "vmx privop tpa")
|
||||
PERFCOUNTER(vmx_tak, "vmx privop tak")
|
||||
PERFCOUNTER(vmx_mov_to_ar_imm, "vmx privop mov_to_ar_imm")
|
||||
PERFCOUNTER(vmx_mov_to_ar_reg, "vmx privop mov_to_ar_reg")
|
||||
PERFCOUNTER(vmx_mov_from_ar_reg, "vmx privop mov_from_ar_reg")
|
||||
PERFCOUNTER(vmx_mov_to_dbr, "vmx privop mov_to_dbr")
|
||||
PERFCOUNTER(vmx_mov_to_ibr, "vmx privop mov_to_ibr")
|
||||
PERFCOUNTER(vmx_mov_to_pmc, "vmx privop mov_to_pmc")
|
||||
PERFCOUNTER(vmx_mov_to_pmd, "vmx privop mov_to_pmd")
|
||||
PERFCOUNTER(vmx_mov_to_pkr, "vmx privop mov_to_pkr")
|
||||
PERFCOUNTER(vmx_mov_from_dbr, "vmx privop mov_from_dbr")
|
||||
PERFCOUNTER(vmx_mov_from_ibr, "vmx privop mov_from_ibr")
|
||||
PERFCOUNTER(vmx_mov_from_pmc, "vmx privop mov_from_pmc")
|
||||
PERFCOUNTER(vmx_mov_from_pkr, "vmx privop mov_from_pkr")
|
||||
PERFCOUNTER(vmx_mov_from_cpuid, "vmx privop mov_from_cpuid")
|
||||
|
||||
|
||||
PERFCOUNTER_ARRAY(slow_hyperprivop, "slow hyperprivops", HYPERPRIVOP_MAX + 1)
|
||||
@@ -84,12 +84,12 @@ PERFCOUNTER_ARRAY(slow_reflect, "slow reflection", 0x80)
|
||||
PERFCOUNTER_ARRAY(fast_reflect, "fast reflection", 0x80)
|
||||
|
||||
PERFSTATUS(vhpt_nbr_entries, "nbr of entries per VHPT")
|
||||
PERFSTATUS_CPU(vhpt_valid_entries, "nbr of valid entries in VHPT")
|
||||
PERFSTATUS(vhpt_valid_entries, "nbr of valid entries in VHPT")
|
||||
|
||||
PERFCOUNTER_ARRAY(vmx_mmio_access, "vmx_mmio_access", 8)
|
||||
PERFCOUNTER_CPU(vmx_pal_emul, "vmx_pal_emul")
|
||||
PERFCOUNTER(vmx_pal_emul, "vmx_pal_emul")
|
||||
PERFCOUNTER_ARRAY(vmx_switch_mm_mode, "vmx_switch_mm_mode", 8)
|
||||
PERFCOUNTER_CPU(vmx_ia64_handle_break,"vmx_ia64_handle_break")
|
||||
PERFCOUNTER(vmx_ia64_handle_break,"vmx_ia64_handle_break")
|
||||
PERFCOUNTER_ARRAY(vmx_inject_guest_interruption,
|
||||
"vmx_inject_guest_interruption", 0x80)
|
||||
PERFCOUNTER_ARRAY(fw_hypercall, "fw_hypercall", 0x20)
|
||||
@@ -106,69 +106,71 @@ PERFSTATUS(privop_addr_##name##_overflow, "privop-addrs overflow " #name)
|
||||
|
||||
PERFPRIVOPADDR(get_ifa)
|
||||
PERFPRIVOPADDR(thash)
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
#endif
|
||||
|
||||
// vhpt.c
|
||||
PERFCOUNTER_CPU(local_vhpt_flush, "local_vhpt_flush")
|
||||
PERFCOUNTER_CPU(vcpu_vhpt_flush, "vcpu_vhpt_flush")
|
||||
PERFCOUNTER_CPU(vcpu_flush_vtlb_all, "vcpu_flush_vtlb_all")
|
||||
PERFCOUNTER_CPU(domain_flush_vtlb_all, "domain_flush_vtlb_all")
|
||||
PERFCOUNTER_CPU(vcpu_flush_tlb_vhpt_range, "vcpu_flush_tlb_vhpt_range")
|
||||
PERFCOUNTER_CPU(domain_flush_vtlb_track_entry, "domain_flush_vtlb_track_entry")
|
||||
PERFCOUNTER_CPU(domain_flush_vtlb_local, "domain_flush_vtlb_local")
|
||||
PERFCOUNTER_CPU(domain_flush_vtlb_global, "domain_flush_vtlb_global")
|
||||
PERFCOUNTER_CPU(domain_flush_vtlb_range, "domain_flush_vtlb_range")
|
||||
PERFCOUNTER(local_vhpt_flush, "local_vhpt_flush")
|
||||
PERFCOUNTER(vcpu_vhpt_flush, "vcpu_vhpt_flush")
|
||||
PERFCOUNTER(vcpu_flush_vtlb_all, "vcpu_flush_vtlb_all")
|
||||
PERFCOUNTER(domain_flush_vtlb_all, "domain_flush_vtlb_all")
|
||||
PERFCOUNTER(vcpu_flush_tlb_vhpt_range, "vcpu_flush_tlb_vhpt_range")
|
||||
PERFCOUNTER(domain_flush_vtlb_track_entry, "domain_flush_vtlb_track_entry")
|
||||
PERFCOUNTER(domain_flush_vtlb_local, "domain_flush_vtlb_local")
|
||||
PERFCOUNTER(domain_flush_vtlb_global, "domain_flush_vtlb_global")
|
||||
PERFCOUNTER(domain_flush_vtlb_range, "domain_flush_vtlb_range")
|
||||
|
||||
// domain.c
|
||||
PERFCOUNTER_CPU(flush_vtlb_for_context_switch, "flush_vtlb_for_context_switch")
|
||||
PERFCOUNTER(flush_vtlb_for_context_switch, "flush_vtlb_for_context_switch")
|
||||
|
||||
// mm.c
|
||||
PERFCOUNTER_CPU(assign_domain_page_replace, "assign_domain_page_replace")
|
||||
PERFCOUNTER_CPU(assign_domain_pge_cmpxchg_rel, "assign_domain_pge_cmpxchg_rel")
|
||||
PERFCOUNTER_CPU(zap_dcomain_page_one, "zap_dcomain_page_one")
|
||||
PERFCOUNTER_CPU(dom0vp_zap_physmap, "dom0vp_zap_physmap")
|
||||
PERFCOUNTER_CPU(dom0vp_add_physmap, "dom0vp_add_physmap")
|
||||
PERFCOUNTER_CPU(create_grant_host_mapping, "create_grant_host_mapping")
|
||||
PERFCOUNTER_CPU(destroy_grant_host_mapping, "destroy_grant_host_mapping")
|
||||
PERFCOUNTER_CPU(steal_page_refcount, "steal_page_refcount")
|
||||
PERFCOUNTER_CPU(steal_page, "steal_page")
|
||||
PERFCOUNTER_CPU(guest_physmap_add_page, "guest_physmap_add_page")
|
||||
PERFCOUNTER_CPU(guest_physmap_remove_page, "guest_physmap_remove_page")
|
||||
PERFCOUNTER_CPU(domain_page_flush_and_put, "domain_page_flush_and_put")
|
||||
PERFCOUNTER(assign_domain_page_replace, "assign_domain_page_replace")
|
||||
PERFCOUNTER(assign_domain_pge_cmpxchg_rel, "assign_domain_pge_cmpxchg_rel")
|
||||
PERFCOUNTER(zap_dcomain_page_one, "zap_dcomain_page_one")
|
||||
PERFCOUNTER(dom0vp_zap_physmap, "dom0vp_zap_physmap")
|
||||
PERFCOUNTER(dom0vp_add_physmap, "dom0vp_add_physmap")
|
||||
PERFCOUNTER(create_grant_host_mapping, "create_grant_host_mapping")
|
||||
PERFCOUNTER(destroy_grant_host_mapping, "destroy_grant_host_mapping")
|
||||
PERFCOUNTER(steal_page_refcount, "steal_page_refcount")
|
||||
PERFCOUNTER(steal_page, "steal_page")
|
||||
PERFCOUNTER(guest_physmap_add_page, "guest_physmap_add_page")
|
||||
PERFCOUNTER(guest_physmap_remove_page, "guest_physmap_remove_page")
|
||||
PERFCOUNTER(domain_page_flush_and_put, "domain_page_flush_and_put")
|
||||
|
||||
// dom0vp
|
||||
PERFCOUNTER_CPU(dom0vp_phystomach, "dom0vp_phystomach")
|
||||
PERFCOUNTER_CPU(dom0vp_machtophys, "dom0vp_machtophys")
|
||||
PERFCOUNTER(dom0vp_phystomach, "dom0vp_phystomach")
|
||||
PERFCOUNTER(dom0vp_machtophys, "dom0vp_machtophys")
|
||||
|
||||
#ifdef CONFIG_XEN_IA64_TLB_TRACK
|
||||
// insert or dirty
|
||||
PERFCOUNTER_CPU(tlb_track_iod, "tlb_track_iod")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_again, "tlb_track_iod_again")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_not_tracked, "tlb_track_iod_not_tracked")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_force_many, "tlb_track_iod_force_many")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_tracked_many, "tlb_track_iod_tracked_many")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_tracked_many_del, "tlb_track_iod_tracked_many_del")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_found, "tlb_track_iod_found")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_new_entry, "tlb_track_iod_new_entry")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_new_failed, "tlb_track_iod_new_failed")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_new_many, "tlb_track_iod_new_many")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_insert, "tlb_track_iod_insert")
|
||||
PERFCOUNTER_CPU(tlb_track_iod_dirtied, "tlb_track_iod_dirtied")
|
||||
PERFCOUNTER(tlb_track_iod, "tlb_track_iod")
|
||||
PERFCOUNTER(tlb_track_iod_again, "tlb_track_iod_again")
|
||||
PERFCOUNTER(tlb_track_iod_not_tracked, "tlb_track_iod_not_tracked")
|
||||
PERFCOUNTER(tlb_track_iod_force_many, "tlb_track_iod_force_many")
|
||||
PERFCOUNTER(tlb_track_iod_tracked_many, "tlb_track_iod_tracked_many")
|
||||
PERFCOUNTER(tlb_track_iod_tracked_many_del, "tlb_track_iod_tracked_many_del")
|
||||
PERFCOUNTER(tlb_track_iod_found, "tlb_track_iod_found")
|
||||
PERFCOUNTER(tlb_track_iod_new_entry, "tlb_track_iod_new_entry")
|
||||
PERFCOUNTER(tlb_track_iod_new_failed, "tlb_track_iod_new_failed")
|
||||
PERFCOUNTER(tlb_track_iod_new_many, "tlb_track_iod_new_many")
|
||||
PERFCOUNTER(tlb_track_iod_insert, "tlb_track_iod_insert")
|
||||
PERFCOUNTER(tlb_track_iod_dirtied, "tlb_track_iod_dirtied")
|
||||
|
||||
// search and remove
|
||||
PERFCOUNTER_CPU(tlb_track_sar, "tlb_track_sar")
|
||||
PERFCOUNTER_CPU(tlb_track_sar_not_tracked, "tlb_track_sar_not_tracked")
|
||||
PERFCOUNTER_CPU(tlb_track_sar_not_found, "tlb_track_sar_not_found")
|
||||
PERFCOUNTER_CPU(tlb_track_sar_found, "tlb_track_sar_found")
|
||||
PERFCOUNTER_CPU(tlb_track_sar_many, "tlb_track_sar_many")
|
||||
PERFCOUNTER(tlb_track_sar, "tlb_track_sar")
|
||||
PERFCOUNTER(tlb_track_sar_not_tracked, "tlb_track_sar_not_tracked")
|
||||
PERFCOUNTER(tlb_track_sar_not_found, "tlb_track_sar_not_found")
|
||||
PERFCOUNTER(tlb_track_sar_found, "tlb_track_sar_found")
|
||||
PERFCOUNTER(tlb_track_sar_many, "tlb_track_sar_many")
|
||||
|
||||
// flush
|
||||
PERFCOUNTER_CPU(tlb_track_use_rr7, "tlb_track_use_rr7")
|
||||
PERFCOUNTER_CPU(tlb_track_swap_rr0, "tlb_track_swap_rr0")
|
||||
PERFCOUNTER(tlb_track_use_rr7, "tlb_track_use_rr7")
|
||||
PERFCOUNTER(tlb_track_swap_rr0, "tlb_track_swap_rr0")
|
||||
#endif
|
||||
|
||||
// tlb flush clock
|
||||
#ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
|
||||
PERFCOUNTER_CPU(tlbflush_clock_cswitch_purge, "tlbflush_clock_cswitch_purge")
|
||||
PERFCOUNTER_CPU(tlbflush_clock_cswitch_skip, "tlbflush_clock_cswitch_skip")
|
||||
PERFCOUNTER(tlbflush_clock_cswitch_purge, "tlbflush_clock_cswitch_purge")
|
||||
PERFCOUNTER(tlbflush_clock_cswitch_skip, "tlbflush_clock_cswitch_skip")
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _XEN_UA64_PRIVOP_STAT_H
|
||||
#define _XEN_UA64_PRIVOP_STAT_H
|
||||
#ifndef _XEN_IA64_PRIVOP_STAT_H
|
||||
#define _XEN_IA64_PRIVOP_STAT_H
|
||||
#include <asm/config.h>
|
||||
#include <xen/types.h>
|
||||
#include <public/xen.h>
|
||||
@@ -9,31 +9,24 @@
|
||||
extern void gather_privop_addrs(void);
|
||||
extern void reset_privop_addrs(void);
|
||||
|
||||
#undef PERFCOUNTER
|
||||
#define PERFCOUNTER(var, name)
|
||||
|
||||
#undef PERFCOUNTER_CPU
|
||||
#define PERFCOUNTER_CPU(var, name)
|
||||
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
#define PERFCOUNTER_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFSTATUS
|
||||
#define PERFSTATUS(var, name)
|
||||
|
||||
#undef PERFSTATUS_CPU
|
||||
#define PERFSTATUS_CPU(var, name)
|
||||
|
||||
#undef PERFSTATUS_ARRAY
|
||||
#define PERFSTATUS_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
#define PERFPRIVOPADDR(name) privop_inst_##name,
|
||||
|
||||
enum privop_inst {
|
||||
#include <asm/perfc_defn.h>
|
||||
};
|
||||
|
||||
#undef PERFCOUNTER
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
|
||||
#undef PERFSTATUS
|
||||
#undef PERFSTATUS_ARRAY
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
|
||||
#define PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst)
|
||||
@@ -45,4 +38,4 @@ extern void privop_count_addr(unsigned long addr, enum privop_inst inst);
|
||||
#define reset_privop_addrs() do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _XEN_UA64_PRIVOP_STAT_H */
|
||||
#endif /* _XEN_IA64_PRIVOP_STAT_H */
|
||||
@@ -97,9 +97,9 @@ vcpu_tlb_track_insert_or_dirty(struct vcpu *vcpu, unsigned long vaddr,
|
||||
{
|
||||
/* optimization.
|
||||
non-tracking pte is most common. */
|
||||
perfc_incrc(tlb_track_iod);
|
||||
perfc_incr(tlb_track_iod);
|
||||
if (!pte_tlb_tracking(entry->used)) {
|
||||
perfc_incrc(tlb_track_iod_not_tracked);
|
||||
perfc_incr(tlb_track_iod_not_tracked);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
#define __POWERPC_BUG_H__
|
||||
|
||||
#define BUG() __bug(__FILE__, __LINE__)
|
||||
#define WARN() __warn(__FILE__, __LINE__)
|
||||
|
||||
#endif /* __POWERPC_BUG_H__ */
|
||||
@@ -67,10 +67,6 @@ static inline void unimplemented(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void __warn(char *file, int line);
|
||||
#define WARN() __warn(__FILE__, __LINE__)
|
||||
#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
|
||||
|
||||
extern void __attn(void);
|
||||
#define ATTN() __attn();
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ struct bug_frame {
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BUGFRAME_dump 0
|
||||
#define BUGFRAME_bug 1
|
||||
#define BUGFRAME_assert 2
|
||||
#define BUGFRAME_rsvd 3
|
||||
#define BUGFRAME_warn 1
|
||||
#define BUGFRAME_bug 2
|
||||
#define BUGFRAME_assert 3
|
||||
|
||||
#endif /* __X86_BUG_H__ */
|
||||
@@ -446,7 +446,6 @@ struct arch_svm_struct {
|
||||
u64 vmcb_pa;
|
||||
u32 *msrpm;
|
||||
u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
|
||||
int saved_irq_vector;
|
||||
int launch_core;
|
||||
|
||||
unsigned long flags; /* VMCB flags */
|
||||
|
||||
@@ -6,84 +6,94 @@
|
||||
#define __ASM_X86_MULTICALL_H__
|
||||
|
||||
#include <xen/errno.h>
|
||||
#include <asm/asm_defns.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define do_multicall_call(_call) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
" movq "STR(MULTICALL_op)"(%0),%%rax; " \
|
||||
" movq %c1(%0),%%rax; " \
|
||||
" leaq hypercall_table(%%rip),%%rdi; " \
|
||||
" cmpq $("STR(NR_hypercalls)"),%%rax; " \
|
||||
" jae 2f; " \
|
||||
" leaq hypercall_table(%%rip),%%rdi; " \
|
||||
" leaq (%%rdi,%%rax,8),%%rax; " \
|
||||
" movq "STR(MULTICALL_arg0)"(%0),%%rdi; " \
|
||||
" movq "STR(MULTICALL_arg1)"(%0),%%rsi; " \
|
||||
" movq "STR(MULTICALL_arg2)"(%0),%%rdx; " \
|
||||
" movq "STR(MULTICALL_arg3)"(%0),%%rcx; " \
|
||||
" movq "STR(MULTICALL_arg4)"(%0),%%r8; " \
|
||||
" callq *(%%rax); " \
|
||||
"1: movq %%rax,"STR(MULTICALL_result)"(%0)\n" \
|
||||
" movq (%%rdi,%%rax,8),%%rax; " \
|
||||
" movq %c2+0*%c3(%0),%%rdi; " \
|
||||
" movq %c2+1*%c3(%0),%%rsi; " \
|
||||
" movq %c2+2*%c3(%0),%%rdx; " \
|
||||
" movq %c2+3*%c3(%0),%%rcx; " \
|
||||
" movq %c2+4*%c3(%0),%%r8; " \
|
||||
" callq *%%rax; " \
|
||||
"1: movq %%rax,%c4(%0)\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"2: movq $-"STR(ENOSYS)",%%rax\n" \
|
||||
" jmp 1b\n" \
|
||||
".previous\n" \
|
||||
: : "b" (_call) \
|
||||
: \
|
||||
: "b" (_call), \
|
||||
"i" (offsetof(__typeof__(*_call), op)), \
|
||||
"i" (offsetof(__typeof__(*_call), args)), \
|
||||
"i" (sizeof(*(_call)->args)), \
|
||||
"i" (offsetof(__typeof__(*_call), result)) \
|
||||
/* all the caller-saves registers */ \
|
||||
: "rax", "rcx", "rdx", "rsi", "rdi", \
|
||||
"r8", "r9", "r10", "r11" ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define compat_multicall_call(_call) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
" movl "STR(COMPAT_MULTICALL_op)"(%0),%%eax; " \
|
||||
" leaq compat_hypercall_table(%%rip),%%rdi; " \
|
||||
" cmpl $("STR(NR_hypercalls)"),%%eax; " \
|
||||
" jae 2f; " \
|
||||
" movq (%%rdi,%%rax,8),%%rax; " \
|
||||
" movl "STR(COMPAT_MULTICALL_arg0)"(%0),%%edi; " \
|
||||
" movl "STR(COMPAT_MULTICALL_arg1)"(%0),%%esi; " \
|
||||
" movl "STR(COMPAT_MULTICALL_arg2)"(%0),%%edx; " \
|
||||
" movl "STR(COMPAT_MULTICALL_arg3)"(%0),%%ecx; " \
|
||||
" movl "STR(COMPAT_MULTICALL_arg4)"(%0),%%r8d; " \
|
||||
" callq *%%rax; " \
|
||||
"1: movl %%eax,"STR(COMPAT_MULTICALL_result)"(%0)\n"\
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"2: movl $-"STR(ENOSYS)",%%eax\n" \
|
||||
" jmp 1b\n" \
|
||||
".previous\n" \
|
||||
: : "b" (_call) \
|
||||
/* all the caller-saves registers */ \
|
||||
: "rax", "rcx", "rdx", "rsi", "rdi", \
|
||||
"r8", "r9", "r10", "r11" ); \
|
||||
} while ( 0 )
|
||||
#define compat_multicall_call(_call) \
|
||||
__asm__ __volatile__ ( \
|
||||
" movl %c1(%0),%%eax; " \
|
||||
" leaq compat_hypercall_table(%%rip),%%rdi; "\
|
||||
" cmpl $("STR(NR_hypercalls)"),%%eax; " \
|
||||
" jae 2f; " \
|
||||
" movq (%%rdi,%%rax,8),%%rax; " \
|
||||
" movl %c2+0*%c3(%0),%%edi; " \
|
||||
" movl %c2+1*%c3(%0),%%esi; " \
|
||||
" movl %c2+2*%c3(%0),%%edx; " \
|
||||
" movl %c2+3*%c3(%0),%%ecx; " \
|
||||
" movl %c2+4*%c3(%0),%%r8d; " \
|
||||
" callq *%%rax; " \
|
||||
"1: movl %%eax,%c4(%0)\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"2: movl $-"STR(ENOSYS)",%%eax\n" \
|
||||
" jmp 1b\n" \
|
||||
".previous\n" \
|
||||
: \
|
||||
: "b" (_call), \
|
||||
"i" (offsetof(__typeof__(*_call), op)), \
|
||||
"i" (offsetof(__typeof__(*_call), args)), \
|
||||
"i" (sizeof(*(_call)->args)), \
|
||||
"i" (offsetof(__typeof__(*_call), result)) \
|
||||
/* all the caller-saves registers */ \
|
||||
: "rax", "rcx", "rdx", "rsi", "rdi", \
|
||||
"r8", "r9", "r10", "r11" ) \
|
||||
|
||||
#else
|
||||
|
||||
#define do_multicall_call(_call) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
" pushl "STR(MULTICALL_arg4)"(%0); " \
|
||||
" pushl "STR(MULTICALL_arg3)"(%0); " \
|
||||
" pushl "STR(MULTICALL_arg2)"(%0); " \
|
||||
" pushl "STR(MULTICALL_arg1)"(%0); " \
|
||||
" pushl "STR(MULTICALL_arg0)"(%0); " \
|
||||
" movl "STR(MULTICALL_op)"(%0),%%eax; " \
|
||||
" movl %c1(%0),%%eax; " \
|
||||
" pushl %c2+4*%c3(%0); " \
|
||||
" pushl %c2+3*%c3(%0); " \
|
||||
" pushl %c2+2*%c3(%0); " \
|
||||
" pushl %c2+1*%c3(%0); " \
|
||||
" pushl %c2+0*%c3(%0); " \
|
||||
" cmpl $("STR(NR_hypercalls)"),%%eax; " \
|
||||
" jae 2f; " \
|
||||
" call *hypercall_table(,%%eax,4); " \
|
||||
"1: movl %%eax,"STR(MULTICALL_result)"(%0); " \
|
||||
"1: movl %%eax,%c4(%0); " \
|
||||
" addl $20,%%esp\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"2: movl $-"STR(ENOSYS)",%%eax\n" \
|
||||
" jmp 1b\n" \
|
||||
".previous\n" \
|
||||
: : "b" (_call) \
|
||||
: \
|
||||
: "bSD" (_call), \
|
||||
"i" (offsetof(__typeof__(*_call), op)), \
|
||||
"i" (offsetof(__typeof__(*_call), args)), \
|
||||
"i" (sizeof(*(_call)->args)), \
|
||||
"i" (offsetof(__typeof__(*_call), result)) \
|
||||
/* all the caller-saves registers */ \
|
||||
: "eax", "ecx", "edx" ); \
|
||||
} while ( 0 )
|
||||
: "eax", "ecx", "edx" ) \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,81 +12,83 @@ PERFCOUNTER_ARRAY(cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE)
|
||||
#define SVM_PERF_EXIT_REASON_SIZE (1+136)
|
||||
PERFCOUNTER_ARRAY(svmexits, "SVMexits", SVM_PERF_EXIT_REASON_SIZE)
|
||||
|
||||
PERFCOUNTER_CPU(seg_fixups, "segmentation fixups")
|
||||
PERFCOUNTER(seg_fixups, "segmentation fixups")
|
||||
|
||||
PERFCOUNTER_CPU(apic_timer, "apic timer interrupts")
|
||||
PERFCOUNTER(apic_timer, "apic timer interrupts")
|
||||
|
||||
PERFCOUNTER_CPU(domain_page_tlb_flush, "domain page tlb flushes")
|
||||
PERFCOUNTER(domain_page_tlb_flush, "domain page tlb flushes")
|
||||
|
||||
PERFCOUNTER_CPU(calls_to_mmu_update, "calls_to_mmu_update")
|
||||
PERFCOUNTER_CPU(num_page_updates, "num_page_updates")
|
||||
PERFCOUNTER_CPU(calls_to_update_va, "calls_to_update_va_map")
|
||||
PERFCOUNTER_CPU(page_faults, "page faults")
|
||||
PERFCOUNTER_CPU(copy_user_faults, "copy_user faults")
|
||||
PERFCOUNTER(calls_to_mmuext_op, "calls to mmuext_op")
|
||||
PERFCOUNTER(num_mmuext_ops, "mmuext ops")
|
||||
PERFCOUNTER(calls_to_mmu_update, "calls to mmu_update")
|
||||
PERFCOUNTER(num_page_updates, "page updates")
|
||||
PERFCOUNTER(calls_to_update_va, "calls to update_va_map")
|
||||
PERFCOUNTER(page_faults, "page faults")
|
||||
PERFCOUNTER(copy_user_faults, "copy_user faults")
|
||||
|
||||
PERFCOUNTER_CPU(map_domain_page_count, "map_domain_page count")
|
||||
PERFCOUNTER_CPU(ptwr_emulations, "writable pt emulations")
|
||||
PERFCOUNTER(map_domain_page_count, "map_domain_page count")
|
||||
PERFCOUNTER(ptwr_emulations, "writable pt emulations")
|
||||
|
||||
PERFCOUNTER_CPU(exception_fixed, "pre-exception fixed")
|
||||
PERFCOUNTER(exception_fixed, "pre-exception fixed")
|
||||
|
||||
|
||||
/* Shadow counters */
|
||||
PERFCOUNTER_CPU(shadow_alloc, "calls to shadow_alloc")
|
||||
PERFCOUNTER_CPU(shadow_alloc_tlbflush, "shadow_alloc flushed TLBs")
|
||||
PERFCOUNTER(shadow_alloc, "calls to shadow_alloc")
|
||||
PERFCOUNTER(shadow_alloc_tlbflush, "shadow_alloc flushed TLBs")
|
||||
|
||||
/* STATUS counters do not reset when 'P' is hit */
|
||||
PERFSTATUS(shadow_alloc_count, "number of shadow pages in use")
|
||||
PERFCOUNTER_CPU(shadow_free, "calls to shadow_free")
|
||||
PERFCOUNTER_CPU(shadow_prealloc_1, "shadow recycles old shadows")
|
||||
PERFCOUNTER_CPU(shadow_prealloc_2, "shadow recycles in-use shadows")
|
||||
PERFCOUNTER_CPU(shadow_linear_map_failed, "shadow hit read-only linear map")
|
||||
PERFCOUNTER_CPU(shadow_a_update, "shadow A bit update")
|
||||
PERFCOUNTER_CPU(shadow_ad_update, "shadow A&D bit update")
|
||||
PERFCOUNTER_CPU(shadow_fault, "calls to shadow_fault")
|
||||
PERFCOUNTER_CPU(shadow_fault_fast_gnp, "shadow_fault fast path n/p")
|
||||
PERFCOUNTER_CPU(shadow_fault_fast_mmio, "shadow_fault fast path mmio")
|
||||
PERFCOUNTER_CPU(shadow_fault_fast_fail, "shadow_fault fast path error")
|
||||
PERFCOUNTER_CPU(shadow_fault_bail_bad_gfn, "shadow_fault guest bad gfn")
|
||||
PERFCOUNTER_CPU(shadow_fault_bail_not_present,
|
||||
PERFCOUNTER(shadow_free, "calls to shadow_free")
|
||||
PERFCOUNTER(shadow_prealloc_1, "shadow recycles old shadows")
|
||||
PERFCOUNTER(shadow_prealloc_2, "shadow recycles in-use shadows")
|
||||
PERFCOUNTER(shadow_linear_map_failed, "shadow hit read-only linear map")
|
||||
PERFCOUNTER(shadow_a_update, "shadow A bit update")
|
||||
PERFCOUNTER(shadow_ad_update, "shadow A&D bit update")
|
||||
PERFCOUNTER(shadow_fault, "calls to shadow_fault")
|
||||
PERFCOUNTER(shadow_fault_fast_gnp, "shadow_fault fast path n/p")
|
||||
PERFCOUNTER(shadow_fault_fast_mmio, "shadow_fault fast path mmio")
|
||||
PERFCOUNTER(shadow_fault_fast_fail, "shadow_fault fast path error")
|
||||
PERFCOUNTER(shadow_fault_bail_bad_gfn, "shadow_fault guest bad gfn")
|
||||
PERFCOUNTER(shadow_fault_bail_not_present,
|
||||
"shadow_fault guest not-present")
|
||||
PERFCOUNTER_CPU(shadow_fault_bail_nx, "shadow_fault guest NX fault")
|
||||
PERFCOUNTER_CPU(shadow_fault_bail_ro_mapping, "shadow_fault guest R/W fault")
|
||||
PERFCOUNTER_CPU(shadow_fault_bail_user_supervisor,
|
||||
PERFCOUNTER(shadow_fault_bail_nx, "shadow_fault guest NX fault")
|
||||
PERFCOUNTER(shadow_fault_bail_ro_mapping, "shadow_fault guest R/W fault")
|
||||
PERFCOUNTER(shadow_fault_bail_user_supervisor,
|
||||
"shadow_fault guest U/S fault")
|
||||
PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
|
||||
PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
|
||||
PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
|
||||
PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
|
||||
PERFCOUNTER_CPU(shadow_fault_mmio, "shadow_fault handled as mmio")
|
||||
PERFCOUNTER_CPU(shadow_fault_fixed, "shadow_fault fixed fault")
|
||||
PERFCOUNTER_CPU(shadow_ptwr_emulate, "shadow causes ptwr to emulate")
|
||||
PERFCOUNTER_CPU(shadow_validate_gl1e_calls, "calls to shadow_validate_gl1e")
|
||||
PERFCOUNTER_CPU(shadow_validate_gl2e_calls, "calls to shadow_validate_gl2e")
|
||||
PERFCOUNTER_CPU(shadow_validate_gl3e_calls, "calls to shadow_validate_gl3e")
|
||||
PERFCOUNTER_CPU(shadow_validate_gl4e_calls, "calls to shadow_validate_gl4e")
|
||||
PERFCOUNTER_CPU(shadow_hash_lookups, "calls to shadow_hash_lookup")
|
||||
PERFCOUNTER_CPU(shadow_hash_lookup_head, "shadow hash hit in bucket head")
|
||||
PERFCOUNTER_CPU(shadow_hash_lookup_miss, "shadow hash misses")
|
||||
PERFCOUNTER_CPU(shadow_get_shadow_status, "calls to get_shadow_status")
|
||||
PERFCOUNTER_CPU(shadow_hash_inserts, "calls to shadow_hash_insert")
|
||||
PERFCOUNTER_CPU(shadow_hash_deletes, "calls to shadow_hash_delete")
|
||||
PERFCOUNTER_CPU(shadow_writeable, "shadow removes write access")
|
||||
PERFCOUNTER_CPU(shadow_writeable_h_1, "shadow writeable: 32b w2k3")
|
||||
PERFCOUNTER_CPU(shadow_writeable_h_2, "shadow writeable: 32pae w2k3")
|
||||
PERFCOUNTER_CPU(shadow_writeable_h_3, "shadow writeable: 64b w2k3")
|
||||
PERFCOUNTER_CPU(shadow_writeable_h_4, "shadow writeable: 32b linux low")
|
||||
PERFCOUNTER_CPU(shadow_writeable_h_5, "shadow writeable: 32b linux high")
|
||||
PERFCOUNTER_CPU(shadow_writeable_bf, "shadow writeable brute-force")
|
||||
PERFCOUNTER_CPU(shadow_mappings, "shadow removes all mappings")
|
||||
PERFCOUNTER_CPU(shadow_mappings_bf, "shadow rm-mappings brute-force")
|
||||
PERFCOUNTER_CPU(shadow_early_unshadow, "shadow unshadows for fork/exit")
|
||||
PERFCOUNTER_CPU(shadow_unshadow, "shadow unshadows a page")
|
||||
PERFCOUNTER_CPU(shadow_up_pointer, "shadow unshadow by up-pointer")
|
||||
PERFCOUNTER_CPU(shadow_unshadow_bf, "shadow unshadow brute-force")
|
||||
PERFCOUNTER_CPU(shadow_get_page_fail, "shadow_get_page_from_l1e failed")
|
||||
PERFCOUNTER_CPU(shadow_guest_walk, "shadow walks guest tables")
|
||||
PERFCOUNTER_CPU(shadow_invlpg, "shadow emulates invlpg")
|
||||
PERFCOUNTER_CPU(shadow_invlpg_fault, "shadow invlpg faults")
|
||||
PERFCOUNTER(shadow_fault_emulate_read, "shadow_fault emulates a read")
|
||||
PERFCOUNTER(shadow_fault_emulate_write, "shadow_fault emulates a write")
|
||||
PERFCOUNTER(shadow_fault_emulate_failed, "shadow_fault emulator fails")
|
||||
PERFCOUNTER(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
|
||||
PERFCOUNTER(shadow_fault_mmio, "shadow_fault handled as mmio")
|
||||
PERFCOUNTER(shadow_fault_fixed, "shadow_fault fixed fault")
|
||||
PERFCOUNTER(shadow_ptwr_emulate, "shadow causes ptwr to emulate")
|
||||
PERFCOUNTER(shadow_validate_gl1e_calls, "calls to shadow_validate_gl1e")
|
||||
PERFCOUNTER(shadow_validate_gl2e_calls, "calls to shadow_validate_gl2e")
|
||||
PERFCOUNTER(shadow_validate_gl3e_calls, "calls to shadow_validate_gl3e")
|
||||
PERFCOUNTER(shadow_validate_gl4e_calls, "calls to shadow_validate_gl4e")
|
||||
PERFCOUNTER(shadow_hash_lookups, "calls to shadow_hash_lookup")
|
||||
PERFCOUNTER(shadow_hash_lookup_head, "shadow hash hit in bucket head")
|
||||
PERFCOUNTER(shadow_hash_lookup_miss, "shadow hash misses")
|
||||
PERFCOUNTER(shadow_get_shadow_status, "calls to get_shadow_status")
|
||||
PERFCOUNTER(shadow_hash_inserts, "calls to shadow_hash_insert")
|
||||
PERFCOUNTER(shadow_hash_deletes, "calls to shadow_hash_delete")
|
||||
PERFCOUNTER(shadow_writeable, "shadow removes write access")
|
||||
PERFCOUNTER(shadow_writeable_h_1, "shadow writeable: 32b w2k3")
|
||||
PERFCOUNTER(shadow_writeable_h_2, "shadow writeable: 32pae w2k3")
|
||||
PERFCOUNTER(shadow_writeable_h_3, "shadow writeable: 64b w2k3")
|
||||
PERFCOUNTER(shadow_writeable_h_4, "shadow writeable: 32b linux low")
|
||||
PERFCOUNTER(shadow_writeable_h_5, "shadow writeable: 32b linux high")
|
||||
PERFCOUNTER(shadow_writeable_bf, "shadow writeable brute-force")
|
||||
PERFCOUNTER(shadow_mappings, "shadow removes all mappings")
|
||||
PERFCOUNTER(shadow_mappings_bf, "shadow rm-mappings brute-force")
|
||||
PERFCOUNTER(shadow_early_unshadow, "shadow unshadows for fork/exit")
|
||||
PERFCOUNTER(shadow_unshadow, "shadow unshadows a page")
|
||||
PERFCOUNTER(shadow_up_pointer, "shadow unshadow by up-pointer")
|
||||
PERFCOUNTER(shadow_unshadow_bf, "shadow unshadow brute-force")
|
||||
PERFCOUNTER(shadow_get_page_fail, "shadow_get_page_from_l1e failed")
|
||||
PERFCOUNTER(shadow_guest_walk, "shadow walks guest tables")
|
||||
PERFCOUNTER(shadow_invlpg, "shadow emulates invlpg")
|
||||
PERFCOUNTER(shadow_invlpg_fault, "shadow invlpg faults")
|
||||
|
||||
|
||||
/*#endif*/ /* __XEN_PERFC_DEFN_H__ */
|
||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more