@@ -1427,19 +1427,21 @@ enabling more sockets and cores to go into deeper sleep states.
Set the serial transmit buffer size.
-### smep
-> `= <boolean>`
+### smap
+> `= <boolean> | hvm`
> Default: `true`
-Flag to enable Supervisor Mode Execution Protection
+Flag to enable Supervisor Mode Access Prevention
+Using `smap=hvm` to enable SMAP for HVM guests only.
-### smap
-> `= <boolean>`
+### smep
+> `= <boolean> | hvm`
> Default: `true`
-Flag to enable Supervisor Mode Access Prevention
+Flag to enable Supervisor Mode Execution Protection
+Using `smep=hvm` to enable SMEP for HVM guests only.
### snb\_igd\_quirk
> `= <boolean> | cap | <integer>`
@@ -4,6 +4,7 @@
#include <asm/hvm/hvm.h>
#include <asm/hvm/vmx/vmcs.h>
#include <asm/processor.h>
+#include <asm/setup.h>
const uint32_t known_features[] = INIT_KNOWN_FEATURES;
const uint32_t special_features[] = INIT_SPECIAL_FEATURES;
@@ -118,6 +119,10 @@ static void __init calculate_pv_featureset(void)
__set_bit(X86_FEATURE_HTT, pv_featureset);
__set_bit(X86_FEATURE_X2APIC, pv_featureset);
__set_bit(X86_FEATURE_CMP_LEGACY, pv_featureset);
+ if ( smep_hvm_only )
+ __clear_bit(X86_FEATURE_SMEP, pv_featureset);
+ if ( smap_hvm_only )
+ __clear_bit(X86_FEATURE_SMAP, pv_featureset);
sanitise_featureset(pv_featureset);
}
@@ -61,13 +61,19 @@ boolean_param("nosmp", opt_nosmp);
static unsigned int __initdata max_cpus;
integer_param("maxcpus", max_cpus);
-/* smep: Enable/disable Supervisor Mode Execution Protection (default on). */
-static bool_t __initdata opt_smep = 1;
-boolean_param("smep", opt_smep);
-
-/* smap: Enable/disable Supervisor Mode Access Prevention (default on). */
-static bool_t __initdata opt_smap = 1;
-boolean_param("smap", opt_smap);
+/* Supervisor Mode Execution Protection (default on). */
+/* "smep=on": Enable SMEP for Xen and guests. */
+/* "smep=hvm": Enable SMEP for HVM only. */
+/* "smep=off": Disable SMEP for Xen and guests. */
+static void parse_smep_param(char *s);
+custom_param("smep", parse_smep_param);
+
+/* Supervisor Mode Access Prevention (default on). */
+/* "smep=on": Enable SMAP for Xen and guests. */
+/* "smep=hvm": Enable SMAP for HVM only. */
+/* "smep=off": Disable SMAP for Xen and guests. */
+static void parse_smap_param(char *s);
+custom_param("smap", parse_smap_param);
unsigned long __read_mostly cr4_pv32_mask;
@@ -111,6 +117,34 @@ struct cpuinfo_x86 __read_mostly boot_cpu_data = { 0, 0, 0, 0, -1 };
unsigned long __read_mostly mmu_cr4_features = XEN_MINIMAL_CR4;
+static bool_t __initdata opt_smep = 1;
+bool_t __initdata smep_hvm_only = 0;
+static void __init parse_smep_param(char *s)
+{
+ if ( !parse_bool(s) )
+ {
+ opt_smep = 0;
+ }
+ else if ( !strcmp(s, "hvm") )
+ {
+ smep_hvm_only = 1;
+ }
+}
+
+static bool_t __initdata opt_smap = 1;
+bool_t __initdata smap_hvm_only = 0;
+static void __init parse_smap_param(char *s)
+{
+ if ( !parse_bool(s) )
+ {
+ opt_smap = 0;
+ }
+ else if ( !strcmp(s, "hvm") )
+ {
+ smap_hvm_only = 1;
+ }
+}
+
bool_t __read_mostly acpi_disabled;
bool_t __initdata acpi_force;
static char __initdata acpi_param[10] = "";
@@ -1404,12 +1438,20 @@ void __init noreturn __start_xen(unsigned long mbi_p)
if ( !opt_smep )
setup_clear_cpu_cap(X86_FEATURE_SMEP);
if ( cpu_has_smep )
+ {
set_in_cr4(X86_CR4_SMEP);
+ if ( smep_hvm_only )
+ write_cr4(read_cr4() & ~X86_CR4_SMEP);
+ }
if ( !opt_smap )
setup_clear_cpu_cap(X86_FEATURE_SMAP);
if ( cpu_has_smap )
+ {
set_in_cr4(X86_CR4_SMAP);
+ if ( smap_hvm_only )
+ write_cr4(read_cr4() & ~X86_CR4_SMAP);
+ }
cr4_pv32_mask = mmu_cr4_features & XEN_CR4_PV32_BITS;
@@ -1570,7 +1612,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
bootstrap_map, cmdline) != 0)
panic("Could not set up DOM0 guest OS");
- if ( cpu_has_smap )
+ if ( cpu_has_smap && !smap_hvm_only )
{
write_cr4(read_cr4() | X86_CR4_SMAP);
cr4_pv32_mask |= X86_CR4_SMAP;
@@ -51,6 +51,9 @@ void microcode_grab_module(
extern uint8_t kbd_shift_flags;
+extern bool_t smep_hvm_only;
+extern bool_t smap_hvm_only;
+
#ifdef NDEBUG
# define highmem_start 0
#else
Enhance "smep" and "smap" command line options to support enabling SMEP or SMAP for HVM only with allowing "hvm" as a value. Signed-off-by: He Chen <he.chen@linux.intel.com> --- Changes in V2: * Allow "hvm" as a value to "smep" and "smap" command line options. * Clear SMEP/SMAP CPUID bits for pv guests if they are set to hvm only. * Refine docs. * Rewrite commit message. --- docs/misc/xen-command-line.markdown | 14 +++++---- xen/arch/x86/cpuid.c | 5 ++++ xen/arch/x86/setup.c | 58 ++++++++++++++++++++++++++++++++----- xen/include/asm-x86/setup.h | 3 ++ 4 files changed, 66 insertions(+), 14 deletions(-)