diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:23:45 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:23:45 -0400 |
| commit | 1f0918d03ff4b5c94540c71ce889672abdbc2f4a (patch) | |
| tree | ecee710444fb3405da55933501e339e10e4ac880 /drivers/lguest | |
| parent | 4266c97a3ef4604561a22212eb0eab8a3c338971 (diff) | |
| parent | ca60a42c9be41c07ebcc2ec8c43dd1be53f147bf (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
lguest: don't force VIRTIO_F_NOTIFY_ON_EMPTY
lguest: cleanup for map_switcher()
lguest: use PGDIR_SHIFT for PAE code to allow different PAGE_OFFSET
lguest: use set_pte/set_pmd uniformly for real page table entries
lguest: move panic notifier registration to its expected place.
virtio_blk: add support for cache flush
virtio: add virtio IDs file
virtio: get rid of redundant VIRTIO_ID_9P definition
virtio: make add_buf return capacity remaining
virtio_pci: minor MSI-X cleanups
Diffstat (limited to 'drivers/lguest')
| -rw-r--r-- | drivers/lguest/core.c | 5 | ||||
| -rw-r--r-- | drivers/lguest/page_tables.c | 45 |
2 files changed, 21 insertions, 29 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 1e2cb846b3c9..8744d24ac6e6 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
| @@ -67,12 +67,11 @@ static __init int map_switcher(void) | |||
| 67 | * so we make sure they're zeroed. | 67 | * so we make sure they're zeroed. |
| 68 | */ | 68 | */ |
| 69 | for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) { | 69 | for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) { |
| 70 | unsigned long addr = get_zeroed_page(GFP_KERNEL); | 70 | switcher_page[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); |
| 71 | if (!addr) { | 71 | if (!switcher_page[i]) { |
| 72 | err = -ENOMEM; | 72 | err = -ENOMEM; |
| 73 | goto free_some_pages; | 73 | goto free_some_pages; |
| 74 | } | 74 | } |
| 75 | switcher_page[i] = virt_to_page(addr); | ||
| 76 | } | 75 | } |
| 77 | 76 | ||
| 78 | /* | 77 | /* |
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 8aaad65c3bb5..cf94326f1b59 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c | |||
| @@ -380,7 +380,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) | |||
| 380 | * And we copy the flags to the shadow PMD entry. The page | 380 | * And we copy the flags to the shadow PMD entry. The page |
| 381 | * number in the shadow PMD is the page we just allocated. | 381 | * number in the shadow PMD is the page we just allocated. |
| 382 | */ | 382 | */ |
| 383 | native_set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); | 383 | set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | /* | 386 | /* |
| @@ -447,7 +447,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) | |||
| 447 | * we will come back here when a write does actually occur, so | 447 | * we will come back here when a write does actually occur, so |
| 448 | * we can update the Guest's _PAGE_DIRTY flag. | 448 | * we can update the Guest's _PAGE_DIRTY flag. |
| 449 | */ | 449 | */ |
| 450 | native_set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); | 450 | set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); |
| 451 | 451 | ||
| 452 | /* | 452 | /* |
| 453 | * Finally, we write the Guest PTE entry back: we've set the | 453 | * Finally, we write the Guest PTE entry back: we've set the |
| @@ -528,7 +528,7 @@ static void release_pmd(pmd_t *spmd) | |||
| 528 | /* Now we can free the page of PTEs */ | 528 | /* Now we can free the page of PTEs */ |
| 529 | free_page((long)ptepage); | 529 | free_page((long)ptepage); |
| 530 | /* And zero out the PMD entry so we never release it twice. */ | 530 | /* And zero out the PMD entry so we never release it twice. */ |
| 531 | native_set_pmd(spmd, __pmd(0)); | 531 | set_pmd(spmd, __pmd(0)); |
| 532 | } | 532 | } |
| 533 | } | 533 | } |
| 534 | 534 | ||
| @@ -833,15 +833,15 @@ static void do_set_pte(struct lg_cpu *cpu, int idx, | |||
| 833 | */ | 833 | */ |
| 834 | if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) { | 834 | if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) { |
| 835 | check_gpte(cpu, gpte); | 835 | check_gpte(cpu, gpte); |
| 836 | native_set_pte(spte, | 836 | set_pte(spte, |
| 837 | gpte_to_spte(cpu, gpte, | 837 | gpte_to_spte(cpu, gpte, |
| 838 | pte_flags(gpte) & _PAGE_DIRTY)); | 838 | pte_flags(gpte) & _PAGE_DIRTY)); |
| 839 | } else { | 839 | } else { |
| 840 | /* | 840 | /* |
| 841 | * Otherwise kill it and we can demand_page() | 841 | * Otherwise kill it and we can demand_page() |
| 842 | * it in later. | 842 | * it in later. |
| 843 | */ | 843 | */ |
| 844 | native_set_pte(spte, __pte(0)); | 844 | set_pte(spte, __pte(0)); |
| 845 | } | 845 | } |
| 846 | #ifdef CONFIG_X86_PAE | 846 | #ifdef CONFIG_X86_PAE |
| 847 | } | 847 | } |
| @@ -983,25 +983,22 @@ static unsigned long setup_pagetables(struct lguest *lg, | |||
| 983 | */ | 983 | */ |
| 984 | for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD; | 984 | for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD; |
| 985 | i += PTRS_PER_PTE, j++) { | 985 | i += PTRS_PER_PTE, j++) { |
| 986 | /* FIXME: native_set_pmd is overkill here. */ | 986 | pmd = pfn_pmd(((unsigned long)&linear[i] - mem_base)/PAGE_SIZE, |
| 987 | native_set_pmd(&pmd, __pmd(((unsigned long)(linear + i) | 987 | __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER)); |
| 988 | - mem_base) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER)); | ||
| 989 | 988 | ||
| 990 | if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0) | 989 | if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0) |
| 991 | return -EFAULT; | 990 | return -EFAULT; |
| 992 | } | 991 | } |
| 993 | 992 | ||
| 994 | /* One PGD entry, pointing to that PMD page. */ | 993 | /* One PGD entry, pointing to that PMD page. */ |
| 995 | set_pgd(&pgd, __pgd(((u32)pmds - mem_base) | _PAGE_PRESENT)); | 994 | pgd = __pgd(((unsigned long)pmds - mem_base) | _PAGE_PRESENT); |
| 996 | /* Copy it in as the first PGD entry (ie. addresses 0-1G). */ | 995 | /* Copy it in as the first PGD entry (ie. addresses 0-1G). */ |
| 997 | if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0) | 996 | if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0) |
| 998 | return -EFAULT; | 997 | return -EFAULT; |
| 999 | /* | 998 | /* |
| 1000 | * And the third PGD entry (ie. addresses 3G-4G). | 999 | * And the other PGD entry to make the linear mapping at PAGE_OFFSET |
| 1001 | * | ||
| 1002 | * FIXME: This assumes that PAGE_OFFSET for the Guest is 0xC0000000. | ||
| 1003 | */ | 1000 | */ |
| 1004 | if (copy_to_user(&pgdir[3], &pgd, sizeof(pgd)) != 0) | 1001 | if (copy_to_user(&pgdir[KERNEL_PGD_BOUNDARY], &pgd, sizeof(pgd))) |
| 1005 | return -EFAULT; | 1002 | return -EFAULT; |
| 1006 | #else | 1003 | #else |
| 1007 | /* | 1004 | /* |
| @@ -1141,15 +1138,13 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) | |||
| 1141 | { | 1138 | { |
| 1142 | pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); | 1139 | pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); |
| 1143 | pte_t regs_pte; | 1140 | pte_t regs_pte; |
| 1144 | unsigned long pfn; | ||
| 1145 | 1141 | ||
| 1146 | #ifdef CONFIG_X86_PAE | 1142 | #ifdef CONFIG_X86_PAE |
| 1147 | pmd_t switcher_pmd; | 1143 | pmd_t switcher_pmd; |
| 1148 | pmd_t *pmd_table; | 1144 | pmd_t *pmd_table; |
| 1149 | 1145 | ||
| 1150 | /* FIXME: native_set_pmd is overkill here. */ | 1146 | switcher_pmd = pfn_pmd(__pa(switcher_pte_page) >> PAGE_SHIFT, |
| 1151 | native_set_pmd(&switcher_pmd, pfn_pmd(__pa(switcher_pte_page) >> | 1147 | PAGE_KERNEL_EXEC); |
| 1152 | PAGE_SHIFT, PAGE_KERNEL_EXEC)); | ||
| 1153 | 1148 | ||
| 1154 | /* Figure out where the pmd page is, by reading the PGD, and converting | 1149 | /* Figure out where the pmd page is, by reading the PGD, and converting |
| 1155 | * it to a virtual address. */ | 1150 | * it to a virtual address. */ |
| @@ -1157,7 +1152,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) | |||
| 1157 | pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX]) | 1152 | pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX]) |
| 1158 | << PAGE_SHIFT); | 1153 | << PAGE_SHIFT); |
| 1159 | /* Now write it into the shadow page table. */ | 1154 | /* Now write it into the shadow page table. */ |
| 1160 | native_set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd); | 1155 | set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd); |
| 1161 | #else | 1156 | #else |
| 1162 | pgd_t switcher_pgd; | 1157 | pgd_t switcher_pgd; |
| 1163 | 1158 | ||
| @@ -1179,10 +1174,8 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) | |||
| 1179 | * page is already mapped there, we don't have to copy them out | 1174 | * page is already mapped there, we don't have to copy them out |
| 1180 | * again. | 1175 | * again. |
| 1181 | */ | 1176 | */ |
| 1182 | pfn = __pa(cpu->regs_page) >> PAGE_SHIFT; | 1177 | regs_pte = pfn_pte(__pa(cpu->regs_page) >> PAGE_SHIFT, PAGE_KERNEL); |
| 1183 | native_set_pte(®s_pte, pfn_pte(pfn, PAGE_KERNEL)); | 1178 | set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], regs_pte); |
| 1184 | native_set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], | ||
| 1185 | regs_pte); | ||
| 1186 | } | 1179 | } |
| 1187 | /*:*/ | 1180 | /*:*/ |
| 1188 | 1181 | ||
| @@ -1209,7 +1202,7 @@ static __init void populate_switcher_pte_page(unsigned int cpu, | |||
| 1209 | 1202 | ||
| 1210 | /* The first entries are easy: they map the Switcher code. */ | 1203 | /* The first entries are easy: they map the Switcher code. */ |
| 1211 | for (i = 0; i < pages; i++) { | 1204 | for (i = 0; i < pages; i++) { |
| 1212 | native_set_pte(&pte[i], mk_pte(switcher_page[i], | 1205 | set_pte(&pte[i], mk_pte(switcher_page[i], |
| 1213 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); | 1206 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); |
| 1214 | } | 1207 | } |
| 1215 | 1208 | ||
| @@ -1217,14 +1210,14 @@ static __init void populate_switcher_pte_page(unsigned int cpu, | |||
| 1217 | i = pages + cpu*2; | 1210 | i = pages + cpu*2; |
| 1218 | 1211 | ||
| 1219 | /* First page (Guest registers) is writable from the Guest */ | 1212 | /* First page (Guest registers) is writable from the Guest */ |
| 1220 | native_set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]), | 1213 | set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]), |
| 1221 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW))); | 1214 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW))); |
| 1222 | 1215 | ||
| 1223 | /* | 1216 | /* |
| 1224 | * The second page contains the "struct lguest_ro_state", and is | 1217 | * The second page contains the "struct lguest_ro_state", and is |
| 1225 | * read-only. | 1218 | * read-only. |
| 1226 | */ | 1219 | */ |
| 1227 | native_set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]), | 1220 | set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]), |
| 1228 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); | 1221 | __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); |
| 1229 | } | 1222 | } |
| 1230 | 1223 | ||
