aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2018-09-10 15:37:34 -0400
committerRodrigo Vivi <rodrigo.vivi@intel.com>2018-09-10 15:37:35 -0400
commit50cbc03e509676a558cc9ac1c448d5c17beee2c2 (patch)
treebc7ada1f6c0aa39a4ccfb6d38b4954a2afa4d273
parent92a6803149465e2339f8f7f8f6415d75be80073d (diff)
parent792fab2c0d45758ad3d187bd252570d2bb627fa9 (diff)
Merge tag 'gvt-fixes-2018-09-10' of https://github.com/intel/gvt-linux into drm-intel-fixes
gvt-fixes-2018-09-10 - KVM mm access reference fix (Zhenyu) - Fix child device config length for virtual opregion (Weinan) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> From: Zhenyu Wang <zhenyuw@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180910092212.GZ20737@zhen-hp.sh.intel.com
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c10
-rw-r--r--drivers/gpu/drm/i915/gvt/opregion.c20
2 files changed, 17 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index a45f46d8537f..c7afee37b2b8 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -32,6 +32,7 @@
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/mmu_context.h> 34#include <linux/mmu_context.h>
35#include <linux/sched/mm.h>
35#include <linux/types.h> 36#include <linux/types.h>
36#include <linux/list.h> 37#include <linux/list.h>
37#include <linux/rbtree.h> 38#include <linux/rbtree.h>
@@ -1792,16 +1793,21 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
1792 info = (struct kvmgt_guest_info *)handle; 1793 info = (struct kvmgt_guest_info *)handle;
1793 kvm = info->kvm; 1794 kvm = info->kvm;
1794 1795
1795 if (kthread) 1796 if (kthread) {
1797 if (!mmget_not_zero(kvm->mm))
1798 return -EFAULT;
1796 use_mm(kvm->mm); 1799 use_mm(kvm->mm);
1800 }
1797 1801
1798 idx = srcu_read_lock(&kvm->srcu); 1802 idx = srcu_read_lock(&kvm->srcu);
1799 ret = write ? kvm_write_guest(kvm, gpa, buf, len) : 1803 ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
1800 kvm_read_guest(kvm, gpa, buf, len); 1804 kvm_read_guest(kvm, gpa, buf, len);
1801 srcu_read_unlock(&kvm->srcu, idx); 1805 srcu_read_unlock(&kvm->srcu, idx);
1802 1806
1803 if (kthread) 1807 if (kthread) {
1804 unuse_mm(kvm->mm); 1808 unuse_mm(kvm->mm);
1809 mmput(kvm->mm);
1810 }
1805 1811
1806 return ret; 1812 return ret;
1807} 1813}
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index fa75a2eead90..b0d3a43ccd03 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -42,8 +42,6 @@
42#define DEVICE_TYPE_EFP3 0x20 42#define DEVICE_TYPE_EFP3 0x20
43#define DEVICE_TYPE_EFP4 0x10 43#define DEVICE_TYPE_EFP4 0x10
44 44
45#define DEV_SIZE 38
46
47struct opregion_header { 45struct opregion_header {
48 u8 signature[16]; 46 u8 signature[16];
49 u32 size; 47 u32 size;
@@ -63,6 +61,10 @@ struct bdb_data_header {
63 u16 size; /* data size */ 61 u16 size; /* data size */
64} __packed; 62} __packed;
65 63
64/* For supporting windows guest with opregion, here hardcode the emulated
65 * bdb header version as '186', and the corresponding child_device_config
66 * length should be '33' but not '38'.
67 */
66struct efp_child_device_config { 68struct efp_child_device_config {
67 u16 handle; 69 u16 handle;
68 u16 device_type; 70 u16 device_type;
@@ -109,12 +111,6 @@ struct efp_child_device_config {
109 u8 mipi_bridge_type; /* 171 */ 111 u8 mipi_bridge_type; /* 171 */
110 u16 device_class_ext; 112 u16 device_class_ext;
111 u8 dvo_function; 113 u8 dvo_function;
112 u8 dp_usb_type_c:1; /* 195 */
113 u8 skip6:7;
114 u8 dp_usb_type_c_2x_gpio_index; /* 195 */
115 u16 dp_usb_type_c_2x_gpio_pin; /* 195 */
116 u8 iboost_dp:4; /* 196 */
117 u8 iboost_hdmi:4; /* 196 */
118} __packed; 114} __packed;
119 115
120struct vbt { 116struct vbt {
@@ -155,7 +151,7 @@ static void virt_vbt_generation(struct vbt *v)
155 v->header.bdb_offset = offsetof(struct vbt, bdb_header); 151 v->header.bdb_offset = offsetof(struct vbt, bdb_header);
156 152
157 strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK"); 153 strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
158 v->bdb_header.version = 186; /* child_dev_size = 38 */ 154 v->bdb_header.version = 186; /* child_dev_size = 33 */
159 v->bdb_header.header_size = sizeof(v->bdb_header); 155 v->bdb_header.header_size = sizeof(v->bdb_header);
160 156
161 v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header) 157 v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
@@ -169,11 +165,13 @@ static void virt_vbt_generation(struct vbt *v)
169 165
170 /* child device */ 166 /* child device */
171 num_child = 4; /* each port has one child */ 167 num_child = 4; /* each port has one child */
168 v->general_definitions.child_dev_size =
169 sizeof(struct efp_child_device_config);
172 v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS; 170 v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS;
173 /* size will include child devices */ 171 /* size will include child devices */
174 v->general_definitions_header.size = 172 v->general_definitions_header.size =
175 sizeof(struct bdb_general_definitions) + num_child * DEV_SIZE; 173 sizeof(struct bdb_general_definitions) +
176 v->general_definitions.child_dev_size = DEV_SIZE; 174 num_child * v->general_definitions.child_dev_size;
177 175
178 /* portA */ 176 /* portA */
179 v->child0.handle = DEVICE_TYPE_EFP1; 177 v->child0.handle = DEVICE_TYPE_EFP1;