# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID b33c08de3d98c07d4d18b5b20c1046cf21b7c08f
# Parent aa1ab056bfbffc28c8f2f8c7142ceb076d9a784d
[HVM] Add a concept of HVM parameters to the hypervisor.
Each HVM domain has a space of HVM parameters associated with it,
and these can be manipulated via a new hvm_op hypercall. This means
that the hypervisor no longer needs to parse the hvm_info table, so
remove that code.
Signed-off-by: Steven Smith <ssmith@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 1
tools/libxc/xc_hvm_build.c | 32 +++++
xen/arch/x86/hvm/hvm.c | 120 ++++++++++-----------
xen/arch/x86/hvm/svm/svm.c | 4
xen/arch/x86/hvm/vlapic.c | 3
xen/arch/x86/hvm/vmx/vmx.c | 2
xen/arch/x86/x86_32/entry.S | 2
xen/arch/x86/x86_64/entry.S | 2
xen/include/asm-x86/hvm/domain.h | 8 -
xen/include/public/xen.h | 1
xen/include/xen/hypercall.h | 5
11 files changed, 114 insertions(+), 66 deletions(-)
diff -r aa1ab056bfbf -r b33c08de3d98
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Aug 02
17:42:38 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Aug 03
13:53:33 2006 +0100
@@ -270,6 +270,7 @@ static int __init privcmd_init(void)
set_bit(__HYPERVISOR_sched_op_compat, hypercall_permission_map);
set_bit(__HYPERVISOR_event_channel_op_compat,
hypercall_permission_map);
+ set_bit(__HYPERVISOR_hvm_op, hypercall_permission_map);
privcmd_intf = create_xen_proc_entry("privcmd", 0400);
if (privcmd_intf != NULL)
diff -r aa1ab056bfbf -r b33c08de3d98 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Wed Aug 02 17:42:38 2006 +0100
+++ b/tools/libxc/xc_hvm_build.c Thu Aug 03 13:53:33 2006 +0100
@@ -6,12 +6,14 @@
#include <stddef.h>
#include <inttypes.h>
#include "xg_private.h"
+#include "xc_private.h"
#include "xc_elf.h"
#include <stdlib.h>
#include <unistd.h>
#include <zlib.h>
#include <xen/hvm/hvm_info_table.h>
#include <xen/hvm/ioreq.h>
+#include <xen/hvm/params.h>
#define HVM_LOADER_ENTR_ADDR 0x00100000
@@ -43,6 +45,30 @@ loadelfimage(
char *elfbase, int xch, uint32_t dom, unsigned long *parray,
struct domain_setup_info *dsi);
+static void xc_set_hvm_param(int handle,
+ domid_t dom, int param, unsigned long value)
+{
+ DECLARE_HYPERCALL;
+ xen_hvm_param_t arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_set_param;
+ hypercall.arg[1] = (unsigned long)&arg;
+ arg.domid = dom;
+ arg.index = param;
+ arg.value = value;
+ if ( mlock(&arg, sizeof(arg)) != 0 )
+ {
+ PERROR("Could not lock memory for set parameter");
+ return;
+ }
+ rc = do_xen_hypercall(handle, &hypercall);
+ safe_munlock(&arg, sizeof(arg));
+ if (rc < 0)
+ PERROR("set HVM parameter failed (%d)", rc);
+}
+
static void build_e820map(void *e820_page, unsigned long long mem_size)
{
struct e820entry *e820entry =
@@ -153,6 +179,9 @@ static int set_hvm_info(int xc_handle, u
set_hvm_info_checksum(va_hvm);
munmap(va_map, PAGE_SIZE);
+
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_APIC_ENABLED, apic);
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
return 0;
}
@@ -286,6 +315,9 @@ static int setup_guest(int xc_handle,
}
munmap(sp, PAGE_SIZE);
+
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, (v_end >>
PAGE_SHIFT) - 2);
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
*store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c Thu Aug 03 13:53:33 2006 +0100
@@ -46,6 +46,7 @@
#include <public/sched.h>
#include <public/hvm/ioreq.h>
#include <public/hvm/hvm_info_table.h>
+#include <xen/guest_access.h>
int hvm_enabled = 0;
@@ -128,61 +129,6 @@ static void hvm_map_io_shared_page(struc
d->arch.hvm_domain.shared_page_va = (unsigned long)p;
}
-static int validate_hvm_info(struct hvm_info_table *t)
-{
- char signature[] = "HVM INFO";
- uint8_t *ptr = (uint8_t *)t;
- uint8_t sum = 0;
- int i;
-
- /* strncmp(t->signature, "HVM INFO", 8) */
- for ( i = 0; i < 8; i++ ) {
- if ( signature[i] != t->signature[i] ) {
- printk("Bad hvm info signature\n");
- return 0;
- }
- }
-
- for ( i = 0; i < t->length; i++ )
- sum += ptr[i];
-
- return (sum == 0);
-}
-
-static void hvm_get_info(struct domain *d)
-{
- unsigned char *p;
- unsigned long mfn;
- struct hvm_info_table *t;
-
- mfn = get_mfn_from_gpfn(HVM_INFO_PFN);
- if ( mfn == INVALID_MFN ) {
- printk("Can not get info page mfn for HVM domain.\n");
- domain_crash_synchronous();
- }
-
- p = map_domain_page(mfn);
- if ( p == NULL ) {
- printk("Can not map info page for HVM domain.\n");
- domain_crash_synchronous();
- }
-
- t = (struct hvm_info_table *)(p + HVM_INFO_OFFSET);
-
- if ( validate_hvm_info(t) ) {
- d->arch.hvm_domain.nr_vcpus = t->nr_vcpus;
- d->arch.hvm_domain.apic_enabled = t->apic_enabled;
- d->arch.hvm_domain.pae_enabled = t->pae_enabled;
- } else {
- printk("Bad hvm info table\n");
- d->arch.hvm_domain.nr_vcpus = 1;
- d->arch.hvm_domain.apic_enabled = 0;
- d->arch.hvm_domain.pae_enabled = 0;
- }
-
- unmap_domain_page(p);
-}
-
void hvm_setup_platform(struct domain* d)
{
struct hvm_domain *platform;
@@ -198,7 +144,6 @@ void hvm_setup_platform(struct domain* d
}
hvm_map_io_shared_page(d);
- hvm_get_info(d);
platform = &d->arch.hvm_domain;
pic_init(&platform->vpic, pic_irq_request, &platform->interrupt_request);
@@ -343,8 +288,8 @@ static hvm_hypercall_t *hvm_hypercall_ta
HYPERCALL(event_channel_op_compat),
HYPERCALL(xen_version),
HYPERCALL(grant_table_op),
- HYPERCALL(event_channel_op)
- /*HYPERCALL(hvm_op)*/
+ HYPERCALL(event_channel_op),
+ HYPERCALL(hvm_op)
};
#undef HYPERCALL
@@ -431,6 +376,65 @@ int hvm_bringup_ap(int vcpuid, int tramp
}
xfree(ctxt);
+
+ return rc;
+}
+
+long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
+
+{
+ long rc = 0;
+
+ switch ( op )
+ {
+ case HVMOP_set_param:
+ case HVMOP_get_param:
+ {
+ struct xen_hvm_param a;
+ struct domain *d;
+
+ if ( copy_from_guest(&a, arg, 1) )
+ return -EFAULT;
+
+ if ( a.index >= HVM_NR_PARAMS )
+ return -EINVAL;
+
+ if ( a.domid == DOMID_SELF )
+ {
+ get_knownalive_domain(current->domain);
+ d = current->domain;
+ }
+ else if ( IS_PRIV(current->domain) )
+ {
+ d = find_domain_by_id(a.domid);
+ if ( !d )
+ return -ESRCH;
+ }
+ else
+ {
+ return -EPERM;
+ }
+
+ if ( op == HVMOP_set_param )
+ {
+ rc = 0;
+ d->arch.hvm_domain.params[a.index] = a.value;
+ }
+ else
+ {
+ rc = d->arch.hvm_domain.params[a.index];
+ }
+
+ put_domain(d);
+ return rc;
+ }
+
+ default:
+ {
+ DPRINTK("Bad HVM op %ld.\n", op);
+ rc = -ENOSYS;
+ }
+ }
return rc;
}
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Thu Aug 03 13:53:33 2006 +0100
@@ -997,7 +997,7 @@ static void svm_vmexit_do_cpuid(struct v
#else
if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
{
- if ( !v->domain->arch.hvm_domain.pae_enabled )
+ if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
clear_bit(X86_FEATURE_PAE, &edx);
clear_bit(X86_FEATURE_PSE, &edx);
clear_bit(X86_FEATURE_PSE36, &edx);
@@ -1060,7 +1060,7 @@ static void svm_vmexit_do_cpuid(struct v
#else
if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
{
- if ( !v->domain->arch.hvm_domain.pae_enabled )
+ if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
{
clear_bit(X86_FEATURE_NX & 31, &edx);
clear_bit(X86_FEATURE_PAE, &edx);
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Thu Aug 03 13:53:33 2006 +0100
@@ -33,6 +33,7 @@
#include <xen/sched.h>
#include <asm/current.h>
#include <public/hvm/ioreq.h>
+#include <public/hvm/params.h>
/* XXX remove this definition after GFW enabled */
#define VLAPIC_NO_BIOS
@@ -57,7 +58,7 @@ static unsigned int vlapic_lvt_mask[VLAP
int hvm_apic_support(struct domain *d)
{
- return d->arch.hvm_domain.apic_enabled;
+ return d->arch.hvm_domain.params[HVM_PARAM_APIC_ENABLED];
}
int vlapic_find_highest_irr(struct vlapic *vlapic)
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Aug 03 13:53:33 2006 +0100
@@ -929,7 +929,7 @@ static void vmx_vmexit_do_cpuid(struct c
#else
if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
{
- if ( v->domain->arch.hvm_domain.pae_enabled )
+ if ( v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
clear_bit(X86_FEATURE_PSE36, &edx);
else
{
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/x86_32/entry.S Thu Aug 03 13:53:33 2006 +0100
@@ -656,6 +656,7 @@ ENTRY(hypercall_table)
.long do_xenoprof_op
.long do_event_channel_op
.long do_physdev_op
+ .long do_hvm_op /* 34 */
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -695,6 +696,7 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_xenoprof_op */
.byte 2 /* do_event_channel_op */
.byte 2 /* do_physdev_op */
+ .byte 2 /* do_hvm_op */ /* 34 */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r aa1ab056bfbf -r b33c08de3d98 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/arch/x86/x86_64/entry.S Thu Aug 03 13:53:33 2006 +0100
@@ -568,6 +568,7 @@ ENTRY(hypercall_table)
.quad do_xenoprof_op
.quad do_event_channel_op
.quad do_physdev_op
+ .quad do_hvm_op
.rept NR_hypercalls-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
@@ -607,6 +608,7 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_xenoprof_op */
.byte 2 /* do_event_channel_op */
.byte 2 /* do_physdev_op */
+ .byte 2 /* do_hvm_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r aa1ab056bfbf -r b33c08de3d98 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/include/asm-x86/hvm/domain.h Thu Aug 03 13:53:33 2006 +0100
@@ -27,17 +27,15 @@
#include <asm/hvm/vpit.h>
#include <asm/hvm/vlapic.h>
#include <asm/hvm/vioapic.h>
+#include <public/hvm/params.h>
#define HVM_PBUF_SIZE 80
struct hvm_domain {
unsigned long shared_page_va;
- unsigned int nr_vcpus;
- unsigned int apic_enabled;
- unsigned int pae_enabled;
s64 tsc_frequency;
struct pl_time pl_time;
-
+
struct hvm_virpic vpic;
struct hvm_vioapic vioapic;
struct hvm_io_handler io_handler;
@@ -48,6 +46,8 @@ struct hvm_domain {
int pbuf_index;
char pbuf[HVM_PBUF_SIZE];
+
+ uint64_t params[HVM_NR_PARAMS];
};
#endif /* __ASM_X86_HVM_DOMAIN_H__ */
diff -r aa1ab056bfbf -r b33c08de3d98 xen/include/public/xen.h
--- a/xen/include/public/xen.h Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/include/public/xen.h Thu Aug 03 13:53:33 2006 +0100
@@ -66,6 +66,7 @@
#define __HYPERVISOR_xenoprof_op 31
#define __HYPERVISOR_event_channel_op 32
#define __HYPERVISOR_physdev_op 33
+#define __HYPERVISOR_hvm_op 34
/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
diff -r aa1ab056bfbf -r b33c08de3d98 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Wed Aug 02 17:42:38 2006 +0100
+++ b/xen/include/xen/hypercall.h Thu Aug 03 13:53:33 2006 +0100
@@ -87,4 +87,9 @@ do_nmi_op(
unsigned int cmd,
XEN_GUEST_HANDLE(void) arg);
+extern long
+do_hvm_op(
+ unsigned long op,
+ XEN_GUEST_HANDLE(void) arg);
+
#endif /* __XEN_HYPERCALL_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|