diff options
author | Sanjay Lal <sanjayl@kymasys.com> | 2012-11-21 21:34:03 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-05-07 21:55:35 -0400 |
commit | 9843b030cc951bce4a4d9bec38b5155c96eb1740 (patch) | |
tree | dd219e76dce1e1b92e6f5fc19e8767b60827c7ee /arch/mips | |
parent | 669e846e6c4e13f16d7418973609931e362cb16a (diff) |
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>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/mach-generic/spaces.h | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/mips/include/asm/uaccess.h | 11 | ||||
-rw-r--r-- | arch/mips/kernel/binfmt_elfo32.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-r4k.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 7 | ||||
-rw-r--r-- | arch/mips/mti-malta/malta-time.c | 15 |
7 files changed, 52 insertions, 3 deletions
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index 73d717a75cb0..5b2f2e68e57f 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h | |||
@@ -20,14 +20,21 @@ | |||
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef CONFIG_32BIT | 22 | #ifdef CONFIG_32BIT |
23 | 23 | #ifdef CONFIG_KVM_GUEST | |
24 | #define CAC_BASE _AC(0x40000000, UL) | ||
25 | #else | ||
24 | #define CAC_BASE _AC(0x80000000, UL) | 26 | #define CAC_BASE _AC(0x80000000, UL) |
27 | #endif | ||
25 | #define IO_BASE _AC(0xa0000000, UL) | 28 | #define IO_BASE _AC(0xa0000000, UL) |
26 | #define UNCAC_BASE _AC(0xa0000000, UL) | 29 | #define UNCAC_BASE _AC(0xa0000000, UL) |
27 | 30 | ||
28 | #ifndef MAP_BASE | 31 | #ifndef MAP_BASE |
32 | #ifdef CONFIG_KVM_GUEST | ||
33 | #define MAP_BASE _AC(0x60000000, UL) | ||
34 | #else | ||
29 | #define MAP_BASE _AC(0xc0000000, UL) | 35 | #define MAP_BASE _AC(0xc0000000, UL) |
30 | #endif | 36 | #endif |
37 | #endif | ||
31 | 38 | ||
32 | /* | 39 | /* |
33 | * Memory above this physical address will be considered highmem. | 40 | * Memory above this physical address will be considered highmem. |
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 2a5fa7abb346..71686c897dea 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -44,11 +44,16 @@ extern unsigned int vced_count, vcei_count; | |||
44 | #define SPECIAL_PAGES_SIZE PAGE_SIZE | 44 | #define SPECIAL_PAGES_SIZE PAGE_SIZE |
45 | 45 | ||
46 | #ifdef CONFIG_32BIT | 46 | #ifdef CONFIG_32BIT |
47 | #ifdef CONFIG_KVM_GUEST | ||
48 | /* User space process size is limited to 1GB in KVM Guest Mode */ | ||
49 | #define TASK_SIZE 0x3fff8000UL | ||
50 | #else | ||
47 | /* | 51 | /* |
48 | * User space process size: 2GB. This is hardcoded into a few places, | 52 | * User space process size: 2GB. This is hardcoded into a few places, |
49 | * so don't change it unless you know what you are doing. | 53 | * so don't change it unless you know what you are doing. |
50 | */ | 54 | */ |
51 | #define TASK_SIZE 0x7fff8000UL | 55 | #define TASK_SIZE 0x7fff8000UL |
56 | #endif | ||
52 | 57 | ||
53 | #ifdef __KERNEL__ | 58 | #ifdef __KERNEL__ |
54 | #define STACK_TOP_MAX TASK_SIZE | 59 | #define STACK_TOP_MAX TASK_SIZE |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index bd87e36bf26a..b46caab453a5 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -23,7 +23,11 @@ | |||
23 | */ | 23 | */ |
24 | #ifdef CONFIG_32BIT | 24 | #ifdef CONFIG_32BIT |
25 | 25 | ||
26 | #define __UA_LIMIT 0x80000000UL | 26 | #ifdef CONFIG_KVM_GUEST |
27 | #define __UA_LIMIT 0x40000000UL | ||
28 | #else | ||
29 | #define __UA_LIMIT 0x80000000UL | ||
30 | #endif | ||
27 | 31 | ||
28 | #define __UA_ADDR ".word" | 32 | #define __UA_ADDR ".word" |
29 | #define __UA_LA "la" | 33 | #define __UA_LA "la" |
@@ -55,8 +59,13 @@ extern u64 __ua_limit; | |||
55 | * address in this range it's the process's problem, not ours :-) | 59 | * address in this range it's the process's problem, not ours :-) |
56 | */ | 60 | */ |
57 | 61 | ||
62 | #ifdef CONFIG_KVM_GUEST | ||
63 | #define KERNEL_DS ((mm_segment_t) { 0x80000000UL }) | ||
64 | #define USER_DS ((mm_segment_t) { 0xC0000000UL }) | ||
65 | #else | ||
58 | #define KERNEL_DS ((mm_segment_t) { 0UL }) | 66 | #define KERNEL_DS ((mm_segment_t) { 0UL }) |
59 | #define USER_DS ((mm_segment_t) { __UA_LIMIT }) | 67 | #define USER_DS ((mm_segment_t) { __UA_LIMIT }) |
68 | #endif | ||
60 | 69 | ||
61 | #define VERIFY_READ 0 | 70 | #define VERIFY_READ 0 |
62 | #define VERIFY_WRITE 1 | 71 | #define VERIFY_WRITE 1 |
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 556a4357d7fc..97c5a1668e53 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c | |||
@@ -48,7 +48,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
48 | __res; \ | 48 | __res; \ |
49 | }) | 49 | }) |
50 | 50 | ||
51 | #ifdef CONFIG_KVM_GUEST | ||
52 | #define TASK32_SIZE 0x3fff8000UL | ||
53 | #else | ||
51 | #define TASK32_SIZE 0x7fff8000UL | 54 | #define TASK32_SIZE 0x7fff8000UL |
55 | #endif | ||
52 | #undef ELF_ET_DYN_BASE | 56 | #undef ELF_ET_DYN_BASE |
53 | #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) | 57 | #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
54 | 58 | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 07b847d77f5d..fd75d7144524 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -118,6 +118,10 @@ int c0_compare_int_usable(void) | |||
118 | unsigned int delta; | 118 | unsigned int delta; |
119 | unsigned int cnt; | 119 | unsigned int cnt; |
120 | 120 | ||
121 | #ifdef CONFIG_KVM_GUEST | ||
122 | return 1; | ||
123 | #endif | ||
124 | |||
121 | /* | 125 | /* |
122 | * IP7 already pending? Try to clear it by acking the timer. | 126 | * IP7 already pending? Try to clear it by acking the timer. |
123 | */ | 127 | */ |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index a200b5bdbb87..59351e5d0591 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1713,7 +1713,12 @@ void __init trap_init(void) | |||
1713 | ebase = (unsigned long) | 1713 | ebase = (unsigned long) |
1714 | __alloc_bootmem(size, 1 << fls(size), 0); | 1714 | __alloc_bootmem(size, 1 << fls(size), 0); |
1715 | } else { | 1715 | } else { |
1716 | ebase = CKSEG0; | 1716 | #ifdef CONFIG_KVM_GUEST |
1717 | #define KVM_GUEST_KSEG0 0x40000000 | ||
1718 | ebase = KVM_GUEST_KSEG0; | ||
1719 | #else | ||
1720 | ebase = CKSEG0; | ||
1721 | #endif | ||
1717 | if (cpu_has_mips_r2) | 1722 | if (cpu_has_mips_r2) |
1718 | ebase += (read_c0_ebase() & 0x3ffff000); | 1723 | ebase += (read_c0_ebase() & 0x3ffff000); |
1719 | } | 1724 | } |
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index a144b89cf9ba..bc6ac00c0d57 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -76,6 +76,21 @@ static void __init estimate_frequencies(void) | |||
76 | unsigned int count, start; | 76 | unsigned int count, start; |
77 | unsigned int giccount = 0, gicstart = 0; | 77 | unsigned int giccount = 0, gicstart = 0; |
78 | 78 | ||
79 | #if defined (CONFIG_KVM_GUEST) && defined (CONFIG_KVM_HOST_FREQ) | ||
80 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
81 | |||
82 | /* | ||
83 | * XXXKYMA: hardwire the CPU frequency to Host Freq/4 | ||
84 | */ | ||
85 | count = (CONFIG_KVM_HOST_FREQ * 1000000) >> 3; | ||
86 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
87 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
88 | count *= 2; | ||
89 | |||
90 | mips_hpt_frequency = count; | ||
91 | return; | ||
92 | #endif | ||
93 | |||
79 | local_irq_save(flags); | 94 | local_irq_save(flags); |
80 | 95 | ||
81 | /* Start counter exactly on falling edge of update flag. */ | 96 | /* Start counter exactly on falling edge of update flag. */ |