|
@@ -65,6 +65,8 @@
|
|
|
#define KVM_INST_TLBSYNC 0x7c00046c
|
|
|
|
|
|
static bool kvm_patching_worked = true;
|
|
|
+static char kvm_tmp[1024 * 1024];
|
|
|
+static int kvm_tmp_index;
|
|
|
|
|
|
static inline void kvm_patch_ins(u32 *inst, u32 new_inst)
|
|
|
{
|
|
@@ -105,6 +107,23 @@ static void kvm_patch_ins_nop(u32 *inst)
|
|
|
kvm_patch_ins(inst, KVM_INST_NOP);
|
|
|
}
|
|
|
|
|
|
+static u32 *kvm_alloc(int len)
|
|
|
+{
|
|
|
+ u32 *p;
|
|
|
+
|
|
|
+ if ((kvm_tmp_index + len) > ARRAY_SIZE(kvm_tmp)) {
|
|
|
+ printk(KERN_ERR "KVM: No more space (%d + %d)\n",
|
|
|
+ kvm_tmp_index, len);
|
|
|
+ kvm_patching_worked = false;
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ p = (void*)&kvm_tmp[kvm_tmp_index];
|
|
|
+ kvm_tmp_index += len;
|
|
|
+
|
|
|
+ return p;
|
|
|
+}
|
|
|
+
|
|
|
static void kvm_map_magic_page(void *data)
|
|
|
{
|
|
|
kvm_hypercall2(KVM_HC_PPC_MAP_MAGIC_PAGE,
|
|
@@ -270,17 +289,36 @@ static int kvm_para_setup(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static __init void kvm_free_tmp(void)
|
|
|
+{
|
|
|
+ unsigned long start, end;
|
|
|
+
|
|
|
+ start = (ulong)&kvm_tmp[kvm_tmp_index + (PAGE_SIZE - 1)] & PAGE_MASK;
|
|
|
+ end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK;
|
|
|
+
|
|
|
+ /* Free the tmp space we don't need */
|
|
|
+ for (; start < end; start += PAGE_SIZE) {
|
|
|
+ ClearPageReserved(virt_to_page(start));
|
|
|
+ init_page_count(virt_to_page(start));
|
|
|
+ free_page(start);
|
|
|
+ totalram_pages++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int __init kvm_guest_init(void)
|
|
|
{
|
|
|
if (!kvm_para_available())
|
|
|
- return 0;
|
|
|
+ goto free_tmp;
|
|
|
|
|
|
if (kvm_para_setup())
|
|
|
- return 0;
|
|
|
+ goto free_tmp;
|
|
|
|
|
|
if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE))
|
|
|
kvm_use_magic_page();
|
|
|
|
|
|
+free_tmp:
|
|
|
+ kvm_free_tmp();
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|