aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2013-05-07 19:27:46 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-05-07 19:27:46 -0400
commit9b3539e0e545e4c2f338acfc1ce52033a6f5e7f7 (patch)
tree5c56e4a208dbe7e985e59911e1a421a7c1ee024c /virt
parent3d39019a1655d195a60a86ebf38f9da30bd83d03 (diff)
parent1cd1c049271233deccfcc75123afa7f39a607f5a (diff)
Merge branch 'mips-next-3.10' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/ioapic.c7
-rw-r--r--virt/kvm/kvm_main.c47
2 files changed, 42 insertions, 12 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index ce82b9401958..5ba005c00e2f 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -74,9 +74,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
74 u32 redir_index = (ioapic->ioregsel - 0x10) >> 1; 74 u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
75 u64 redir_content; 75 u64 redir_content;
76 76
77 ASSERT(redir_index < IOAPIC_NUM_PINS); 77 if (redir_index < IOAPIC_NUM_PINS)
78 redir_content =
79 ioapic->redirtbl[redir_index].bits;
80 else
81 redir_content = ~0ULL;
78 82
79 redir_content = ioapic->redirtbl[redir_index].bits;
80 result = (ioapic->ioregsel & 0x1) ? 83 result = (ioapic->ioregsel & 0x1) ?
81 (redir_content >> 32) & 0xffffffff : 84 (redir_content >> 32) & 0xffffffff :
82 redir_content & 0xffffffff; 85 redir_content & 0xffffffff;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index adc68feb5c5a..f18013f09e68 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1541,21 +1541,38 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
1541} 1541}
1542 1542
1543int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, 1543int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
1544 gpa_t gpa) 1544 gpa_t gpa, unsigned long len)
1545{ 1545{
1546 struct kvm_memslots *slots = kvm_memslots(kvm); 1546 struct kvm_memslots *slots = kvm_memslots(kvm);
1547 int offset = offset_in_page(gpa); 1547 int offset = offset_in_page(gpa);
1548 gfn_t gfn = gpa >> PAGE_SHIFT; 1548 gfn_t start_gfn = gpa >> PAGE_SHIFT;
1549 gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT;
1550 gfn_t nr_pages_needed = end_gfn - start_gfn + 1;
1551 gfn_t nr_pages_avail;
1549 1552
1550 ghc->gpa = gpa; 1553 ghc->gpa = gpa;
1551 ghc->generation = slots->generation; 1554 ghc->generation = slots->generation;
1552 ghc->memslot = gfn_to_memslot(kvm, gfn); 1555 ghc->len = len;
1553 ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL); 1556 ghc->memslot = gfn_to_memslot(kvm, start_gfn);
1554 if (!kvm_is_error_hva(ghc->hva)) 1557 ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail);
1558 if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) {
1555 ghc->hva += offset; 1559 ghc->hva += offset;
1556 else 1560 } else {
1557 return -EFAULT; 1561 /*
1558 1562 * If the requested region crosses two memslots, we still
1563 * verify that the entire region is valid here.
1564 */
1565 while (start_gfn <= end_gfn) {
1566 ghc->memslot = gfn_to_memslot(kvm, start_gfn);
1567 ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn,
1568 &nr_pages_avail);
1569 if (kvm_is_error_hva(ghc->hva))
1570 return -EFAULT;
1571 start_gfn += nr_pages_avail;
1572 }
1573 /* Use the slow path for cross page reads and writes. */
1574 ghc->memslot = NULL;
1575 }
1559 return 0; 1576 return 0;
1560} 1577}
1561EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init); 1578EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
@@ -1566,8 +1583,13 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
1566 struct kvm_memslots *slots = kvm_memslots(kvm); 1583 struct kvm_memslots *slots = kvm_memslots(kvm);
1567 int r; 1584 int r;
1568 1585
1586 BUG_ON(len > ghc->len);
1587
1569 if (slots->generation != ghc->generation) 1588 if (slots->generation != ghc->generation)
1570 kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); 1589 kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
1590
1591 if (unlikely(!ghc->memslot))
1592 return kvm_write_guest(kvm, ghc->gpa, data, len);
1571 1593
1572 if (kvm_is_error_hva(ghc->hva)) 1594 if (kvm_is_error_hva(ghc->hva))
1573 return -EFAULT; 1595 return -EFAULT;
@@ -1587,8 +1609,13 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
1587 struct kvm_memslots *slots = kvm_memslots(kvm); 1609 struct kvm_memslots *slots = kvm_memslots(kvm);
1588 int r; 1610 int r;
1589 1611
1612 BUG_ON(len > ghc->len);
1613
1590 if (slots->generation != ghc->generation) 1614 if (slots->generation != ghc->generation)
1591 kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); 1615 kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
1616
1617 if (unlikely(!ghc->memslot))
1618 return kvm_read_guest(kvm, ghc->gpa, data, len);
1592 1619
1593 if (kvm_is_error_hva(ghc->hva)) 1620 if (kvm_is_error_hva(ghc->hva))
1594 return -EFAULT; 1621 return -EFAULT;