|
12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
13 | 13 |
|
14 | 14 | #include <linux/slab.h>
|
| 15 | +#include <asm/intel-family.h> |
15 | 16 | #include "intel_rdt.h"
|
16 | 17 |
|
| 18 | +/* |
| 19 | + * MSR_MISC_FEATURE_CONTROL register enables the modification of hardware |
| 20 | + * prefetcher state. Details about this register can be found in the MSR |
| 21 | + * tables for specific platforms found in Intel's SDM. |
| 22 | + */ |
| 23 | +#define MSR_MISC_FEATURE_CONTROL 0x000001a4 |
| 24 | + |
| 25 | +/* |
| 26 | + * The bits needed to disable hardware prefetching varies based on the |
| 27 | + * platform. During initialization we will discover which bits to use. |
| 28 | + */ |
| 29 | +static u64 prefetch_disable_bits; |
| 30 | + |
| 31 | +/** |
| 32 | + * get_prefetch_disable_bits - prefetch disable bits of supported platforms |
| 33 | + * |
| 34 | + * Capture the list of platforms that have been validated to support |
| 35 | + * pseudo-locking. This includes testing to ensure pseudo-locked regions |
| 36 | + * with low cache miss rates can be created under variety of load conditions |
| 37 | + * as well as that these pseudo-locked regions can maintain their low cache |
| 38 | + * miss rates under variety of load conditions for significant lengths of time. |
| 39 | + * |
| 40 | + * After a platform has been validated to support pseudo-locking its |
| 41 | + * hardware prefetch disable bits are included here as they are documented |
| 42 | + * in the SDM. |
| 43 | + * |
| 44 | + * Return: |
| 45 | + * If platform is supported, the bits to disable hardware prefetchers, 0 |
| 46 | + * if platform is not supported. |
| 47 | + */ |
| 48 | +static u64 get_prefetch_disable_bits(void) |
| 49 | +{ |
| 50 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || |
| 51 | + boot_cpu_data.x86 != 6) |
| 52 | + return 0; |
| 53 | + |
| 54 | + switch (boot_cpu_data.x86_model) { |
| 55 | + case INTEL_FAM6_BROADWELL_X: |
| 56 | + /* |
| 57 | + * SDM defines bits of MSR_MISC_FEATURE_CONTROL register |
| 58 | + * as: |
| 59 | + * 0 L2 Hardware Prefetcher Disable (R/W) |
| 60 | + * 1 L2 Adjacent Cache Line Prefetcher Disable (R/W) |
| 61 | + * 2 DCU Hardware Prefetcher Disable (R/W) |
| 62 | + * 3 DCU IP Prefetcher Disable (R/W) |
| 63 | + * 63:4 Reserved |
| 64 | + */ |
| 65 | + return 0xF; |
| 66 | + case INTEL_FAM6_ATOM_GOLDMONT: |
| 67 | + case INTEL_FAM6_ATOM_GEMINI_LAKE: |
| 68 | + /* |
| 69 | + * SDM defines bits of MSR_MISC_FEATURE_CONTROL register |
| 70 | + * as: |
| 71 | + * 0 L2 Hardware Prefetcher Disable (R/W) |
| 72 | + * 1 Reserved |
| 73 | + * 2 DCU Hardware Prefetcher Disable (R/W) |
| 74 | + * 63:3 Reserved |
| 75 | + */ |
| 76 | + return 0x5; |
| 77 | + } |
| 78 | + |
| 79 | + return 0; |
| 80 | +} |
| 81 | + |
17 | 82 | /**
|
18 | 83 | * pseudo_lock_init - Initialize a pseudo-lock region
|
19 | 84 | * @rdtgrp: resource group to which new pseudo-locked region will belong
|
@@ -225,6 +290,16 @@ int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
|
225 | 290 | return -EINVAL;
|
226 | 291 | }
|
227 | 292 |
|
| 293 | + /* |
| 294 | + * Not knowing the bits to disable prefetching implies that this |
| 295 | + * platform does not support Cache Pseudo-Locking. |
| 296 | + */ |
| 297 | + prefetch_disable_bits = get_prefetch_disable_bits(); |
| 298 | + if (prefetch_disable_bits == 0) { |
| 299 | + rdt_last_cmd_puts("pseudo-locking not supported\n"); |
| 300 | + return -EINVAL; |
| 301 | + } |
| 302 | + |
228 | 303 | if (rdtgroup_monitor_in_progress(rdtgrp)) {
|
229 | 304 | rdt_last_cmd_puts("monitoring in progress\n");
|
230 | 305 | return -EINVAL;
|
|
0 commit comments