Commit 9843b030 authored by Sanjay Lal's avatar Sanjay Lal Committed by Ralf Baechle

KVM/MIPS32: KVM Guest kernel support.

Both Guest kernel and Guest Userspace execute in UM. The memory map is as follows:
Guest User address space:   0x00000000 -> 0x40000000
Guest Kernel Unmapped:      0x40000000 -> 0x60000000
Guest Kernel Mapped:        0x60000000 -> 0x80000000
- Guest Usermode virtual memory is limited to 1GB.
Signed-off-by: default avatarSanjay Lal <sanjayl@kymasys.com>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 669e846e
...@@ -20,14 +20,21 @@ ...@@ -20,14 +20,21 @@
#endif #endif
#ifdef CONFIG_32BIT #ifdef CONFIG_32BIT
#ifdef CONFIG_KVM_GUEST
#define CAC_BASE _AC(0x40000000, UL)
#else
#define CAC_BASE _AC(0x80000000, UL) #define CAC_BASE _AC(0x80000000, UL)
#endif
#define IO_BASE _AC(0xa0000000, UL) #define IO_BASE _AC(0xa0000000, UL)
#define UNCAC_BASE _AC(0xa0000000, UL) #define UNCAC_BASE _AC(0xa0000000, UL)
#ifndef MAP_BASE #ifndef MAP_BASE
#ifdef CONFIG_KVM_GUEST
#define MAP_BASE _AC(0x60000000, UL)
#else
#define MAP_BASE _AC(0xc0000000, UL) #define MAP_BASE _AC(0xc0000000, UL)
#endif #endif
#endif
/* /*
* Memory above this physical address will be considered highmem. * Memory above this physical address will be considered highmem.
......
...@@ -44,11 +44,16 @@ extern unsigned int vced_count, vcei_count; ...@@ -44,11 +44,16 @@ extern unsigned int vced_count, vcei_count;
#define SPECIAL_PAGES_SIZE PAGE_SIZE #define SPECIAL_PAGES_SIZE PAGE_SIZE
#ifdef CONFIG_32BIT #ifdef CONFIG_32BIT
#ifdef CONFIG_KVM_GUEST
/* User space process size is limited to 1GB in KVM Guest Mode */
#define TASK_SIZE 0x3fff8000UL
#else
/* /*
* User space process size: 2GB. This is hardcoded into a few places, * User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing. * so don't change it unless you know what you are doing.
*/ */
#define TASK_SIZE 0x7fff8000UL #define TASK_SIZE 0x7fff8000UL
#endif
#ifdef __KERNEL__ #ifdef __KERNEL__
#define STACK_TOP_MAX TASK_SIZE #define STACK_TOP_MAX TASK_SIZE
......
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
*/ */
#ifdef CONFIG_32BIT #ifdef CONFIG_32BIT
#define __UA_LIMIT 0x80000000UL #ifdef CONFIG_KVM_GUEST
#define __UA_LIMIT 0x40000000UL
#else
#define __UA_LIMIT 0x80000000UL
#endif
#define __UA_ADDR ".word" #define __UA_ADDR ".word"
#define __UA_LA "la" #define __UA_LA "la"
...@@ -55,8 +59,13 @@ extern u64 __ua_limit; ...@@ -55,8 +59,13 @@ extern u64 __ua_limit;
* address in this range it's the process's problem, not ours :-) * address in this range it's the process's problem, not ours :-)
*/ */
#ifdef CONFIG_KVM_GUEST
#define KERNEL_DS ((mm_segment_t) { 0x80000000UL })
#define USER_DS ((mm_segment_t) { 0xC0000000UL })
#else
#define KERNEL_DS ((mm_segment_t) { 0UL }) #define KERNEL_DS ((mm_segment_t) { 0UL })
#define USER_DS ((mm_segment_t) { __UA_LIMIT }) #define USER_DS ((mm_segment_t) { __UA_LIMIT })
#endif
#define VERIFY_READ 0 #define VERIFY_READ 0
#define VERIFY_WRITE 1 #define VERIFY_WRITE 1
......
...@@ -48,7 +48,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ...@@ -48,7 +48,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
__res; \ __res; \
}) })
#ifdef CONFIG_KVM_GUEST
#define TASK32_SIZE 0x3fff8000UL
#else
#define TASK32_SIZE 0x7fff8000UL #define TASK32_SIZE 0x7fff8000UL
#endif
#undef ELF_ET_DYN_BASE #undef ELF_ET_DYN_BASE
#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
......
...@@ -118,6 +118,10 @@ int c0_compare_int_usable(void) ...@@ -118,6 +118,10 @@ int c0_compare_int_usable(void)
unsigned int delta; unsigned int delta;
unsigned int cnt; unsigned int cnt;
#ifdef CONFIG_KVM_GUEST
return 1;
#endif
/* /*
* IP7 already pending? Try to clear it by acking the timer. * IP7 already pending? Try to clear it by acking the timer.
*/ */
......
...@@ -1713,7 +1713,12 @@ void __init trap_init(void) ...@@ -1713,7 +1713,12 @@ void __init trap_init(void)
ebase = (unsigned long) ebase = (unsigned long)
__alloc_bootmem(size, 1 << fls(size), 0); __alloc_bootmem(size, 1 << fls(size), 0);
} else { } else {
ebase = CKSEG0; #ifdef CONFIG_KVM_GUEST
#define KVM_GUEST_KSEG0 0x40000000
ebase = KVM_GUEST_KSEG0;
#else
ebase = CKSEG0;
#endif
if (cpu_has_mips_r2) if (cpu_has_mips_r2)
ebase += (read_c0_ebase() & 0x3ffff000); ebase += (read_c0_ebase() & 0x3ffff000);
} }
......
...@@ -76,6 +76,21 @@ static void __init estimate_frequencies(void) ...@@ -76,6 +76,21 @@ static void __init estimate_frequencies(void)
unsigned int count, start; unsigned int count, start;
unsigned int giccount = 0, gicstart = 0; unsigned int giccount = 0, gicstart = 0;
#if defined (CONFIG_KVM_GUEST) && defined (CONFIG_KVM_HOST_FREQ)
unsigned int prid = read_c0_prid() & 0xffff00;
/*
* XXXKYMA: hardwire the CPU frequency to Host Freq/4
*/
count = (CONFIG_KVM_HOST_FREQ * 1000000) >> 3;
if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
count *= 2;
mips_hpt_frequency = count;
return;
#endif
local_irq_save(flags); local_irq_save(flags);
/* Start counter exactly on falling edge of update flag. */ /* Start counter exactly on falling edge of update flag. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment