Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05eebfb2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 paravirt changes from Ingo Molnar:
 "Hypervisor signature detection cleanup and fixes - the goal is to make
  KVM guests run better on MS/Hyperv and to generalize and factor out
  the code a bit"

* 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86: Correctly detect hypervisor
  x86, kvm: Switch to use hypervisor_cpuid_base()
  xen: Switch to use hypervisor_cpuid_base()
  x86: Introduce hypervisor_cpuid_base()
parents cb3e4330 9df56f19
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ struct hypervisor_x86 {
	const char	*name;

	/* Detection routine */
	bool		(*detect)(void);
	uint32_t	(*detect)(void);

	/* Adjust CPU feature bits (run once per CPU) */
	void		(*set_cpu_features)(struct cpuinfo_x86 *);
+9 −15
Original line number Diff line number Diff line
@@ -85,26 +85,20 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
	return ret;
}

static inline bool kvm_para_available(void)
static inline uint32_t kvm_cpuid_base(void)
{
	unsigned int eax, ebx, ecx, edx;
	char signature[13];

	if (boot_cpu_data.cpuid_level < 0)
		return false;	/* So we don't blow up on old processors */
		return 0;	/* So we don't blow up on old processors */

	if (cpu_has_hypervisor) {
		cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
		memcpy(signature + 0, &ebx, 4);
		memcpy(signature + 4, &ecx, 4);
		memcpy(signature + 8, &edx, 4);
		signature[12] = 0;
	if (cpu_has_hypervisor)
		return hypervisor_cpuid_base("KVMKVMKVM\0\0\0", 0);

		if (strcmp(signature, "KVMKVMKVM") == 0)
			return true;
	return 0;
}

	return false;
static inline bool kvm_para_available(void)
{
	return kvm_cpuid_base() != 0;
}

static inline unsigned int kvm_arch_para_features(void)
+15 −0
Original line number Diff line number Diff line
@@ -942,6 +942,21 @@ extern int set_tsc_mode(unsigned int val);

extern u16 amd_get_nb_id(int cpu);

static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
{
	uint32_t base, eax, signature[3];

	for (base = 0x40000000; base < 0x40010000; base += 0x100) {
		cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);

		if (!memcmp(sig, signature, 12) &&
		    (leaves == 0 || ((eax - base) >= leaves)))
			return base;
	}

	return 0;
}

extern unsigned long arch_align_stack(unsigned long sp);
extern void free_init_pages(char *what, unsigned long begin, unsigned long end);

+1 −15
Original line number Diff line number Diff line
@@ -40,21 +40,7 @@ extern struct start_info *xen_start_info;

static inline uint32_t xen_cpuid_base(void)
{
	uint32_t base, eax, ebx, ecx, edx;
	char signature[13];

	for (base = 0x40000000; base < 0x40010000; base += 0x100) {
		cpuid(base, &eax, &ebx, &ecx, &edx);
		*(uint32_t *)(signature + 0) = ebx;
		*(uint32_t *)(signature + 4) = ecx;
		*(uint32_t *)(signature + 8) = edx;
		signature[12] = 0;

		if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2))
			return base;
	}

	return 0;
	return hypervisor_cpuid_base("XenVMMXenVMM", 2);
}

#ifdef CONFIG_XEN
+7 −8
Original line number Diff line number Diff line
@@ -25,11 +25,6 @@
#include <asm/processor.h>
#include <asm/hypervisor.h>

/*
 * Hypervisor detect order.  This is specified explicitly here because
 * some hypervisors might implement compatibility modes for other
 * hypervisors and therefore need to be detected in specific sequence.
 */
static const __initconst struct hypervisor_x86 * const hypervisors[] =
{
#ifdef CONFIG_XEN_PVHVM
@@ -49,15 +44,19 @@ static inline void __init
detect_hypervisor_vendor(void)
{
	const struct hypervisor_x86 *h, * const *p;
	uint32_t pri, max_pri = 0;

	for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
		h = *p;
		if (h->detect()) {
		pri = h->detect();
		if (pri != 0 && pri > max_pri) {
			max_pri = pri;
			x86_hyper = h;
			printk(KERN_INFO "Hypervisor detected: %s\n", h->name);
			break;
		}
	}

	if (max_pri)
		printk(KERN_INFO "Hypervisor detected: %s\n", x86_hyper->name);
}

void init_hypervisor(struct cpuinfo_x86 *c)
Loading