aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Dong <eddie.dong@intel.com>2007-07-17 04:52:33 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:17 -0400
commit65619eb5a88dae3dadbb1050f957ed357aa54a50 (patch)
tree4c9d83266f84d9eed29904d2022e0625816b9fe4
parent24cbc7e9cb0488095e4e144a762276c85ff55f9b (diff)
KVM: In-kernel string pio write support
Add string pio write support to support some version of Windows. Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/kvm_main.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index df9c05e9b34e..1be510b657fd 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1760,18 +1760,35 @@ static int complete_pio(struct kvm_vcpu *vcpu)
1760 return 0; 1760 return 0;
1761} 1761}
1762 1762
1763void kernel_pio(struct kvm_io_device *pio_dev, struct kvm_vcpu *vcpu) 1763static void kernel_pio(struct kvm_io_device *pio_dev,
1764 struct kvm_vcpu *vcpu,
1765 void *pd)
1764{ 1766{
1765 /* TODO: String I/O for in kernel device */ 1767 /* TODO: String I/O for in kernel device */
1766 1768
1767 if (vcpu->pio.in) 1769 if (vcpu->pio.in)
1768 kvm_iodevice_read(pio_dev, vcpu->pio.port, 1770 kvm_iodevice_read(pio_dev, vcpu->pio.port,
1769 vcpu->pio.size, 1771 vcpu->pio.size,
1770 vcpu->pio_data); 1772 pd);
1771 else 1773 else
1772 kvm_iodevice_write(pio_dev, vcpu->pio.port, 1774 kvm_iodevice_write(pio_dev, vcpu->pio.port,
1773 vcpu->pio.size, 1775 vcpu->pio.size,
1774 vcpu->pio_data); 1776 pd);
1777}
1778
1779static void pio_string_write(struct kvm_io_device *pio_dev,
1780 struct kvm_vcpu *vcpu)
1781{
1782 struct kvm_pio_request *io = &vcpu->pio;
1783 void *pd = vcpu->pio_data;
1784 int i;
1785
1786 for (i = 0; i < io->cur_count; i++) {
1787 kvm_iodevice_write(pio_dev, io->port,
1788 io->size,
1789 pd);
1790 pd += io->size;
1791 }
1775} 1792}
1776 1793
1777int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, 1794int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
@@ -1779,7 +1796,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1779 gva_t address, int rep, unsigned port) 1796 gva_t address, int rep, unsigned port)
1780{ 1797{
1781 unsigned now, in_page; 1798 unsigned now, in_page;
1782 int i; 1799 int i, ret = 0;
1783 int nr_pages = 1; 1800 int nr_pages = 1;
1784 struct page *page; 1801 struct page *page;
1785 struct kvm_io_device *pio_dev; 1802 struct kvm_io_device *pio_dev;
@@ -1806,15 +1823,12 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1806 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4); 1823 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
1807 kvm_arch_ops->decache_regs(vcpu); 1824 kvm_arch_ops->decache_regs(vcpu);
1808 if (pio_dev) { 1825 if (pio_dev) {
1809 kernel_pio(pio_dev, vcpu); 1826 kernel_pio(pio_dev, vcpu, vcpu->pio_data);
1810 complete_pio(vcpu); 1827 complete_pio(vcpu);
1811 return 1; 1828 return 1;
1812 } 1829 }
1813 return 0; 1830 return 0;
1814 } 1831 }
1815 /* TODO: String I/O for in kernel device */
1816 if (pio_dev)
1817 printk(KERN_ERR "kvm_setup_pio: no string io support\n");
1818 1832
1819 if (!count) { 1833 if (!count) {
1820 kvm_arch_ops->skip_emulated_instruction(vcpu); 1834 kvm_arch_ops->skip_emulated_instruction(vcpu);
@@ -1862,9 +1876,21 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1862 } 1876 }
1863 } 1877 }
1864 1878
1865 if (!vcpu->pio.in) 1879 if (!vcpu->pio.in) {
1866 return pio_copy_data(vcpu); 1880 /* string PIO write */
1867 return 0; 1881 ret = pio_copy_data(vcpu);
1882 if (ret >= 0 && pio_dev) {
1883 pio_string_write(pio_dev, vcpu);
1884 complete_pio(vcpu);
1885 if (vcpu->pio.count == 0)
1886 ret = 1;
1887 }
1888 } else if (pio_dev)
1889 printk(KERN_ERR "no string pio read support yet, "
1890 "port %x size %d count %ld\n",
1891 port, size, count);
1892
1893 return ret;
1868} 1894}
1869EXPORT_SYMBOL_GPL(kvm_setup_pio); 1895EXPORT_SYMBOL_GPL(kvm_setup_pio);
1870 1896