19d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox/* timskmodutils.c
29d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox *
3f6d0c1e62b111bef3be279e4bf1bc2a6d560e205Benjamin Romer * Copyright (C) 2010 - 2013 UNISYS CORPORATION
49d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * All rights reserved.
59d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox *
69d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * This program is free software; you can redistribute it and/or modify
79d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * it under the terms of the GNU General Public License as published by
89d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * the Free Software Foundation; either version 2 of the License, or (at
99d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * your option) any later version.
109d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox *
119d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * This program is distributed in the hope that it will be useful, but
129d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * WITHOUT ANY WARRANTY; without even the implied warranty of
139d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
149d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * NON INFRINGEMENT.  See the GNU General Public License for more
159d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox * details.
169d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox */
179d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox
189d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox#include "uniklog.h"
199d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox#include "timskmod.h"
209d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox
219d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox#define MYDRVNAME "timskmodutils"
229d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox
23fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox/* s-Par uses the Intel processor's VT-X features to separate groups of
24fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox * processors into partitions. The firmware sets the hypervisor bit and
25fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox * reports an ID in the HV capabilities leaf so that the partition's OS
26fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox * knows s-Par is present and managing the processors.
27fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox */
28fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
29fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox#define UNISYS_SPAR_LEAF_ID 0x40000000
30fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
31fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox/* The s-Par leaf ID returns "UnisysSpar64" encoded across ebx, ecx, edx */
32fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox#define UNISYS_SPAR_ID_EBX 0x73696e55
33fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox#define UNISYS_SPAR_ID_ECX 0x70537379
34fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox#define UNISYS_SPAR_ID_EDX 0x34367261
35fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
36fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxint unisys_spar_platform;
37fcd0157ece8a1bf36b877a9c8078ea721678a38bKen CoxEXPORT_SYMBOL_GPL(unisys_spar_platform);
38fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
399d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox/** Callers to interfaces that set __GFP_NORETRY flag below
409d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox *  must check for a NULL (error) result as we are telling the
419d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox *  kernel interface that it is okay to fail.
429d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox */
439d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox
449d9baadd4069c77a97bf530abad9ddb74875fe76Ken Coxvoid *kmalloc_kernel(size_t siz)
459d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox{
469d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox	return kmalloc(siz, GFP_KERNEL | __GFP_NORETRY);
479d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox}
489d9baadd4069c77a97bf530abad9ddb74875fe76Ken Cox
49fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxstatic __init uint32_t
50fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxvisorutil_spar_detect(void)
51fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox{
52fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox	unsigned int eax, ebx, ecx, edx;
53fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
54fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox	if (cpu_has_hypervisor) {
55fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		/* check the ID */
56fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		cpuid(UNISYS_SPAR_LEAF_ID, &eax, &ebx, &ecx, &edx);
57fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		return  (ebx == UNISYS_SPAR_ID_EBX) &&
58fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox			(ecx == UNISYS_SPAR_ID_ECX) &&
59fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox			(edx == UNISYS_SPAR_ID_EDX);
60fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox	} else
61fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		return 0;
62fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
63fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox}
64fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
65fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
66fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
67fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
68fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxstatic __init int
69fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxvisorutil_mod_init(void)
70fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox{
71fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox	if (visorutil_spar_detect()) {
72fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		unisys_spar_platform = TRUE;
73fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		return 0;
74fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox	} else
75fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox		return -ENODEV;
76fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox}
77fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
78fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxstatic __exit void
79fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxvisorutil_mod_exit(void)
80fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox{
81fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox}
82fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
83fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxmodule_init(visorutil_mod_init);
84fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Coxmodule_exit(visorutil_mod_exit);
85fcd0157ece8a1bf36b877a9c8078ea721678a38bKen Cox
8637b7e990ff0ac58f8b09b5e8beee7777edbff739Ken CoxMODULE_LICENSE("GPL");
87