aboutsummaryrefslogtreecommitdiffstats
path: root/xen/xsm/xsm_policy.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-12-01 17:57:54 +0100
committerJan Beulich <jbeulich@suse.com>2011-12-01 17:57:54 +0100
commit436fb462abf5673af105e0f2f0640a598286d0fe (patch)
tree6f1880e47cae89dcb546fa97d315a3de703dfe40 /xen/xsm/xsm_policy.c
parent0bda96825f7f8fcb32a609b3d507e8f0a0adf8a2 (diff)
downloadxen-436fb462abf5673af105e0f2f0640a598286d0fe.tar.gz
xen-436fb462abf5673af105e0f2f0640a598286d0fe.tar.bz2
xen-436fb462abf5673af105e0f2f0640a598286d0fe.zip
x86/microcode: enable boot time (pre-Dom0) loading
Largely as a result of the continuing resistance of Linux maintainers to accept a microcode loading patch for pv-ops Xen kernels, this follows the suggested route and provides a means to load microcode updates without the assistance of Dom0, thus also addressing eventual problems in the hardware much earlier. This leverages the fact that via the multiboot protocol another blob of data can be easily added in the form of just an extra module. Since microcode data cannot reliably be recognized by looking at the provided data, this requires (in the non-EFI case) the use of a command line parameter ("ucode=<number>") to identify which of the modules is to be parsed for an eventual microcode update (in the EFI case the module is being identified in the config file, and hence the command line argument, if given, will be ignored). This required to adjust the XSM module determination logic accordingly. The format of the data to be provided is the raw binary blob already used for AMD CPUs, and the output of the intel-microcode2ucode utility for the Intel case (either the per-(family,model,stepping) file or - to make things easier for distro-s integration-wise - simply the concatenation of all of them). In order to not convert the spin_lock() in microcode_update_cpu() (and then obviously also all other uses on microcode_mutex) to spin_lock_irqsave() (which would be undesirable for the hypercall context in which the function also runs), the boot time handling gets done using a tasklet (instead of using on_selected_cpus()). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/xsm/xsm_policy.c')
-rw-r--r--xen/xsm/xsm_policy.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index c5b334e7e9..a419cf4e84 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -20,11 +20,12 @@
#include <xsm/xsm.h>
#include <xen/multiboot.h>
+#include <asm/bitops.h>
char *__initdata policy_buffer = NULL;
u32 __initdata policy_size = 0;
-int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
+int xsm_policy_init(unsigned long *module_map, const multiboot_info_t *mbi,
void *(*bootstrap_map)(const module_t *))
{
int i;
@@ -35,10 +36,13 @@ int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
/*
* Try all modules and see whichever could be the binary policy.
- * Adjust the initrdidx if module[1] is the binary policy.
+ * Adjust module_map for the module that is the binary policy.
*/
for ( i = mbi->mods_count-1; i >= 1; i-- )
{
+ if ( !test_bit(i, module_map) )
+ continue;
+
_policy_start = bootstrap_map(mod + i);
_policy_len = mod[i].mod_end;
@@ -50,8 +54,7 @@ int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
printk("Policy len 0x%lx, start at %p.\n",
_policy_len,_policy_start);
- if ( i == 1 )
- *initrdidx = (mbi->mods_count > 2) ? 2 : 0;
+ __clear_bit(i, module_map);
break;
}