Commit ac2bf28a authored by Rodrigo Vivi's avatar Rodrigo Vivi

Merge tag 'gvt-next-2018-06-19' of https://github.com/intel/gvt-linux into drm-intel-next-queued

gvt-next-2018-06-19

- fine-grained per vgpu locking (Colin)
- fine-grained vgpu scheduler locking (Colin)
- deliver windows guest cursor hotspot info (Tina)
- GVT-g BXT support (Colin)
- other misc and checker fixes (Chris, Xinyun)
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180619090043.ly6gquafbmxuus6h@zhen-hp.sh.intel.com
parents 1c3eced3 57c8a484
...@@ -172,6 +172,7 @@ struct decode_info { ...@@ -172,6 +172,7 @@ struct decode_info {
#define OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD OP_3D_MEDIA(0x2, 0x0, 0x2) #define OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD OP_3D_MEDIA(0x2, 0x0, 0x2)
#define OP_MEDIA_GATEWAY_STATE OP_3D_MEDIA(0x2, 0x0, 0x3) #define OP_MEDIA_GATEWAY_STATE OP_3D_MEDIA(0x2, 0x0, 0x3)
#define OP_MEDIA_STATE_FLUSH OP_3D_MEDIA(0x2, 0x0, 0x4) #define OP_MEDIA_STATE_FLUSH OP_3D_MEDIA(0x2, 0x0, 0x4)
#define OP_MEDIA_POOL_STATE OP_3D_MEDIA(0x2, 0x0, 0x5)
#define OP_MEDIA_OBJECT OP_3D_MEDIA(0x2, 0x1, 0x0) #define OP_MEDIA_OBJECT OP_3D_MEDIA(0x2, 0x1, 0x0)
#define OP_MEDIA_OBJECT_PRT OP_3D_MEDIA(0x2, 0x1, 0x2) #define OP_MEDIA_OBJECT_PRT OP_3D_MEDIA(0x2, 0x1, 0x2)
...@@ -1256,7 +1257,9 @@ static int gen8_check_mi_display_flip(struct parser_exec_state *s, ...@@ -1256,7 +1257,9 @@ static int gen8_check_mi_display_flip(struct parser_exec_state *s,
if (!info->async_flip) if (!info->async_flip)
return 0; return 0;
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) {
stride = vgpu_vreg_t(s->vgpu, info->stride_reg) & GENMASK(9, 0); stride = vgpu_vreg_t(s->vgpu, info->stride_reg) & GENMASK(9, 0);
tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) & tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) &
GENMASK(12, 10)) >> 10; GENMASK(12, 10)) >> 10;
...@@ -1284,7 +1287,9 @@ static int gen8_update_plane_mmio_from_mi_display_flip( ...@@ -1284,7 +1287,9 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
set_mask_bits(&vgpu_vreg_t(vgpu, info->surf_reg), GENMASK(31, 12), set_mask_bits(&vgpu_vreg_t(vgpu, info->surf_reg), GENMASK(31, 12),
info->surf_val << 12); info->surf_val << 12);
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) {
set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(9, 0), set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(9, 0),
info->stride_val); info->stride_val);
set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(12, 10), set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(12, 10),
...@@ -1308,7 +1313,9 @@ static int decode_mi_display_flip(struct parser_exec_state *s, ...@@ -1308,7 +1313,9 @@ static int decode_mi_display_flip(struct parser_exec_state *s,
if (IS_BROADWELL(dev_priv)) if (IS_BROADWELL(dev_priv))
return gen8_decode_mi_display_flip(s, info); return gen8_decode_mi_display_flip(s, info);
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv))
return skl_decode_mi_display_flip(s, info); return skl_decode_mi_display_flip(s, info);
return -ENODEV; return -ENODEV;
...@@ -1317,26 +1324,14 @@ static int decode_mi_display_flip(struct parser_exec_state *s, ...@@ -1317,26 +1324,14 @@ static int decode_mi_display_flip(struct parser_exec_state *s,
static int check_mi_display_flip(struct parser_exec_state *s, static int check_mi_display_flip(struct parser_exec_state *s,
struct mi_display_flip_command_info *info) struct mi_display_flip_command_info *info)
{ {
struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
if (IS_BROADWELL(dev_priv)
|| IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv))
return gen8_check_mi_display_flip(s, info); return gen8_check_mi_display_flip(s, info);
return -ENODEV;
} }
static int update_plane_mmio_from_mi_display_flip( static int update_plane_mmio_from_mi_display_flip(
struct parser_exec_state *s, struct parser_exec_state *s,
struct mi_display_flip_command_info *info) struct mi_display_flip_command_info *info)
{ {
struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
if (IS_BROADWELL(dev_priv)
|| IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv))
return gen8_update_plane_mmio_from_mi_display_flip(s, info); return gen8_update_plane_mmio_from_mi_display_flip(s, info);
return -ENODEV;
} }
static int cmd_handler_mi_display_flip(struct parser_exec_state *s) static int cmd_handler_mi_display_flip(struct parser_exec_state *s)
...@@ -1615,15 +1610,10 @@ static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm, ...@@ -1615,15 +1610,10 @@ static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
*/ */
static int batch_buffer_needs_scan(struct parser_exec_state *s) static int batch_buffer_needs_scan(struct parser_exec_state *s)
{ {
struct intel_gvt *gvt = s->vgpu->gvt; /* Decide privilege based on address space */
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv)) {
/* BDW decides privilege based on address space */
if (cmd_val(s, 0) & (1 << 8) && if (cmd_val(s, 0) & (1 << 8) &&
!(s->vgpu->scan_nonprivbb & (1 << s->ring_id))) !(s->vgpu->scan_nonprivbb & (1 << s->ring_id)))
return 0; return 0;
}
return 1; return 1;
} }
...@@ -2349,6 +2339,9 @@ static struct cmd_info cmd_info[] = { ...@@ -2349,6 +2339,9 @@ static struct cmd_info cmd_info[] = {
{"MEDIA_STATE_FLUSH", OP_MEDIA_STATE_FLUSH, F_LEN_VAR, R_RCS, D_ALL, {"MEDIA_STATE_FLUSH", OP_MEDIA_STATE_FLUSH, F_LEN_VAR, R_RCS, D_ALL,
0, 16, NULL}, 0, 16, NULL},
{"MEDIA_POOL_STATE", OP_MEDIA_POOL_STATE, F_LEN_VAR, R_RCS, D_ALL,
0, 16, NULL},
{"MEDIA_OBJECT", OP_MEDIA_OBJECT, F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL}, {"MEDIA_OBJECT", OP_MEDIA_OBJECT, F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
{"MEDIA_CURBE_LOAD", OP_MEDIA_CURBE_LOAD, F_LEN_VAR, R_RCS, D_ALL, {"MEDIA_CURBE_LOAD", OP_MEDIA_CURBE_LOAD, F_LEN_VAR, R_RCS, D_ALL,
......
...@@ -171,6 +171,29 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) ...@@ -171,6 +171,29 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
int pipe; int pipe;
if (IS_BROXTON(dev_priv)) {
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~(BXT_DE_PORT_HP_DDIA |
BXT_DE_PORT_HP_DDIB |
BXT_DE_PORT_HP_DDIC);
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
BXT_DE_PORT_HP_DDIA;
}
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
BXT_DE_PORT_HP_DDIB;
}
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
BXT_DE_PORT_HP_DDIC;
}
return;
}
vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT | vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
SDE_PORTC_HOTPLUG_CPT | SDE_PORTC_HOTPLUG_CPT |
SDE_PORTD_HOTPLUG_CPT); SDE_PORTD_HOTPLUG_CPT);
...@@ -337,26 +360,28 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt) ...@@ -337,26 +360,28 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt)
struct intel_gvt_irq *irq = &gvt->irq; struct intel_gvt_irq *irq = &gvt->irq;
struct intel_vgpu *vgpu; struct intel_vgpu *vgpu;
int pipe, id; int pipe, id;
int found = false;
if (WARN_ON(!mutex_is_locked(&gvt->lock))) mutex_lock(&gvt->lock);
return;
for_each_active_vgpu(gvt, vgpu, id) { for_each_active_vgpu(gvt, vgpu, id) {
for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) { for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) {
if (pipe_is_enabled(vgpu, pipe)) if (pipe_is_enabled(vgpu, pipe)) {
goto out; found = true;
break;
}
} }
if (found)
break;
} }
/* all the pipes are disabled */ /* all the pipes are disabled */
if (!found)
hrtimer_cancel(&irq->vblank_timer.timer); hrtimer_cancel(&irq->vblank_timer.timer);
return; else
out:
hrtimer_start(&irq->vblank_timer.timer, hrtimer_start(&irq->vblank_timer.timer,
ktime_add_ns(ktime_get(), irq->vblank_timer.period), ktime_add_ns(ktime_get(), irq->vblank_timer.period),
HRTIMER_MODE_ABS); HRTIMER_MODE_ABS);
mutex_unlock(&gvt->lock);
} }
static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe) static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
...@@ -393,8 +418,10 @@ static void emulate_vblank(struct intel_vgpu *vgpu) ...@@ -393,8 +418,10 @@ static void emulate_vblank(struct intel_vgpu *vgpu)
{ {
int pipe; int pipe;
mutex_lock(&vgpu->vgpu_lock);
for_each_pipe(vgpu->gvt->dev_priv, pipe) for_each_pipe(vgpu->gvt->dev_priv, pipe)
emulate_vblank_on_pipe(vgpu, pipe); emulate_vblank_on_pipe(vgpu, pipe);
mutex_unlock(&vgpu->vgpu_lock);
} }
/** /**
...@@ -409,11 +436,10 @@ void intel_gvt_emulate_vblank(struct intel_gvt *gvt) ...@@ -409,11 +436,10 @@ void intel_gvt_emulate_vblank(struct intel_gvt *gvt)
struct intel_vgpu *vgpu; struct intel_vgpu *vgpu;
int id; int id;
if (WARN_ON(!mutex_is_locked(&gvt->lock))) mutex_lock(&gvt->lock);
return;
for_each_active_vgpu(gvt, vgpu, id) for_each_active_vgpu(gvt, vgpu, id)
emulate_vblank(vgpu); emulate_vblank(vgpu);
mutex_unlock(&gvt->lock);
} }
/** /**
......
...@@ -164,7 +164,9 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev, ...@@ -164,7 +164,9 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
obj->read_domains = I915_GEM_DOMAIN_GTT; obj->read_domains = I915_GEM_DOMAIN_GTT;
obj->write_domain = 0; obj->write_domain = 0;
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) {
unsigned int tiling_mode = 0; unsigned int tiling_mode = 0;
unsigned int stride = 0; unsigned int stride = 0;
...@@ -192,6 +194,14 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev, ...@@ -192,6 +194,14 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
return obj; return obj;
} }
static bool validate_hotspot(struct intel_vgpu_cursor_plane_format *c)
{
if (c && c->x_hot <= c->width && c->y_hot <= c->height)
return true;
else
return false;
}
static int vgpu_get_plane_info(struct drm_device *dev, static int vgpu_get_plane_info(struct drm_device *dev,
struct intel_vgpu *vgpu, struct intel_vgpu *vgpu,
struct intel_vgpu_fb_info *info, struct intel_vgpu_fb_info *info,
...@@ -229,12 +239,14 @@ static int vgpu_get_plane_info(struct drm_device *dev, ...@@ -229,12 +239,14 @@ static int vgpu_get_plane_info(struct drm_device *dev,
info->x_pos = c.x_pos; info->x_pos = c.x_pos;
info->y_pos = c.y_pos; info->y_pos = c.y_pos;
/* The invalid cursor hotspot value is delivered to host if (validate_hotspot(&c)) {
* until we find a way to get the cursor hotspot info of info->x_hot = c.x_hot;
* guest OS. info->y_hot = c.y_hot;
*/ } else {
info->x_hot = UINT_MAX; info->x_hot = UINT_MAX;
info->y_hot = UINT_MAX; info->y_hot = UINT_MAX;
}
info->size = (((info->stride * c.height * c.bpp) / 8) info->size = (((info->stride * c.height * c.bpp) / 8)
+ (PAGE_SIZE - 1)) >> PAGE_SHIFT; + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
} else { } else {
......
...@@ -77,6 +77,20 @@ static unsigned char edid_get_byte(struct intel_vgpu *vgpu) ...@@ -77,6 +77,20 @@ static unsigned char edid_get_byte(struct intel_vgpu *vgpu)
return chr; return chr;
} }
static inline int bxt_get_port_from_gmbus0(u32 gmbus0)
{
int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
int port = -EINVAL;
if (port_select == 1)
port = PORT_B;
else if (port_select == 2)
port = PORT_C;
else if (port_select == 3)
port = PORT_D;
return port;
}
static inline int get_port_from_gmbus0(u32 gmbus0) static inline int get_port_from_gmbus0(u32 gmbus0)
{ {
int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK; int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
...@@ -105,6 +119,7 @@ static void reset_gmbus_controller(struct intel_vgpu *vgpu) ...@@ -105,6 +119,7 @@ static void reset_gmbus_controller(struct intel_vgpu *vgpu)
static int gmbus0_mmio_write(struct intel_vgpu *vgpu, static int gmbus0_mmio_write(struct intel_vgpu *vgpu,
unsigned int offset, void *p_data, unsigned int bytes) unsigned int offset, void *p_data, unsigned int bytes)
{ {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
int port, pin_select; int port, pin_select;
memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes); memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
...@@ -116,6 +131,9 @@ static int gmbus0_mmio_write(struct intel_vgpu *vgpu, ...@@ -116,6 +131,9 @@ static int gmbus0_mmio_write(struct intel_vgpu *vgpu,
if (pin_select == 0) if (pin_select == 0)
return 0; return 0;
if (IS_BROXTON(dev_priv))
port = bxt_get_port_from_gmbus0(pin_select);
else
port = get_port_from_gmbus0(pin_select); port = get_port_from_gmbus0(pin_select);
if (WARN_ON(port < 0)) if (WARN_ON(port < 0))
return 0; return 0;
......
...@@ -146,14 +146,11 @@ struct execlist_ring_context { ...@@ -146,14 +146,11 @@ struct execlist_ring_context {
u32 nop4; u32 nop4;
u32 lri_cmd_2; u32 lri_cmd_2;
struct execlist_mmio_pair ctx_timestamp; struct execlist_mmio_pair ctx_timestamp;
struct execlist_mmio_pair pdp3_UDW; /*
struct execlist_mmio_pair pdp3_LDW; * pdps[8]={ pdp3_UDW, pdp3_LDW, pdp2_UDW, pdp2_LDW,
struct execlist_mmio_pair pdp2_UDW; * pdp1_UDW, pdp1_LDW, pdp0_UDW, pdp0_LDW}
struct execlist_mmio_pair pdp2_LDW; */
struct execlist_mmio_pair pdp1_UDW; struct execlist_mmio_pair pdps[8];
struct execlist_mmio_pair pdp1_LDW;
struct execlist_mmio_pair pdp0_UDW;
struct execlist_mmio_pair pdp0_LDW;
}; };
struct intel_vgpu_elsp_dwords { struct intel_vgpu_elsp_dwords {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <uapi/drm/drm_fourcc.h> #include <uapi/drm/drm_fourcc.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h" #include "gvt.h"
#include "i915_pvinfo.h"
#define PRIMARY_FORMAT_NUM 16 #define PRIMARY_FORMAT_NUM 16
struct pixel_format { struct pixel_format {
...@@ -150,7 +151,9 @@ static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe, ...@@ -150,7 +151,9 @@ static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & stride_mask; u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & stride_mask;
u32 stride = stride_reg; u32 stride = stride_reg;
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) {
switch (tiled) { switch (tiled) {
case PLANE_CTL_TILED_LINEAR: case PLANE_CTL_TILED_LINEAR:
stride = stride_reg * 64; stride = stride_reg * 64;
...@@ -214,7 +217,9 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, ...@@ -214,7 +217,9 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
if (!plane->enabled) if (!plane->enabled)
return -ENODEV; return -ENODEV;
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) {
plane->tiled = (val & PLANE_CTL_TILED_MASK) >> plane->tiled = (val & PLANE_CTL_TILED_MASK) >>
_PLANE_CTL_TILED_SHIFT; _PLANE_CTL_TILED_SHIFT;
fmt = skl_format_to_drm( fmt = skl_format_to_drm(
...@@ -256,7 +261,9 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, ...@@ -256,7 +261,9 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
} }
plane->stride = intel_vgpu_get_stride(vgpu, pipe, (plane->tiled << 10), plane->stride = intel_vgpu_get_stride(vgpu, pipe, (plane->tiled << 10),
(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) ? (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv)) ?
(_PRI_PLANE_STRIDE_MASK >> 6) : (_PRI_PLANE_STRIDE_MASK >> 6) :
_PRI_PLANE_STRIDE_MASK, plane->bpp); _PRI_PLANE_STRIDE_MASK, plane->bpp);
...@@ -384,6 +391,8 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, ...@@ -384,6 +391,8 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT; plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT; plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT;
plane->x_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot));
plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot));
return 0; return 0;
} }
......
...@@ -162,7 +162,7 @@ static int verify_firmware(struct intel_gvt *gvt, ...@@ -162,7 +162,7 @@ static int verify_firmware(struct intel_gvt *gvt,
h = (struct gvt_firmware_header *)fw->data; h = (struct gvt_firmware_header *)fw->data;
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4; crc32_start = offsetofend(struct gvt_firmware_header, crc32);
mem = fw->data + crc32_start; mem = fw->data + crc32_start;
#define VERIFY(s, a, b) do { \ #define VERIFY(s, a, b) do { \
......
...@@ -1972,7 +1972,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu, ...@@ -1972,7 +1972,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
* GTT_TYPE_PPGTT_PDE_PT level pt, that means this scratch_pt it self * GTT_TYPE_PPGTT_PDE_PT level pt, that means this scratch_pt it self
* is GTT_TYPE_PPGTT_PTE_PT, and full filled by scratch page mfn. * is GTT_TYPE_PPGTT_PTE_PT, and full filled by scratch page mfn.
*/ */
if (type > GTT_TYPE_PPGTT_PTE_PT && type < GTT_TYPE_MAX) { if (type > GTT_TYPE_PPGTT_PTE_PT) {
struct intel_gvt_gtt_entry se; struct intel_gvt_gtt_entry se;
memset(&se, 0, sizeof(struct intel_gvt_gtt_entry)); memset(&se, 0, sizeof(struct intel_gvt_gtt_entry));
...@@ -2256,13 +2256,8 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) ...@@ -2256,13 +2256,8 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
gvt_dbg_core("init gtt\n"); gvt_dbg_core("init gtt\n");
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv)) {
gvt->gtt.pte_ops = &gen8_gtt_pte_ops; gvt->gtt.pte_ops = &gen8_gtt_pte_ops;
gvt->gtt.gma_ops = &gen8_gtt_gma_ops; gvt->gtt.gma_ops = &gen8_gtt_gma_ops;
} else {
return -ENODEV;
}
page = (void *)get_zeroed_page(GFP_KERNEL); page = (void *)get_zeroed_page(GFP_KERNEL);
if (!page) { if (!page) {
......
...@@ -238,8 +238,6 @@ static void init_device_info(struct intel_gvt *gvt) ...@@ -238,8 +238,6 @@ static void init_device_info(struct intel_gvt *gvt)
struct intel_gvt_device_info *info = &gvt->device_info; struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = gvt->dev_priv->drm.pdev; struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv)) {
info->max_support_vgpus = 8; info->max_support_vgpus = 8;
info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE; info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
info->mmio_size = 2 * 1024 * 1024; info->mmio_size = 2 * 1024 * 1024;
...@@ -249,7 +247,6 @@ static void init_device_info(struct intel_gvt *gvt) ...@@ -249,7 +247,6 @@ static void init_device_info(struct intel_gvt *gvt)
info->gtt_entry_size_shift = 3; info->gtt_entry_size_shift = 3;
info->gmadr_bytes_in_cmd = 8; info->gmadr_bytes_in_cmd = 8;
info->max_surface_size = 36 * 1024 * 1024; info->max_surface_size = 36 * 1024 * 1024;
}
info->msi_cap_offset = pdev->msi_cap; info->msi_cap_offset = pdev->msi_cap;
} }
...@@ -271,11 +268,8 @@ static int gvt_service_thread(void *data) ...@@ -271,11 +268,8 @@ static int gvt_service_thread(void *data)
continue; continue;
if (test_and_clear_bit(INTEL_GVT_REQUEST_EMULATE_VBLANK, if (test_and_clear_bit(INTEL_GVT_REQUEST_EMULATE_VBLANK,
(void *)&gvt->service_request)) { (void *)&gvt->service_request))
mutex_lock(&gvt->lock);
intel_gvt_emulate_vblank(gvt); intel_gvt_emulate_vblank(gvt);
mutex_unlock(&gvt->lock);
}
if (test_bit(INTEL_GVT_REQUEST_SCHED, if (test_bit(INTEL_GVT_REQUEST_SCHED,
(void *)&gvt->service_request) || (void *)&gvt->service_request) ||
...@@ -379,6 +373,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) ...@@ -379,6 +373,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
idr_init(&gvt->vgpu_idr); idr_init(&gvt->vgpu_idr);
spin_lock_init(&gvt->scheduler.mmio_context_lock); spin_lock_init(&gvt->scheduler.mmio_context_lock);
mutex_init(&gvt->lock); mutex_init(&gvt->lock);
mutex_init(&gvt->sched_lock);
gvt->dev_priv = dev_priv; gvt->dev_priv = dev_priv;
init_device_info(gvt); init_device_info(gvt);
......
...@@ -170,12 +170,18 @@ struct intel_vgpu_submission { ...@@ -170,12 +170,18 @@ struct intel_vgpu_submission {
struct intel_vgpu { struct intel_vgpu {
struct intel_gvt *gvt; struct intel_gvt *gvt;
struct mutex vgpu_lock;
int id; int id;
unsigned long handle; /* vGPU handle used by hypervisor MPT modules */ unsigned long handle; /* vGPU handle used by hypervisor MPT modules */
bool active; bool active;
bool pv_notified; bool pv_notified;
bool failsafe; bool failsafe;
unsigned int resetting_eng; unsigned int resetting_eng;
/* Both sched_data and sched_ctl can be seen a part of the global gvt
* scheduler structure. So below 2 vgpu data are protected
* by sched_lock, not vgpu_lock.
*/
void *sched_data; void *sched_data;
struct vgpu_sched_ctl sched_ctl; struct vgpu_sched_ctl sched_ctl;
...@@ -294,7 +300,13 @@ struct intel_vgpu_type { ...@@ -294,7 +300,13 @@ struct intel_vgpu_type {
}; };
struct intel_gvt { struct intel_gvt {
/* GVT scope lock, protect GVT itself, and all resource currently
* not yet protected by special locks(vgpu and scheduler lock).
*/
struct mutex lock; struct mutex lock;
/* scheduler scope lock, protect gvt and vgpu schedule related data */
struct mutex sched_lock;
struct drm_i915_private *dev_priv; struct drm_i915_private *dev_priv;
struct idr vgpu_idr; /* vGPU IDR pool */ struct idr vgpu_idr; /* vGPU IDR pool */
...@@ -314,6 +326,10 @@ struct intel_gvt { ...@@ -314,6 +326,10 @@ struct intel_gvt {
struct task_struct *service_thread; struct task_struct *service_thread;
wait_queue_head_t service_thread_wq; wait_queue_head_t service_thread_wq;
/* service_request is always used in bit operation, we should always
* use it with atomic bit ops so that no need to use gvt big lock.
*/
unsigned long service_request; unsigned long service_request;
struct { struct {
......
This diff is collapsed.
...@@ -350,7 +350,8 @@ static void update_upstream_irq(struct intel_vgpu *vgpu, ...@@ -350,7 +350,8 @@ static void update_upstream_irq(struct intel_vgpu *vgpu,
clear_bits |= (1 << bit); clear_bits |= (1 << bit);
} }
WARN_ON(!up_irq_info); if (WARN_ON(!up_irq_info))
return;
if (up_irq_info->group == INTEL_GVT_IRQ_INFO_MASTER) { if (up_irq_info->group == INTEL_GVT_IRQ_INFO_MASTER) {
u32 isr = i915_mmio_reg_offset(up_irq_info->reg_base); u32 isr = i915_mmio_reg_offset(up_irq_info->reg_base);
...@@ -580,7 +581,9 @@ static void gen8_init_irq( ...@@ -580,7 +581,9 @@ static void gen8_init_irq(
SET_BIT_INFO(irq, 4, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C); SET_BIT_INFO(irq, 4, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
SET_BIT_INFO(irq, 5, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C); SET_BIT_INFO(irq, 5, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
} else if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) { } else if (IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv)
|| IS_BROXTON(gvt->dev_priv)) {
SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_DE_PORT); SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_DE_PORT);
SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_DE_PORT); SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_DE_PORT);
SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_DE_PORT); SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_DE_PORT);
...@@ -690,14 +693,8 @@ int intel_gvt_init_irq(struct intel_gvt *gvt) ...@@ -690,14 +693,8 @@ int intel_gvt_init_irq(struct intel_gvt *gvt)
gvt_dbg_core("init irq framework\n"); gvt_dbg_core("init irq framework\n");
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv)) {
irq->ops = &gen8_irq_ops; irq->ops = &gen8_irq_ops;
irq->irq_map = gen8_irq_map; irq->irq_map = gen8_irq_map;
} else {
WARN_ON(1);
return -ENODEV;
}
/* common event initialization */ /* common event initialization */
init_events(irq); init_events(irq);
......
...@@ -67,7 +67,7 @@ static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -67,7 +67,7 @@ static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa,
return; return;
gvt = vgpu->gvt; gvt = vgpu->gvt;
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
if (reg_is_mmio(gvt, offset)) { if (reg_is_mmio(gvt, offset)) {
if (read) if (read)
...@@ -85,7 +85,7 @@ static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -85,7 +85,7 @@ static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa,
memcpy(pt, p_data, bytes); memcpy(pt, p_data, bytes);
} }
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
} }
/** /**
...@@ -109,7 +109,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -109,7 +109,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
failsafe_emulate_mmio_rw(vgpu, pa, p_data, bytes, true); failsafe_emulate_mmio_rw(vgpu, pa, p_data, bytes, true);
return 0; return 0;
} }
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
...@@ -156,7 +156,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -156,7 +156,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
gvt_vgpu_err("fail to emulate MMIO read %08x len %d\n", gvt_vgpu_err("fail to emulate MMIO read %08x len %d\n",
offset, bytes); offset, bytes);
out: out:
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
return ret; return ret;
} }
...@@ -182,7 +182,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -182,7 +182,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
return 0; return 0;
} }
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
...@@ -220,7 +220,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, ...@@ -220,7 +220,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
gvt_vgpu_err("fail to emulate MMIO write %08x len %d\n", offset, gvt_vgpu_err("fail to emulate MMIO write %08x len %d\n", offset,
bytes); bytes);
out: out:
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
return ret; return ret;
} }
......
...@@ -42,15 +42,16 @@ struct intel_vgpu; ...@@ -42,15 +42,16 @@ struct intel_vgpu;
#define D_BDW (1 << 0) #define D_BDW (1 << 0)
#define D_SKL (1 << 1) #define D_SKL (1 << 1)
#define D_KBL (1 << 2) #define D_KBL (1 << 2)
#define D_BXT (1 << 3)
#define D_GEN9PLUS (D_SKL | D_KBL) #define D_GEN9PLUS (D_SKL | D_KBL | D_BXT)
#define D_GEN8PLUS (D_BDW | D_SKL | D_KBL) #define D_GEN8PLUS (D_BDW | D_SKL | D_KBL | D_BXT)
#define D_SKL_PLUS (D_SKL | D_KBL) #define D_SKL_PLUS (D_SKL | D_KBL | D_BXT)
#define D_BDW_PLUS (D_BDW | D_SKL | D_KBL) #define D_BDW_PLUS (D_BDW | D_SKL | D_KBL | D_BXT)
#define D_PRE_SKL (D_BDW) #define D_PRE_SKL (D_BDW)
#define D_ALL (D_BDW | D_SKL | D_KBL) #define D_ALL (D_BDW | D_SKL | D_KBL | D_BXT)
typedef int (*gvt_mmio_func)(struct intel_vgpu *, unsigned int, void *, typedef int (*gvt_mmio_func)(struct intel_vgpu *, unsigned int, void *,
unsigned int); unsigned int);
......
...@@ -364,7 +364,8 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) ...@@ -364,7 +364,8 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
*/ */
fw = intel_uncore_forcewake_for_reg(dev_priv, reg, fw = intel_uncore_forcewake_for_reg(dev_priv, reg,
FW_REG_READ | FW_REG_WRITE); FW_REG_READ | FW_REG_WRITE);
if (ring_id == RCS && (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))) if (ring_id == RCS && (IS_SKYLAKE(dev_priv) ||
IS_KABYLAKE(dev_priv) || IS_BROXTON(dev_priv)))
fw |= FORCEWAKE_RENDER; fw |= FORCEWAKE_RENDER;
intel_uncore_forcewake_get(dev_priv, fw); intel_uncore_forcewake_get(dev_priv, fw);
...@@ -401,7 +402,7 @@ static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next, ...@@ -401,7 +402,7 @@ static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
return; return;
if (IS_KABYLAKE(dev_priv) && ring_id == RCS) if ((IS_KABYLAKE(dev_priv) || IS_BROXTON(dev_priv)) && ring_id == RCS)
return; return;
if (!pre && !gen9_render_mocs.initialized) if (!pre && !gen9_render_mocs.initialized)
...@@ -467,7 +468,9 @@ static void switch_mmio(struct intel_vgpu *pre, ...@@ -467,7 +468,9 @@ static void switch_mmio(struct intel_vgpu *pre,
u32 old_v, new_v; u32 old_v, new_v;
dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv; dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) if (IS_SKYLAKE(dev_priv)
|| IS_KABYLAKE(dev_priv)
|| IS_BROXTON(dev_priv))
switch_mocs(pre, next, ring_id); switch_mocs(pre, next, ring_id);
for (mmio = dev_priv->gvt->engine_mmio_list.mmio; for (mmio = dev_priv->gvt->engine_mmio_list.mmio;
...@@ -479,7 +482,8 @@ static void switch_mmio(struct intel_vgpu *pre, ...@@ -479,7 +482,8 @@ static void switch_mmio(struct intel_vgpu *pre,
* state image on kabylake, it's initialized by lri command and * state image on kabylake, it's initialized by lri command and
* save or restore with context together. * save or restore with context together.
*/ */
if (IS_KABYLAKE(dev_priv) && mmio->in_context) if ((IS_KABYLAKE(dev_priv) || IS_BROXTON(dev_priv))
&& mmio->in_context)
continue; continue;
// save // save
...@@ -574,7 +578,9 @@ void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt) ...@@ -574,7 +578,9 @@ void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt)
{ {
struct engine_mmio *mmio; struct engine_mmio *mmio;
if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) if (IS_SKYLAKE(gvt->dev_priv) ||
IS_KABYLAKE(gvt->dev_priv) ||
IS_BROXTON(gvt->dev_priv))
gvt->engine_mmio_list.mmio = gen9_engine_mmio_list; gvt->engine_mmio_list.mmio = gen9_engine_mmio_list;
else else
gvt->engine_mmio_list.mmio = gen8_engine_mmio_list; gvt->engine_mmio_list.mmio = gen8_engine_mmio_list;
......
...@@ -157,11 +157,10 @@ int intel_vgpu_disable_page_track(struct intel_vgpu *vgpu, unsigned long gfn) ...@@ -157,11 +157,10 @@ int intel_vgpu_disable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)
int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa, int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,
void *data, unsigned int bytes) void *data, unsigned int bytes)
{ {
struct intel_gvt *gvt = vgpu->gvt;
struct intel_vgpu_page_track *page_track; struct intel_vgpu_page_track *page_track;
int ret = 0; int ret = 0;
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
page_track = intel_vgpu_find_page_track(vgpu, gpa >> PAGE_SHIFT); page_track = intel_vgpu_find_page_track(vgpu, gpa >> PAGE_SHIFT);
if (!page_track) { if (!page_track) {
...@@ -179,6 +178,6 @@ int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa, ...@@ -179,6 +178,6 @@ int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,
} }
out: out:
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
return ret; return ret;
} }
...@@ -228,7 +228,7 @@ void intel_gvt_schedule(struct intel_gvt *gvt) ...@@ -228,7 +228,7 @@ void intel_gvt_schedule(struct intel_gvt *gvt)
struct gvt_sched_data *sched_data = gvt->scheduler.sched_data; struct gvt_sched_data *sched_data = gvt->scheduler.sched_data;
ktime_t cur_time; ktime_t cur_time;
mutex_lock(&gvt->lock); mutex_lock(&gvt->sched_lock);
cur_time = ktime_get(); cur_time = ktime_get();
if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED, if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED,
...@@ -244,7 +244,7 @@ void intel_gvt_schedule(struct intel_gvt *gvt) ...@@ -244,7 +244,7 @@ void intel_gvt_schedule(struct intel_gvt *gvt)
vgpu_update_timeslice(gvt->scheduler.current_vgpu, cur_time); vgpu_update_timeslice(gvt->scheduler.current_vgpu, cur_time);
tbs_sched_func(sched_data); tbs_sched_func(sched_data);
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->sched_lock);
} }
static enum hrtimer_restart tbs_timer_fn(struct hrtimer *timer_data) static enum hrtimer_restart tbs_timer_fn(struct hrtimer *timer_data)
...@@ -359,39 +359,65 @@ static struct intel_gvt_sched_policy_ops tbs_schedule_ops = { ...@@ -359,39 +359,65 @@ static struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
int intel_gvt_init_sched_policy(struct intel_gvt *gvt) int intel_gvt_init_sched_policy(struct intel_gvt *gvt)
{ {
int ret;
mutex_lock(&gvt->sched_lock);
gvt->scheduler.sched_ops = &tbs_schedule_ops; gvt->scheduler.sched_ops = &tbs_schedule_ops;
ret = gvt->scheduler.sched_ops->init(gvt);
mutex_unlock(&gvt->sched_lock);
return gvt->scheduler.sched_ops->init(gvt); return ret;
} }
void intel_gvt_clean_sched_policy(struct intel_gvt *gvt) void intel_gvt_clean_sched_policy(struct intel_gvt *gvt)
{ {
mutex_lock(&gvt->sched_lock);
gvt->scheduler.sched_ops->clean(gvt); gvt->scheduler.sched_ops->clean(gvt);
mutex_unlock(&gvt->sched_lock);
} }
/* for per-vgpu scheduler policy, there are 2 per-vgpu data:
* sched_data, and sched_ctl. We see these 2 data as part of
* the global scheduler which are proteced by gvt->sched_lock.
* Caller should make their decision if the vgpu_lock should
* be hold outside.
*/
int intel_vgpu_init_sched_policy(struct intel_vgpu *vgpu) int intel_vgpu_init_sched_policy(struct intel_vgpu *vgpu)
{ {
return vgpu->gvt->scheduler.sched_ops->init_vgpu(vgpu); int ret;
mutex_lock(&vgpu->gvt->sched_lock);
ret = vgpu->gvt->scheduler.sched_ops->init_vgpu(vgpu);
mutex_unlock(&vgpu->gvt->sched_lock);
return ret;
} }
void intel_vgpu_clean_sched_policy(struct intel_vgpu *vgpu) void intel_vgpu_clean_sched_policy(struct intel_vgpu *vgpu)
{ {
mutex_lock(&vgpu->gvt->sched_lock);
vgpu->gvt->scheduler.sched_ops->clean_vgpu(vgpu); vgpu->gvt->scheduler.sched_ops->clean_vgpu(vgpu);
mutex_unlock(&vgpu->gvt->sched_lock);
} }
void intel_vgpu_start_schedule(struct intel_vgpu *vgpu) void intel_vgpu_start_schedule(struct intel_vgpu *vgpu)
{ {
struct vgpu_sched_data *vgpu_data = vgpu->sched_data; struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
mutex_lock(&vgpu->gvt->sched_lock);
if (!vgpu_data->active) { if (!vgpu_data->active) {
gvt_dbg_core("vgpu%d: start schedule\n", vgpu->id); gvt_dbg_core("vgpu%d: start schedule\n", vgpu->id);
vgpu->gvt->scheduler.sched_ops->start_schedule(vgpu); vgpu->gvt->scheduler.sched_ops->start_schedule(vgpu);
} }
mutex_unlock(&vgpu->gvt->sched_lock);
} }
void intel_gvt_kick_schedule(struct intel_gvt *gvt) void intel_gvt_kick_schedule(struct intel_gvt *gvt)
{ {
mutex_lock(&gvt->sched_lock);
intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED); intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED);
mutex_unlock(&gvt->sched_lock);
} }
void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
...@@ -406,6 +432,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) ...@@ -406,6 +432,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id); gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
mutex_lock(&vgpu->gvt->sched_lock);
scheduler->sched_ops->stop_schedule(vgpu); scheduler->sched_ops->stop_schedule(vgpu);
if (scheduler->next_vgpu == vgpu) if (scheduler->next_vgpu == vgpu)
...@@ -425,4 +452,5 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) ...@@ -425,4 +452,5 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
} }
} }
spin_unlock_bh(&scheduler->mmio_context_lock); spin_unlock_bh(&scheduler->mmio_context_lock);
mutex_unlock(&vgpu->gvt->sched_lock);
} }
...@@ -45,11 +45,10 @@ static void set_context_pdp_root_pointer( ...@@ -45,11 +45,10 @@ static void set_context_pdp_root_pointer(
struct execlist_ring_context *ring_context, struct execlist_ring_context *ring_context,
u32 pdp[8]) u32 pdp[8])
{ {
struct execlist_mmio_pair *pdp_pair = &ring_context->pdp3_UDW;
int i; int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
pdp_pair[i].val = pdp[7 - i]; ring_context->pdps[i].val = pdp[7 - i];
} }
static void update_shadow_pdps(struct intel_vgpu_workload *workload) static void update_shadow_pdps(struct intel_vgpu_workload *workload)
...@@ -298,7 +297,8 @@ static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) ...@@ -298,7 +297,8 @@ static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload)
void *shadow_ring_buffer_va; void *shadow_ring_buffer_va;
u32 *cs; u32 *cs;
if (IS_KABYLAKE(req->i915) && is_inhibit_context(req->hw_context)) if ((IS_KABYLAKE(req->i915) || IS_BROXTON(req->i915))
&& is_inhibit_context(req->hw_context))
intel_vgpu_restore_inhibit_context(vgpu, req); intel_vgpu_restore_inhibit_context(vgpu, req);
/* allocate shadow ring buffer */ /* allocate shadow ring buffer */
...@@ -634,6 +634,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ...@@ -634,6 +634,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n", gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
ring_id, workload); ring_id, workload);
mutex_lock(&vgpu->vgpu_lock);
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
ret = intel_gvt_scan_and_shadow_workload(workload); ret = intel_gvt_scan_and_shadow_workload(workload);
...@@ -654,6 +655,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ...@@ -654,6 +655,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
} }
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
mutex_unlock(&vgpu->vgpu_lock);
return ret; return ret;
} }
...@@ -663,7 +665,7 @@ static struct intel_vgpu_workload *pick_next_workload( ...@@ -663,7 +665,7 @@ static struct intel_vgpu_workload *pick_next_workload(
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
struct intel_vgpu_workload *workload = NULL; struct intel_vgpu_workload *workload = NULL;
mutex_lock(&gvt->lock); mutex_lock(&gvt->sched_lock);
/* /*
* no current vgpu / will be scheduled out / no workload * no current vgpu / will be scheduled out / no workload
...@@ -709,7 +711,7 @@ static struct intel_vgpu_workload *pick_next_workload( ...@@ -709,7 +711,7 @@ static struct intel_vgpu_workload *pick_next_workload(
atomic_inc(&workload->vgpu->submission.running_workload_num); atomic_inc(&workload->vgpu->submission.running_workload_num);
out: out:
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->sched_lock);
return workload; return workload;
} }
...@@ -807,7 +809,8 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id) ...@@ -807,7 +809,8 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
struct i915_request *rq = workload->req; struct i915_request *rq = workload->req;
int event; int event;
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
mutex_lock(&gvt->sched_lock);
/* For the workload w/ request, needs to wait for the context /* For the workload w/ request, needs to wait for the context
* switch to make sure request is completed. * switch to make sure request is completed.
...@@ -883,7 +886,8 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id) ...@@ -883,7 +886,8 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
if (gvt->scheduler.need_reschedule) if (gvt->scheduler.need_reschedule)
intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED); intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED);
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->sched_lock);
mutex_unlock(&vgpu->vgpu_lock);
} }
struct workload_thread_param { struct workload_thread_param {
...@@ -901,7 +905,8 @@ static int workload_thread(void *priv) ...@@ -901,7 +905,8 @@ static int workload_thread(void *priv)
struct intel_vgpu *vgpu = NULL; struct intel_vgpu *vgpu = NULL;
int ret; int ret;
bool need_force_wake = IS_SKYLAKE(gvt->dev_priv) bool need_force_wake = IS_SKYLAKE(gvt->dev_priv)
|| IS_KABYLAKE(gvt->dev_priv); || IS_KABYLAKE(gvt->dev_priv)
|| IS_BROXTON(gvt->dev_priv);
DEFINE_WAIT_FUNC(wait, woken_wake_function); DEFINE_WAIT_FUNC(wait, woken_wake_function);
kfree(p); kfree(p);
...@@ -935,9 +940,7 @@ static int workload_thread(void *priv) ...@@ -935,9 +940,7 @@ static int workload_thread(void *priv)
intel_uncore_forcewake_get(gvt->dev_priv, intel_uncore_forcewake_get(gvt->dev_priv,
FORCEWAKE_ALL); FORCEWAKE_ALL);
mutex_lock(&gvt->lock);
ret = dispatch_workload(workload); ret = dispatch_workload(workload);
mutex_unlock(&gvt->lock);
if (ret) { if (ret) {
vgpu = workload->vgpu; vgpu = workload->vgpu;
...@@ -1228,7 +1231,7 @@ static void read_guest_pdps(struct intel_vgpu *vgpu, ...@@ -1228,7 +1231,7 @@ static void read_guest_pdps(struct intel_vgpu *vgpu,
u64 gpa; u64 gpa;
int i; int i;
gpa = ring_context_gpa + RING_CTX_OFF(pdp3_UDW.val); gpa = ring_context_gpa + RING_CTX_OFF(pdps[0].val);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
intel_gvt_hypervisor_read_gpa(vgpu, intel_gvt_hypervisor_read_gpa(vgpu,
......
...@@ -58,6 +58,9 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu) ...@@ -58,6 +58,9 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.fence_num)) = vgpu_fence_sz(vgpu); vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.fence_num)) = vgpu_fence_sz(vgpu);
vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot)) = UINT_MAX;
vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot)) = UINT_MAX;
gvt_dbg_core("Populate PVINFO PAGE for vGPU %d\n", vgpu->id); gvt_dbg_core("Populate PVINFO PAGE for vGPU %d\n", vgpu->id);
gvt_dbg_core("aperture base [GMADR] 0x%llx size 0x%llx\n", gvt_dbg_core("aperture base [GMADR] 0x%llx size 0x%llx\n",
vgpu_aperture_gmadr_base(vgpu), vgpu_aperture_sz(vgpu)); vgpu_aperture_gmadr_base(vgpu), vgpu_aperture_sz(vgpu));
...@@ -223,22 +226,20 @@ void intel_gvt_activate_vgpu(struct intel_vgpu *vgpu) ...@@ -223,22 +226,20 @@ void intel_gvt_activate_vgpu(struct intel_vgpu *vgpu)
*/ */
void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu) void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu)
{ {
struct intel_gvt *gvt = vgpu->gvt; mutex_lock(&vgpu->vgpu_lock);
mutex_lock(&gvt->lock);
vgpu->active = false; vgpu->active = false;
if (atomic_read(&vgpu->submission.running_workload_num)) { if (atomic_read(&vgpu->submission.running_workload_num)) {
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
intel_gvt_wait_vgpu_idle(vgpu); intel_gvt_wait_vgpu_idle(vgpu);
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
} }
intel_vgpu_stop_schedule(vgpu); intel_vgpu_stop_schedule(vgpu);
intel_vgpu_dmabuf_cleanup(vgpu); intel_vgpu_dmabuf_cleanup(vgpu);
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
} }
/** /**
...@@ -252,14 +253,11 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) ...@@ -252,14 +253,11 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
{ {
struct intel_gvt *gvt = vgpu->gvt; struct intel_gvt *gvt = vgpu->gvt;
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
WARN(vgpu->active, "vGPU is still active!\n"); WARN(vgpu->active, "vGPU is still active!\n");
intel_gvt_debugfs_remove_vgpu(vgpu); intel_gvt_debugfs_remove_vgpu(vgpu);
idr_remove(&gvt->vgpu_idr, vgpu->id);
if (idr_is_empty(&gvt->vgpu_idr))
intel_gvt_clean_irq(gvt);
intel_vgpu_clean_sched_policy(vgpu); intel_vgpu_clean_sched_policy(vgpu);
intel_vgpu_clean_submission(vgpu); intel_vgpu_clean_submission(vgpu);
intel_vgpu_clean_display(vgpu); intel_vgpu_clean_display(vgpu);
...@@ -269,10 +267,16 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) ...@@ -269,10 +267,16 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
intel_vgpu_free_resource(vgpu); intel_vgpu_free_resource(vgpu);
intel_vgpu_clean_mmio(vgpu); intel_vgpu_clean_mmio(vgpu);
intel_vgpu_dmabuf_cleanup(vgpu); intel_vgpu_dmabuf_cleanup(vgpu);
vfree(vgpu); mutex_unlock(&vgpu->vgpu_lock);
mutex_lock(&gvt->lock);
idr_remove(&gvt->vgpu_idr, vgpu->id);
if (idr_is_empty(&gvt->vgpu_idr))
intel_gvt_clean_irq(gvt);
intel_gvt_update_vgpu_types(gvt); intel_gvt_update_vgpu_types(gvt);
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->lock);
vfree(vgpu);
} }
#define IDLE_VGPU_IDR 0 #define IDLE_VGPU_IDR 0
...@@ -298,6 +302,7 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt) ...@@ -298,6 +302,7 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt)
vgpu->id = IDLE_VGPU_IDR; vgpu->id = IDLE_VGPU_IDR;
vgpu->gvt = gvt; vgpu->gvt = gvt;
mutex_init(&vgpu->vgpu_lock);
for (i = 0; i < I915_NUM_ENGINES; i++) for (i = 0; i < I915_NUM_ENGINES; i++)
INIT_LIST_HEAD(&vgpu->submission.workload_q_head[i]); INIT_LIST_HEAD(&vgpu->submission.workload_q_head[i]);
...@@ -324,7 +329,10 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt) ...@@ -324,7 +329,10 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt)
*/ */
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu) void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu)
{ {
mutex_lock(&vgpu->vgpu_lock);
intel_vgpu_clean_sched_policy(vgpu); intel_vgpu_clean_sched_policy(vgpu);
mutex_unlock(&vgpu->vgpu_lock);
vfree(vgpu); vfree(vgpu);
} }
...@@ -342,8 +350,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -342,8 +350,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (!vgpu) if (!vgpu)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
mutex_lock(&gvt->lock);
ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU, ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
GFP_KERNEL); GFP_KERNEL);
if (ret < 0) if (ret < 0)
...@@ -353,6 +359,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -353,6 +359,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
vgpu->handle = param->handle; vgpu->handle = param->handle;
vgpu->gvt = gvt; vgpu->gvt = gvt;
vgpu->sched_ctl.weight = param->weight; vgpu->sched_ctl.weight = param->weight;
mutex_init(&vgpu->vgpu_lock);
INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head); INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL); INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
idr_init(&vgpu->object_idr); idr_init(&vgpu->object_idr);
...@@ -400,8 +407,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -400,8 +407,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret) if (ret)
goto out_clean_sched_policy; goto out_clean_sched_policy;
mutex_unlock(&gvt->lock);
return vgpu; return vgpu;
out_clean_sched_policy: out_clean_sched_policy:
...@@ -424,7 +429,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -424,7 +429,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
idr_remove(&gvt->vgpu_idr, vgpu->id); idr_remove(&gvt->vgpu_idr, vgpu->id);
out_free_vgpu: out_free_vgpu:
vfree(vgpu); vfree(vgpu);
mutex_unlock(&gvt->lock);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
...@@ -456,12 +460,12 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -456,12 +460,12 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz); param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz);
param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz); param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz);
mutex_lock(&gvt->lock);
vgpu = __intel_gvt_create_vgpu(gvt, &param); vgpu = __intel_gvt_create_vgpu(gvt, &param);
if (IS_ERR(vgpu)) if (!IS_ERR(vgpu))
return vgpu;
/* calculate left instance change for types */ /* calculate left instance change for types */
intel_gvt_update_vgpu_types(gvt); intel_gvt_update_vgpu_types(gvt);
mutex_unlock(&gvt->lock);
return vgpu; return vgpu;
} }
...@@ -473,7 +477,7 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -473,7 +477,7 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
* @engine_mask: engines to reset for GT reset * @engine_mask: engines to reset for GT reset
* *
* This function is called when user wants to reset a virtual GPU through * This function is called when user wants to reset a virtual GPU through
* device model reset or GT reset. The caller should hold the gvt lock. * device model reset or GT reset. The caller should hold the vgpu lock.
* *
* vGPU Device Model Level Reset (DMLR) simulates the PCI level reset to reset * vGPU Device Model Level Reset (DMLR) simulates the PCI level reset to reset
* the whole vGPU to default state as when it is created. This vGPU function * the whole vGPU to default state as when it is created. This vGPU function
...@@ -513,9 +517,9 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, ...@@ -513,9 +517,9 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
* scheduler when the reset is triggered by current vgpu. * scheduler when the reset is triggered by current vgpu.
*/ */
if (scheduler->current_vgpu == NULL) { if (scheduler->current_vgpu == NULL) {
mutex_unlock(&gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
intel_gvt_wait_vgpu_idle(vgpu); intel_gvt_wait_vgpu_idle(vgpu);
mutex_lock(&gvt->lock); mutex_lock(&vgpu->vgpu_lock);
} }
intel_vgpu_reset_submission(vgpu, resetting_eng); intel_vgpu_reset_submission(vgpu, resetting_eng);
...@@ -555,7 +559,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, ...@@ -555,7 +559,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
*/ */
void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu) void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu)
{ {
mutex_lock(&vgpu->gvt->lock); mutex_lock(&vgpu->vgpu_lock);
intel_gvt_reset_vgpu_locked(vgpu, true, 0); intel_gvt_reset_vgpu_locked(vgpu, true, 0);
mutex_unlock(&vgpu->gvt->lock); mutex_unlock(&vgpu->vgpu_lock);
} }
...@@ -94,7 +94,10 @@ struct vgt_if { ...@@ -94,7 +94,10 @@ struct vgt_if {
u32 rsv5[4]; u32 rsv5[4];
u32 g2v_notify; u32 g2v_notify;
u32 rsv6[7]; u32 rsv6[5];
u32 cursor_x_hot;
u32 cursor_y_hot;
struct { struct {
u32 lo; u32 lo;
......
...@@ -47,6 +47,8 @@ static bool is_supported_device(struct drm_i915_private *dev_priv) ...@@ -47,6 +47,8 @@ static bool is_supported_device(struct drm_i915_private *dev_priv)
return true; return true;
if (IS_KABYLAKE(dev_priv)) if (IS_KABYLAKE(dev_priv))
return true; return true;
if (IS_BROXTON(dev_priv))
return true;
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment