* [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves
2014-04-21 21:57 [PATCH v8 0/3] Expose HW APIC virtualization support to HVM guests Boris Ostrovsky
@ 2014-04-21 21:57 ` Boris Ostrovsky
2014-04-22 9:45 ` Jan Beulich
2014-04-21 21:57 ` [PATCH v8 2/3] x86/hvm: Add HVM-specific hypervisor CPUID leaf Boris Ostrovsky
2014-04-21 21:57 ` [PATCH v8 3/3] x86/hvm: Indicate avaliability of HW support of APIC virtualization to HVM guests Boris Ostrovsky
2 siblings, 1 reply; 8+ messages in thread
From: Boris Ostrovsky @ 2014-04-21 21:57 UTC (permalink / raw)
To: jbeulich, ian.campbell, ian.jackson, stefano.stabellini,
eddie.dong, kevin.tian
Cc: yang.z.zhang, andrew.cooper3, boris.ostrovsky, xen-devel
Add support for changing max number of hypervisor leaves from configuration
file.
This number can be specified using xl's standard 'cpuid' option. Only lowest
8 bits of leaf's 0x4000xx00 eax register are processed, all others are ignored.
The changes allow us to revert commit 80ecb40362365ba77e68fc609de8bd3b7208ae19
which is most likely no longer needed now anyway (Solaris bug that it addressed
has been fixed and backported to earlier releases) but leave possibility of
running unpatched version of Solaris by forcing number of leaves to 2 in the
configuration file.
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
docs/man/xl.cfg.pod.5 | 8 ++++++--
tools/libxc/xc_cpuid_x86.c | 11 +++++++++++
tools/libxl/libxl_cpuid.c | 1 +
xen/arch/x86/traps.c | 16 +++++++++-------
xen/include/public/arch-x86/cpuid.h | 2 ++
5 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index a6663b9..3c557c8 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -873,9 +873,13 @@ Possible values for a single feature bit:
'k' -> pass through the host bit value
's' -> as 'k' but preserve across save/restore and migration (not implemented)
+Note: when specifying B<cpuid> for hypervisor leaves (0x4000xxxx major group)
+only the lowest 8 bits of leaf's 0x4000xx00 EAX register are processed, the rest
+are ignored (these 8 bits signify maximum number of hypervisor leaves).
+
List of keys taking a value:
-apicidsize brandid clflush family localapicid maxleaf model nc proccount procpkg
-stepping
+apicidsize brandid clflush family localapicid maxleaf maxhvleaf model nc
+proccount procpkg stepping
List of keys taking a character:
3dnow 3dnowext 3dnowprefetch abm acpi aes altmovcr8 apic avx clfsh cmov
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 9264039..f0aa31d 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -560,6 +560,17 @@ static int xc_cpuid_policy(
{
xc_dominfo_t info;
+ /*
+ * For hypervisor leaves (0x4000XXXX) only 0x4000xx00.EAX[7:0] bits (max
+ * number of leaves) can be set by user. Hypervisor will enforce this so
+ * all other bits are don't-care and we can set them to zero.
+ */
+ if ( (input[0] & 0xffff0000) == 0x40000000 )
+ {
+ regs[0] = regs[1] = regs[2] = regs[3] = 0;
+ return 0;
+ }
+
if ( xc_domain_getinfo(xch, domid, 1, &info) == 0 )
return -EINVAL;
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index dd21b78..d1ea50d 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -187,6 +187,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
{"svm_vmcbclean",0x8000000a, NA, CPUID_REG_EDX, 5, 1},
{"svm_decode", 0x8000000a, NA, CPUID_REG_EDX, 7, 1},
{"svm_pausefilt",0x8000000a, NA, CPUID_REG_EDX, 10, 1},
+ {"maxhvleaf", 0x40000000, NA, CPUID_REG_EAX, 0, 8},
{NULL, 0, NA, CPUID_REG_INV, 0, 0}
};
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index b7303d7..b2a35a3 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -677,15 +677,17 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
struct domain *d = current->domain;
/* Optionally shift out of the way of Viridian architectural leaves. */
uint32_t base = is_viridian_domain(d) ? 0x40000100 : 0x40000000;
- uint32_t limit;
+ uint32_t limit, dummy;
idx -= base;
-
- /*
- * Some Solaris PV drivers fail if max > base + 2. Help them out by
- * hiding the PVRDTSCP leaf if PVRDTSCP is disabled.
- */
- limit = (d->arch.tsc_mode < TSC_MODE_PVRDTSCP) ? 2 : 3;
+ if ( idx > XEN_CPUID_MAX_NUM_LEAVES )
+ return 0; /* Avoid unnecessary pass through domain_cpuid() */
+
+ /* Number of leaves may be user-specified */
+ domain_cpuid(d, base, 0, &limit, &dummy, &dummy, &dummy);
+ limit &= 0xff;
+ if ( (limit < 2) || (limit > XEN_CPUID_MAX_NUM_LEAVES) )
+ limit = XEN_CPUID_MAX_NUM_LEAVES;
if ( idx > limit )
return 0;
diff --git a/xen/include/public/arch-x86/cpuid.h b/xen/include/public/arch-x86/cpuid.h
index d9bd627..19fc9dd 100644
--- a/xen/include/public/arch-x86/cpuid.h
+++ b/xen/include/public/arch-x86/cpuid.h
@@ -65,4 +65,6 @@
#define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0
#define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0)
+#define XEN_CPUID_MAX_NUM_LEAVES 3
+
#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves
2014-04-21 21:57 ` [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves Boris Ostrovsky
@ 2014-04-22 9:45 ` Jan Beulich
2014-04-22 12:32 ` Boris Ostrovsky
0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2014-04-22 9:45 UTC (permalink / raw)
To: Boris Ostrovsky
Cc: kevin.tian, ian.campbell, stefano.stabellini, andrew.cooper3,
eddie.dong, xen-devel, yang.z.zhang, ian.jackson
>>> On 21.04.14 at 23:57, <boris.ostrovsky@oracle.com> wrote:
> + if ( (limit < 2) || (limit > XEN_CPUID_MAX_NUM_LEAVES) )
> + limit = XEN_CPUID_MAX_NUM_LEAVES;
Almost: If limit < 2, you would be better off using 2 rather than the
default (which may be growing).
Jan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves
2014-04-22 9:45 ` Jan Beulich
@ 2014-04-22 12:32 ` Boris Ostrovsky
2014-04-22 12:41 ` Jan Beulich
0 siblings, 1 reply; 8+ messages in thread
From: Boris Ostrovsky @ 2014-04-22 12:32 UTC (permalink / raw)
To: Jan Beulich
Cc: kevin.tian, ian.campbell, stefano.stabellini, andrew.cooper3,
eddie.dong, xen-devel, yang.z.zhang, ian.jackson
On 04/22/2014 05:45 AM, Jan Beulich wrote:
>>>> On 21.04.14 at 23:57, <boris.ostrovsky@oracle.com> wrote:
>> + if ( (limit < 2) || (limit > XEN_CPUID_MAX_NUM_LEAVES) )
>> + limit = XEN_CPUID_MAX_NUM_LEAVES;
> Almost: If limit < 2, you would be better off using 2 rather than the
> default (which may be growing).
My thinking was that for any invalid limit value we should ignore what
the user file specified, not try to guess what was meant.
-boris
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves
2014-04-22 12:32 ` Boris Ostrovsky
@ 2014-04-22 12:41 ` Jan Beulich
2014-04-22 14:26 ` Don Slutz
0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2014-04-22 12:41 UTC (permalink / raw)
To: Boris Ostrovsky
Cc: kevin.tian, ian.campbell, stefano.stabellini, andrew.cooper3,
eddie.dong, xen-devel, yang.z.zhang, ian.jackson
>>> On 22.04.14 at 14:32, <boris.ostrovsky@oracle.com> wrote:
> On 04/22/2014 05:45 AM, Jan Beulich wrote:
>>>>> On 21.04.14 at 23:57, <boris.ostrovsky@oracle.com> wrote:
>>> + if ( (limit < 2) || (limit > XEN_CPUID_MAX_NUM_LEAVES) )
>>> + limit = XEN_CPUID_MAX_NUM_LEAVES;
>> Almost: If limit < 2, you would be better off using 2 rather than the
>> default (which may be growing).
>
> My thinking was that for any invalid limit value we should ignore what
> the user file specified, not try to guess what was meant.
And I think that 0 or 1 aren't really invalid - if a lower limit is wanted,
provided as low as possible one rather than ignoring the request (I
didn't look at what upsets hvmloader - I suppose this could be fixed
rather than going with the slightly awkward lower limit of 2).
Jan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves
2014-04-22 12:41 ` Jan Beulich
@ 2014-04-22 14:26 ` Don Slutz
0 siblings, 0 replies; 8+ messages in thread
From: Don Slutz @ 2014-04-22 14:26 UTC (permalink / raw)
To: Jan Beulich, Boris Ostrovsky
Cc: kevin.tian, ian.campbell, stefano.stabellini, andrew.cooper3,
eddie.dong, xen-devel, yang.z.zhang, ian.jackson
On 04/22/14 08:41, Jan Beulich wrote:
>>>> On 22.04.14 at 14:32, <boris.ostrovsky@oracle.com> wrote:
>> On 04/22/2014 05:45 AM, Jan Beulich wrote:
>>>>>> On 21.04.14 at 23:57, <boris.ostrovsky@oracle.com> wrote:
>>>> + if ( (limit < 2) || (limit > XEN_CPUID_MAX_NUM_LEAVES) )
>>>> + limit = XEN_CPUID_MAX_NUM_LEAVES;
>>> Almost: If limit < 2, you would be better off using 2 rather than the
>>> default (which may be growing).
>> My thinking was that for any invalid limit value we should ignore what
>> the user file specified, not try to guess what was meant.
> And I think that 0 or 1 aren't really invalid - if a lower limit is wanted,
> provided as low as possible one rather than ignoring the request (I
> didn't look at what upsets hvmloader - I suppose this could be fixed
> rather than going with the slightly awkward lower limit of 2).
I think the routine init_hypercalls() is where hvmloader gets upset:
/* Fill in hypercall transfer pages. */
cpuid(base + 2, &eax, &ebx, &ecx, &edx);
for ( i = 0; i < eax; i++ )
wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
-Don Slutz
> Jan
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v8 2/3] x86/hvm: Add HVM-specific hypervisor CPUID leaf
2014-04-21 21:57 [PATCH v8 0/3] Expose HW APIC virtualization support to HVM guests Boris Ostrovsky
2014-04-21 21:57 ` [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves Boris Ostrovsky
@ 2014-04-21 21:57 ` Boris Ostrovsky
2014-04-21 21:57 ` [PATCH v8 3/3] x86/hvm: Indicate avaliability of HW support of APIC virtualization to HVM guests Boris Ostrovsky
2 siblings, 0 replies; 8+ messages in thread
From: Boris Ostrovsky @ 2014-04-21 21:57 UTC (permalink / raw)
To: jbeulich, ian.campbell, ian.jackson, stefano.stabellini,
eddie.dong, kevin.tian
Cc: yang.z.zhang, andrew.cooper3, boris.ostrovsky, xen-devel
CPUID leaf 0x40000004 is for HVM-specific features.
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-off-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/hvm/hvm.c | 9 +++++++++
xen/arch/x86/traps.c | 4 ++++
xen/include/asm-x86/hvm/hvm.h | 7 +++++++
xen/include/public/arch-x86/cpuid.h | 7 ++++++-
4 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ae7a645..16b968c 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -2983,6 +2983,15 @@ unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
return rc ? len : 0; /* fake a copy_from_user() return code */
}
+void hvm_hypervisor_cpuid_leaf(uint32_t sub_idx,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ *eax = *ebx = *ecx = *edx = 0;
+ if ( hvm_funcs.hypervisor_cpuid_leaf )
+ hvm_funcs.hypervisor_cpuid_leaf(sub_idx, eax, ebx, ecx, edx);
+}
+
void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index b2a35a3..d6daddf 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -724,6 +724,10 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
cpuid_time_leaf( sub_idx, eax, ebx, ecx, edx );
break;
+ case 4:
+ hvm_hypervisor_cpuid_leaf(sub_idx, eax, ebx, ecx, edx);
+ break;
+
default:
BUG();
}
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index dcc3483..a030ea4 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -200,6 +200,10 @@ struct hvm_function_table {
paddr_t *L1_gpa, unsigned int *page_order,
uint8_t *p2m_acc, bool_t access_r,
bool_t access_w, bool_t access_x);
+
+ void (*hypervisor_cpuid_leaf)(uint32_t sub_idx,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
};
extern struct hvm_function_table hvm_funcs;
@@ -336,6 +340,9 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v)
#define is_viridian_domain(_d) \
(is_hvm_domain(_d) && ((_d)->arch.hvm_domain.params[HVM_PARAM_VIRIDIAN]))
+void hvm_hypervisor_cpuid_leaf(uint32_t sub_idx,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx);
void hvm_migrate_timers(struct vcpu *v);
diff --git a/xen/include/public/arch-x86/cpuid.h b/xen/include/public/arch-x86/cpuid.h
index 19fc9dd..fff972a 100644
--- a/xen/include/public/arch-x86/cpuid.h
+++ b/xen/include/public/arch-x86/cpuid.h
@@ -65,6 +65,11 @@
#define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0
#define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0)
-#define XEN_CPUID_MAX_NUM_LEAVES 3
+/*
+ * Leaf 5 (0x40000004)
+ * HVM-specific features
+ */
+
+#define XEN_CPUID_MAX_NUM_LEAVES 4
#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v8 3/3] x86/hvm: Indicate avaliability of HW support of APIC virtualization to HVM guests
2014-04-21 21:57 [PATCH v8 0/3] Expose HW APIC virtualization support to HVM guests Boris Ostrovsky
2014-04-21 21:57 ` [PATCH v8 1/3] xen/libxc: Allow changing max number of hypervisor cpuid leaves Boris Ostrovsky
2014-04-21 21:57 ` [PATCH v8 2/3] x86/hvm: Add HVM-specific hypervisor CPUID leaf Boris Ostrovsky
@ 2014-04-21 21:57 ` Boris Ostrovsky
2 siblings, 0 replies; 8+ messages in thread
From: Boris Ostrovsky @ 2014-04-21 21:57 UTC (permalink / raw)
To: jbeulich, ian.campbell, ian.jackson, stefano.stabellini,
eddie.dong, kevin.tian
Cc: yang.z.zhang, andrew.cooper3, boris.ostrovsky, xen-devel
Set bits in hypervisor CPUID leaf indicating that HW provides (and the
hypervisor enables) HW support for APIC and x2APIC virtualization.
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
xen/arch/x86/hvm/vmx/vmx.c | 21 +++++++++++++++++++++
xen/include/public/arch-x86/cpuid.h | 4 ++++
2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 180cf6c..7c7acd6 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -57,6 +57,7 @@
#include <asm/apic.h>
#include <asm/hvm/nestedhvm.h>
#include <asm/event.h>
+#include <public/arch-x86/cpuid.h>
enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised };
@@ -1651,6 +1652,25 @@ static void vmx_handle_eoi(u8 vector)
__vmwrite(GUEST_INTR_STATUS, status);
}
+void vmx_hypervisor_cpuid_leaf(uint32_t sub_idx,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ if ( sub_idx != 0 )
+ return;
+
+ if ( cpu_has_vmx_apic_reg_virt )
+ *eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT;
+ /*
+ * We want to claim that x2APIC is virtualized if APIC MSR accesses are
+ * not intercepted. When all three of these are true both rdmsr and wrmsr
+ * in the guest will run without VMEXITs (see vmx_vlapic_msr_changed()).
+ */
+ if ( cpu_has_vmx_virtualize_x2apic_mode && cpu_has_vmx_apic_reg_virt &&
+ cpu_has_vmx_virtual_intr_delivery)
+ *eax |= XEN_HVM_CPUID_X2APIC_VIRT;
+}
+
static struct hvm_function_table __initdata vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -1708,6 +1728,7 @@ static struct hvm_function_table __initdata vmx_function_table = {
.sync_pir_to_irr = vmx_sync_pir_to_irr,
.handle_eoi = vmx_handle_eoi,
.nhvm_hap_walk_L1_p2m = nvmx_hap_walk_L1_p2m,
+ .hypervisor_cpuid_leaf= vmx_hypervisor_cpuid_leaf,
};
const struct hvm_function_table * __init start_vmx(void)
diff --git a/xen/include/public/arch-x86/cpuid.h b/xen/include/public/arch-x86/cpuid.h
index fff972a..7135d54 100644
--- a/xen/include/public/arch-x86/cpuid.h
+++ b/xen/include/public/arch-x86/cpuid.h
@@ -70,6 +70,10 @@
* HVM-specific features
*/
+/* EAX Features */
+#define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0) /* Virtualized APIC registers */
+#define XEN_HVM_CPUID_X2APIC_VIRT (1u << 1) /* Virtualized x2APIC accesses */
+
#define XEN_CPUID_MAX_NUM_LEAVES 4
#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread