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: Sanjay Lal <sanjayl@kymasys.com> Cc: kvm@vger.kernel.org Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
669e846e6c
commit
9843b030cc
|
@ -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;
|
||||||
#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 @@
|
||||||
*/
|
*/
|
||||||
#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;
|
||||||
* 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];
|
||||||
__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)
|
||||||
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)
|
||||||
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)
|
||||||
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. */
|
||||||
|
|
Loading…
Reference in New Issue