projects: add kernel-config project

This is just a direct import of the current kernel/ directory, with a
slight splitting up of the dockerfiles to build a kernel-source and kernel
image.

Signed-off-by: Tycho Andersen <tycho@docker.com>
This commit is contained in:
Tycho Andersen 2017-05-05 15:17:37 -06:00
parent a4c95be30a
commit 1e0021d969
15 changed files with 13911 additions and 0 deletions

View File

@ -21,6 +21,7 @@ If you want to create a project, please submit a pull request to create a new di
- [Clear Containers](clear-containers/) Clear Containers image
- [Logging](logging/) Experimental logging tools
- [etcd cluster](etcd/) etcd cluster demo from DockerCon'17
- [kernel-config](kernel-config/) an experiment on how to manage kernel config
## Current projects not yet documented
- VMWare support (VMWare)

View File

@ -0,0 +1,59 @@
ARG source=nosuchimage
FROM ${source}
ARG KERNEL_VERSION
ARG KERNEL_SERIES
ARG DEBUG
COPY kernel_config-${KERNEL_SERIES} /linux/arch/x86/configs/x86_64_defconfig
COPY kernel_config.debug /linux/debug_config
RUN if [ -n "${DEBUG}" ]; then \
sed -i 's/CONFIG_PANIC_ON_OOPS=y/# CONFIG_PANIC_ON_OOPS is not set/' /linux/arch/x86/configs/x86_64_defconfig; \
cat /linux/debug_config >> /linux/arch/x86/configs/x86_64_defconfig; \
fi
RUN mkdir /out
# Kernel
RUN make defconfig && \
make oldconfig && \
make -j "$(getconf _NPROCESSORS_ONLN)" KCFLAGS="-fno-pie" && \
cp arch/x86_64/boot/bzImage /out/kernel && \
cp System.map /out
# Modules
RUN make INSTALL_MOD_PATH=/tmp/kernel-modules modules_install && \
( DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdepth 1)) && \
cd /tmp/kernel-modules/lib/modules/$DVER && \
rm build source && \
ln -s /usr/src/linux-headers-$DVER build ) && \
( cd /tmp/kernel-modules && tar cf /out/kernel.tar lib )
# Headers (userspace API)
RUN mkdir -p /tmp/kernel-headers/usr && \
make INSTALL_HDR_PATH=/tmp/kernel-headers/usr headers_install && \
( cd /tmp/kernel-headers && tar cf /out/kernel-headers.tar usr )
# Headers (kernel development)
RUN DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdepth 1)) && \
dir=/tmp/usr/src/linux-headers-$DVER && \
mkdir -p $dir && \
cp /linux/.config $dir && \
cp /linux/Module.symvers $dir && \
find . -path './include/*' -prune -o \
-path './arch/*/include' -prune -o \
-path './scripts/*' -prune -o \
-type f \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
-name '*.lds' -o -name '*.pl' -o -name '*.sh' \) | \
tar cf - -T - | (cd $dir; tar xf -) && \
( cd /tmp && tar cf /out/kernel-dev.tar usr/src )
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info
FROM linuxkit/toybox-media:eee3dd4d72cd784801e95b1781e6c4f9d8a5e5eb@sha256:7f940e687164ee2676e11c61705c79f7dd2d144ee87ad17a494848a7045f5f53
ENTRYPOINT []
CMD []
WORKDIR /
COPY --from=kernel-build /out/* /

View File

@ -0,0 +1,18 @@
FROM linuxkit/kernel-compile:1b396c221af673757703258159ddc8539843b02b@sha256:6b32d205bfc6407568324337b707d195d027328dbfec554428ea93e7b0a8299b AS kernel-build
ARG KERNEL_VERSION
ARG KERNEL_SERIES
ENV KERNEL_SOURCE=https://www.kernel.org/pub/linux/kernel/v4.x/linux-${KERNEL_VERSION}.tar.xz
RUN curl -fsSL -o linux-${KERNEL_VERSION}.tar.xz ${KERNEL_SOURCE}
RUN cat linux-${KERNEL_VERSION}.tar.xz | tar --absolute-names -xJ && mv /linux-${KERNEL_VERSION} /linux
# Apply local patches
COPY patches-${KERNEL_SERIES} /patches
WORKDIR /linux
RUN set -e && for patch in /patches/*.patch; do \
echo "Applying $patch"; \
patch -p1 < "$patch"; \
done

View File

@ -0,0 +1,78 @@
# This builds the supported LinuxKit kernels. Kernels are wrapped up
# in a minimal toybox container, which contains the bzImage, a tar
# ball with modules and the kernel source.
#
# Each kernel is pushed to hub twice, once as
# linuxkit/kernel:<kernel>.<major>.<minor>-<hash> and once as
# inuxkit/kernel:<kernel>.<major>.x. The <hash> is the git tree hash
# of the current directory. The build will only rebuild the kernel
# image if the git tree hash changed.
# Git tree hash of this directory. Override to force build
HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}')
# Name on Hub
IMAGE:=kernel
.PHONY: check tag push sign
# Targets:
# build: builds all kernels
# push: pushes all tagged kernel images to hub
# sign: sign and push all kernel images to hub
build:
push:
sign:
# A template for defining kernel build
# Arguments:
# $1: Full kernel version, e.g., 4.9.22
# $2: Kernel "series", e.g., 4.9.x
# $3: Build a debug kernel (used as suffix for image)
# This defines targets like:
# build_4.9.x, push_4.9.x and sign_4.9.x and adds them as dependencies
# to the global targets
# Set $3 to "_dbg", to build debug kernels. This defines targets like
# build_4.9.x_dbg and adds "_dbg" to the hub image name.
define kernel
.PHONY: source_$(2)$(3)
source_$(2)$(3):
docker image inspect linuxkit/$(IMAGE)-source:$(1)-$(HASH) >/dev/null || \
docker build -f Dockerfile.source \
--build-arg KERNEL_VERSION=$(1) \
--build-arg KERNEL_SERIES=$(2) \
--no-cache -t linuxkit/$(IMAGE)-source:$(1)-$(HASH) .
build_$(2)$(3): Dockerfile.build Makefile $(wildcard patches-$(2)/*) kernel_config-$(2) kernel_config.debug source_$(2)$(3)
docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
docker build -f Dockerfile.build \
--build-arg KERNEL_VERSION=$(1) \
--build-arg KERNEL_SERIES=$(2) \
--build-arg DEBUG=$(3) \
--build-arg source=linuxkit/$(IMAGE)-source:$(1)$(3)-$(HASH) \
--no-cache -t linuxkit/$(IMAGE):$(1)$(3)-$(HASH) .
push_$(2)$(3): build_$(2)$(3)
docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
(docker push linuxkit/$(IMAGE):$(1)$(3)-$(HASH) && \
docker tag linuxkit/$(IMAGE):$(1)$(3)-$(HASH) linuxkit/$(IMAGE):$(2)$(3) && \
docker push linuxkit/$(IMAGE):$(2)$(3))
sign_$(2)$(3): build_$(2)$(3)
DOCKER_CONTENT_TRUST=1 docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
(DOCKER_CONTENT_TRUST=1 docker push linuxkit/$(IMAGE):$(1)$(3)-$(HASH) && \
docker tag linuxkit/$(IMAGE):$(1)$(3)-$(HASH) linuxkit/$(IMAGE):$(2)$(3) && \
DOCKER_CONTENT_TRUST=1 docker push linuxkit/$(IMAGE):$(2)$(3))
build: build_$(2)$(3)
push: push_$(2)$(3)
sign: sign_$(2)$(3)
endef
#
# Build Targets
# Debug targets only for latest stable and LTS stable
#
$(eval $(call kernel,4.10.14,4.10.x))
$(eval $(call kernel,4.10.14,4.10.x,_dbg))
$(eval $(call kernel,4.9.26,4.9.x))
$(eval $(call kernel,4.9.26,4.9.x,_dbg))
$(eval $(call kernel,4.4.66,4.4.x))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
## LinuxKit DEBUG OPTIONS ##
CONFIG_LOCKDEP=y
CONFIG_FRAME_POINTER=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_TIMEKEEPING=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_PROVE_RCU=y
CONFIG_RCU_TRACE=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDBOC=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DEBUG_WX=y

View File

@ -0,0 +1,492 @@
From 6d21f35a580779c88a2f251395097b082574f4cc Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sat, 28 Jan 2017 12:37:17 -0700
Subject: [PATCH 2/7] Drivers: hv: vmbus: Use all supported IC versions to
negotiate
Previously, we were assuming that each IC protocol version was tied to a
specific host version. For example, some Windows 10 preview hosts only
support v3 TimeSync even though driver assumes v4 is supported by all
Windows 10 hosts.
The guest will stop trying to negotiate even though older supported
versions may still be offered by the host.
Make IC version negotiation more robust by going through all versions
that are supported by the guest.
Fixes: 3da0401b4d0e ("Drivers: hv: utils: Fix the mapping between host
version and protocol to use")
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
(cherry picked from commit a1656454131880980bc3a5313c8bf66ef5990c91)
---
drivers/hv/channel_mgmt.c | 80 +++++++++++++++++++++++++++-------------
drivers/hv/hv_fcopy.c | 20 +++++++---
drivers/hv/hv_kvp.c | 41 +++++++++------------
drivers/hv/hv_snapshot.c | 18 +++++++--
drivers/hv/hv_util.c | 94 +++++++++++++++++++++++++----------------------
include/linux/hyperv.h | 7 ++--
6 files changed, 154 insertions(+), 106 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index a58cd102af1b..feca5d2e7b25 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -203,33 +203,34 @@ static u16 hv_get_dev_type(const struct vmbus_channel *channel)
* @buf: Raw buffer channel data
*
* @icmsghdrp is of type &struct icmsg_hdr.
- * @negop is of type &struct icmsg_negotiate.
* Set up and fill in default negotiate response message.
*
- * The fw_version specifies the framework version that
- * we can support and srv_version specifies the service
- * version we can support.
+ * The fw_version and fw_vercnt specifies the framework version that
+ * we can support.
+ *
+ * The srv_version and srv_vercnt specifies the service
+ * versions we can support.
+ *
+ * Versions are given in decreasing order.
+ *
+ * nego_fw_version and nego_srv_version store the selected protocol versions.
*
* Mainly used by Hyper-V drivers.
*/
bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
- struct icmsg_negotiate *negop, u8 *buf,
- int fw_version, int srv_version)
+ u8 *buf, const int *fw_version, int fw_vercnt,
+ const int *srv_version, int srv_vercnt,
+ int *nego_fw_version, int *nego_srv_version)
{
int icframe_major, icframe_minor;
int icmsg_major, icmsg_minor;
int fw_major, fw_minor;
int srv_major, srv_minor;
- int i;
+ int i, j;
bool found_match = false;
+ struct icmsg_negotiate *negop;
icmsghdrp->icmsgsize = 0x10;
- fw_major = (fw_version >> 16);
- fw_minor = (fw_version & 0xFFFF);
-
- srv_major = (srv_version >> 16);
- srv_minor = (srv_version & 0xFFFF);
-
negop = (struct icmsg_negotiate *)&buf[
sizeof(struct vmbuspipe_hdr) +
sizeof(struct icmsg_hdr)];
@@ -245,13 +246,22 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
* support.
*/
- for (i = 0; i < negop->icframe_vercnt; i++) {
- if ((negop->icversion_data[i].major == fw_major) &&
- (negop->icversion_data[i].minor == fw_minor)) {
- icframe_major = negop->icversion_data[i].major;
- icframe_minor = negop->icversion_data[i].minor;
- found_match = true;
+ for (i = 0; i < fw_vercnt; i++) {
+ fw_major = (fw_version[i] >> 16);
+ fw_minor = (fw_version[i] & 0xFFFF);
+
+ for (j = 0; j < negop->icframe_vercnt; j++) {
+ if ((negop->icversion_data[j].major == fw_major) &&
+ (negop->icversion_data[j].minor == fw_minor)) {
+ icframe_major = negop->icversion_data[j].major;
+ icframe_minor = negop->icversion_data[j].minor;
+ found_match = true;
+ break;
+ }
}
+
+ if (found_match)
+ break;
}
if (!found_match)
@@ -259,14 +269,26 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
found_match = false;
- for (i = negop->icframe_vercnt;
- (i < negop->icframe_vercnt + negop->icmsg_vercnt); i++) {
- if ((negop->icversion_data[i].major == srv_major) &&
- (negop->icversion_data[i].minor == srv_minor)) {
- icmsg_major = negop->icversion_data[i].major;
- icmsg_minor = negop->icversion_data[i].minor;
- found_match = true;
+ for (i = 0; i < srv_vercnt; i++) {
+ srv_major = (srv_version[i] >> 16);
+ srv_minor = (srv_version[i] & 0xFFFF);
+
+ for (j = negop->icframe_vercnt;
+ (j < negop->icframe_vercnt + negop->icmsg_vercnt);
+ j++) {
+
+ if ((negop->icversion_data[j].major == srv_major) &&
+ (negop->icversion_data[j].minor == srv_minor)) {
+
+ icmsg_major = negop->icversion_data[j].major;
+ icmsg_minor = negop->icversion_data[j].minor;
+ found_match = true;
+ break;
+ }
}
+
+ if (found_match)
+ break;
}
/*
@@ -283,6 +305,12 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
negop->icmsg_vercnt = 1;
}
+ if (nego_fw_version)
+ *nego_fw_version = (icframe_major << 16) | icframe_minor;
+
+ if (nego_srv_version)
+ *nego_srv_version = (icmsg_major << 16) | icmsg_minor;
+
negop->icversion_data[0].major = icframe_major;
negop->icversion_data[0].minor = icframe_minor;
negop->icversion_data[1].major = icmsg_major;
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
index e47d8c9db03a..0a315e6aa589 100644
--- a/drivers/hv/hv_fcopy.c
+++ b/drivers/hv/hv_fcopy.c
@@ -31,6 +31,16 @@
#define WIN8_SRV_MINOR 1
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
+#define FCOPY_VER_COUNT 1
+static const int fcopy_versions[] = {
+ WIN8_SRV_VERSION
+};
+
+#define FW_VER_COUNT 1
+static const int fw_versions[] = {
+ UTIL_FW_VERSION
+};
+
/*
* Global state maintained for transaction that is being processed.
* For a class of integration services, including the "file copy service",
@@ -228,8 +238,6 @@ void hv_fcopy_onchannelcallback(void *context)
u64 requestid;
struct hv_fcopy_hdr *fcopy_msg;
struct icmsg_hdr *icmsghdr;
- struct icmsg_negotiate *negop = NULL;
- int util_fw_version;
int fcopy_srv_version;
if (fcopy_transaction.state > HVUTIL_READY)
@@ -243,10 +251,10 @@ void hv_fcopy_onchannelcallback(void *context)
icmsghdr = (struct icmsg_hdr *)&recv_buffer[
sizeof(struct vmbuspipe_hdr)];
if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- util_fw_version = UTIL_FW_VERSION;
- fcopy_srv_version = WIN8_SRV_VERSION;
- vmbus_prep_negotiate_resp(icmsghdr, negop, recv_buffer,
- util_fw_version, fcopy_srv_version);
+ vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
+ fw_versions, FW_VER_COUNT,
+ fcopy_versions, FCOPY_VER_COUNT,
+ NULL, &fcopy_srv_version);
} else {
fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 3abfc5983c97..2cc670442f6c 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -46,6 +46,19 @@
#define WIN8_SRV_MINOR 0
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
+#define KVP_VER_COUNT 3
+static const int kvp_versions[] = {
+ WIN8_SRV_VERSION,
+ WIN7_SRV_VERSION,
+ WS2008_SRV_VERSION
+};
+
+#define FW_VER_COUNT 2
+static const int fw_versions[] = {
+ UTIL_FW_VERSION,
+ UTIL_WS2K8_FW_VERSION
+};
+
/*
* Global state maintained for transaction that is being processed. For a class
* of integration services, including the "KVP service", the specified protocol
@@ -610,8 +623,6 @@ void hv_kvp_onchannelcallback(void *context)
struct hv_kvp_msg *kvp_msg;
struct icmsg_hdr *icmsghdrp;
- struct icmsg_negotiate *negop = NULL;
- int util_fw_version;
int kvp_srv_version;
static enum {NEGO_NOT_STARTED,
NEGO_IN_PROGRESS,
@@ -640,28 +651,10 @@ void hv_kvp_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- /*
- * Based on the host, select appropriate
- * framework and service versions we will
- * negotiate.
- */
- switch (vmbus_proto_version) {
- case (VERSION_WS2008):
- util_fw_version = UTIL_WS2K8_FW_VERSION;
- kvp_srv_version = WS2008_SRV_VERSION;
- break;
- case (VERSION_WIN7):
- util_fw_version = UTIL_FW_VERSION;
- kvp_srv_version = WIN7_SRV_VERSION;
- break;
- default:
- util_fw_version = UTIL_FW_VERSION;
- kvp_srv_version = WIN8_SRV_VERSION;
- }
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- recv_buffer, util_fw_version,
- kvp_srv_version);
-
+ vmbus_prep_negotiate_resp(icmsghdrp,
+ recv_buffer, fw_versions, FW_VER_COUNT,
+ kvp_versions, KVP_VER_COUNT,
+ NULL, &kvp_srv_version);
} else {
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index 4e543dbb731a..d14f10b924a0 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -31,6 +31,16 @@
#define VSS_MINOR 0
#define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR)
+#define VSS_VER_COUNT 1
+static const int vss_versions[] = {
+ VSS_VERSION
+};
+
+#define FW_VER_COUNT 1
+static const int fw_versions[] = {
+ UTIL_FW_VERSION
+};
+
/*
* Timeout values are based on expecations from host
*/
@@ -297,7 +307,6 @@ void hv_vss_onchannelcallback(void *context)
struct icmsg_hdr *icmsghdrp;
- struct icmsg_negotiate *negop = NULL;
if (vss_transaction.state > HVUTIL_READY)
return;
@@ -310,9 +319,10 @@ void hv_vss_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- recv_buffer, UTIL_FW_VERSION,
- VSS_VERSION);
+ vmbus_prep_negotiate_resp(icmsghdrp,
+ recv_buffer, fw_versions, FW_VER_COUNT,
+ vss_versions, VSS_VER_COUNT,
+ NULL, NULL);
} else {
vss_msg = (struct hv_vss_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index e7707747f56d..f3797c07be10 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -57,7 +57,31 @@
static int sd_srv_version;
static int ts_srv_version;
static int hb_srv_version;
-static int util_fw_version;
+
+#define SD_VER_COUNT 2
+static const int sd_versions[] = {
+ SD_VERSION,
+ SD_VERSION_1
+};
+
+#define TS_VER_COUNT 3
+static const int ts_versions[] = {
+ TS_VERSION,
+ TS_VERSION_3,
+ TS_VERSION_1
+};
+
+#define HB_VER_COUNT 2
+static const int hb_versions[] = {
+ HB_VERSION,
+ HB_VERSION_1
+};
+
+#define FW_VER_COUNT 2
+static const int fw_versions[] = {
+ UTIL_FW_VERSION,
+ UTIL_WS2K8_FW_VERSION
+};
static void shutdown_onchannelcallback(void *context);
static struct hv_util_service util_shutdown = {
@@ -118,7 +142,6 @@ static void shutdown_onchannelcallback(void *context)
struct shutdown_msg_data *shutdown_msg;
struct icmsg_hdr *icmsghdrp;
- struct icmsg_negotiate *negop = NULL;
vmbus_recvpacket(channel, shut_txf_buf,
PAGE_SIZE, &recvlen, &requestid);
@@ -128,9 +151,14 @@ static void shutdown_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- shut_txf_buf, util_fw_version,
- sd_srv_version);
+ if (vmbus_prep_negotiate_resp(icmsghdrp, shut_txf_buf,
+ fw_versions, FW_VER_COUNT,
+ sd_versions, SD_VER_COUNT,
+ NULL, &sd_srv_version)) {
+ pr_info("Shutdown IC version %d.%d\n",
+ sd_srv_version >> 16,
+ sd_srv_version & 0xFFFF);
+ }
} else {
shutdown_msg =
(struct shutdown_msg_data *)&shut_txf_buf[
@@ -253,7 +281,6 @@ static void timesync_onchannelcallback(void *context)
struct ictimesync_data *timedatap;
struct ictimesync_ref_data *refdata;
u8 *time_txf_buf = util_timesynch.recv_buffer;
- struct icmsg_negotiate *negop = NULL;
vmbus_recvpacket(channel, time_txf_buf,
PAGE_SIZE, &recvlen, &requestid);
@@ -263,12 +290,14 @@ static void timesync_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- time_txf_buf,
- util_fw_version,
- ts_srv_version);
- pr_info("Using TimeSync version %d.%d\n",
- ts_srv_version >> 16, ts_srv_version & 0xFFFF);
+ if (vmbus_prep_negotiate_resp(icmsghdrp, time_txf_buf,
+ fw_versions, FW_VER_COUNT,
+ ts_versions, TS_VER_COUNT,
+ NULL, &ts_srv_version)) {
+ pr_info("TimeSync version %d.%d\n",
+ ts_srv_version >> 16,
+ ts_srv_version & 0xFFFF);
+ }
} else {
if (ts_srv_version > TS_VERSION_3) {
refdata = (struct ictimesync_ref_data *)
@@ -312,7 +341,6 @@ static void heartbeat_onchannelcallback(void *context)
struct icmsg_hdr *icmsghdrp;
struct heartbeat_msg_data *heartbeat_msg;
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
- struct icmsg_negotiate *negop = NULL;
while (1) {
@@ -326,9 +354,16 @@ static void heartbeat_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- hbeat_txf_buf, util_fw_version,
- hb_srv_version);
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
+ hbeat_txf_buf,
+ fw_versions, FW_VER_COUNT,
+ hb_versions, HB_VER_COUNT,
+ NULL, &hb_srv_version)) {
+
+ pr_info("Heartbeat version %d.%d\n",
+ hb_srv_version >> 16,
+ hb_srv_version & 0xFFFF);
+ }
} else {
heartbeat_msg =
(struct heartbeat_msg_data *)&hbeat_txf_buf[
@@ -378,33 +413,6 @@ static int util_probe(struct hv_device *dev,
hv_set_drvdata(dev, srv);
- /*
- * Based on the host; initialize the framework and
- * service version numbers we will negotiate.
- */
- switch (vmbus_proto_version) {
- case (VERSION_WS2008):
- util_fw_version = UTIL_WS2K8_FW_VERSION;
- sd_srv_version = SD_VERSION_1;
- ts_srv_version = TS_VERSION_1;
- hb_srv_version = HB_VERSION_1;
- break;
- case VERSION_WIN7:
- case VERSION_WIN8:
- case VERSION_WIN8_1:
- util_fw_version = UTIL_FW_VERSION;
- sd_srv_version = SD_VERSION;
- ts_srv_version = TS_VERSION_3;
- hb_srv_version = HB_VERSION;
- break;
- case VERSION_WIN10:
- default:
- util_fw_version = UTIL_FW_VERSION;
- sd_srv_version = SD_VERSION;
- ts_srv_version = TS_VERSION;
- hb_srv_version = HB_VERSION;
- }
-
ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
srv->util_cb, dev->channel);
if (ret)
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ca26335de49a..41e5ed87f833 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1459,9 +1459,10 @@ struct hyperv_service_callback {
};
#define MAX_SRV_VER 0x7ffffff
-extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
- struct icmsg_negotiate *, u8 *, int,
- int);
+extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
+ const int *fw_version, int fw_vercnt,
+ const int *srv_version, int srv_vercnt,
+ int *nego_fw_version, int *nego_srv_version);
void hv_event_tasklet_disable(struct vmbus_channel *channel);
void hv_event_tasklet_enable(struct vmbus_channel *channel);
--
2.11.0

View File

@ -0,0 +1,118 @@
From fbdcc24ca6ecc490da8254110a85aa33325137b9 Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sat, 28 Jan 2017 12:37:18 -0700
Subject: [PATCH 3/7] Drivers: hv: Log the negotiated IC versions.
Log the negotiated IC versions.
Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
(cherry picked from commit 1274a690f6b2bd2b37447c47e3062afa8aa43f93)
---
drivers/hv/hv_fcopy.c | 9 +++++++--
drivers/hv/hv_kvp.c | 8 ++++++--
drivers/hv/hv_snapshot.c | 11 ++++++++---
drivers/hv/hv_util.c | 4 ++--
4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
index 0a315e6aa589..9aee6014339d 100644
--- a/drivers/hv/hv_fcopy.c
+++ b/drivers/hv/hv_fcopy.c
@@ -251,10 +251,15 @@ void hv_fcopy_onchannelcallback(void *context)
icmsghdr = (struct icmsg_hdr *)&recv_buffer[
sizeof(struct vmbuspipe_hdr)];
if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
+ if (vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
fw_versions, FW_VER_COUNT,
fcopy_versions, FCOPY_VER_COUNT,
- NULL, &fcopy_srv_version);
+ NULL, &fcopy_srv_version)) {
+
+ pr_info("FCopy IC version %d.%d\n",
+ fcopy_srv_version >> 16,
+ fcopy_srv_version & 0xFFFF);
+ }
} else {
fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 2cc670442f6c..de263712e247 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -651,10 +651,14 @@ void hv_kvp_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp,
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
recv_buffer, fw_versions, FW_VER_COUNT,
kvp_versions, KVP_VER_COUNT,
- NULL, &kvp_srv_version);
+ NULL, &kvp_srv_version)) {
+ pr_info("KVP IC version %d.%d\n",
+ kvp_srv_version >> 16,
+ kvp_srv_version & 0xFFFF);
+ }
} else {
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index d14f10b924a0..bcc03f0748d6 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -304,7 +304,7 @@ void hv_vss_onchannelcallback(void *context)
u32 recvlen;
u64 requestid;
struct hv_vss_msg *vss_msg;
-
+ int vss_srv_version;
struct icmsg_hdr *icmsghdrp;
@@ -319,10 +319,15 @@ void hv_vss_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- vmbus_prep_negotiate_resp(icmsghdrp,
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
recv_buffer, fw_versions, FW_VER_COUNT,
vss_versions, VSS_VER_COUNT,
- NULL, NULL);
+ NULL, &vss_srv_version)) {
+
+ pr_info("VSS IC version %d.%d\n",
+ vss_srv_version >> 16,
+ vss_srv_version & 0xFFFF);
+ }
} else {
vss_msg = (struct hv_vss_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index f3797c07be10..89440c2eb346 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -294,7 +294,7 @@ static void timesync_onchannelcallback(void *context)
fw_versions, FW_VER_COUNT,
ts_versions, TS_VER_COUNT,
NULL, &ts_srv_version)) {
- pr_info("TimeSync version %d.%d\n",
+ pr_info("TimeSync IC version %d.%d\n",
ts_srv_version >> 16,
ts_srv_version & 0xFFFF);
}
@@ -360,7 +360,7 @@ static void heartbeat_onchannelcallback(void *context)
hb_versions, HB_VER_COUNT,
NULL, &hb_srv_version)) {
- pr_info("Heartbeat version %d.%d\n",
+ pr_info("Heartbeat IC version %d.%d\n",
hb_srv_version >> 16,
hb_srv_version & 0xFFFF);
}
--
2.11.0

View File

@ -0,0 +1,56 @@
From 64b212adc820690cb54855b79e30e23329aecc5a Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Sun, 26 Mar 2017 16:42:20 +0800
Subject: [PATCH 4/7] vmbus: fix missed ring events on boot
During initialization, the channel initialization code schedules the
tasklet to scan the VMBUS receive event page (i.e. simulates an
interrupt). The problem was that it invokes the tasklet on a different
CPU from where it normally runs and therefore if an event is present,
it will clear the bit but not find the associated channel.
This can lead to missed events, typically stuck tasks, during bootup
when sub channels are being initialized. Typically seen as stuck
boot with 8 or more CPU's.
This patch is not necessary for upstream (4.11 and later) since
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
This changed vmbus code to get rid of common tasklet which
caused the problem.
Cc: stable@vger.kernel.org
Fixes: 638fea33aee8 ("Drivers: hv: vmbus: fix the race when querying & updating the percpu list")
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 5cf3a72a111cecc7da759542c56560ce509159d7)
---
drivers/hv/channel_mgmt.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index feca5d2e7b25..3fda63bf60ab 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -389,8 +389,17 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel)
tasklet = hv_context.event_dpc[channel->target_cpu];
tasklet_enable(tasklet);
- /* In case there is any pending event */
- tasklet_schedule(tasklet);
+ /*
+ * In case there is any pending event schedule a rescan
+ * but must be on the correct CPU for the channel.
+ */
+ if (channel->target_cpu == get_cpu())
+ tasklet_schedule(tasklet);
+ else
+ smp_call_function_single(channel->target_cpu,
+ (smp_call_func_t)tasklet_schedule,
+ tasklet, false);
+ put_cpu();
}
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
--
2.11.0

View File

@ -0,0 +1,59 @@
From 0c089ad42dfc3a845ce6a21a1f78dd1704cbbaed Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 29 Mar 2017 18:37:10 +0800
Subject: [PATCH 5/7] vmbus: remove "goto error_clean_msglist" in vmbus_open()
This is just a cleanup patch to simplify the code a little.
No semantic change.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 2c89f21cbdfd39299482cd6068094097a45f13b3)
---
drivers/hv/channel.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 1606e7f08f4b..1caed01954f6 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -184,17 +184,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
ret = vmbus_post_msg(open_msg,
sizeof(struct vmbus_channel_open_channel), true);
- if (ret != 0) {
- err = ret;
- goto error_clean_msglist;
- }
-
- wait_for_completion(&open_info->waitevent);
+ if (ret == 0)
+ wait_for_completion(&open_info->waitevent);
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_del(&open_info->msglistentry);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+ if (ret != 0) {
+ err = ret;
+ goto error_free_gpadl;
+ }
+
if (newchannel->rescind) {
err = -ENODEV;
goto error_free_gpadl;
@@ -209,11 +210,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
kfree(open_info);
return 0;
-error_clean_msglist:
- spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
- list_del(&open_info->msglistentry);
- spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
-
error_free_gpadl:
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
kfree(open_info);
--
2.11.0

View File

@ -0,0 +1,177 @@
From 67f5a959cea3dea2f5773cf7b690337dde421f9b Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 24 Mar 2017 20:53:18 +0800
Subject: [PATCH 6/7] vmbus: dynamically enqueue/dequeue the channel on
vmbus_open/close
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit bee4910daa4aed57ce60d2e2350e3cc120c383ca)
---
drivers/hv/channel.c | 16 ++++++++++---
drivers/hv/channel_mgmt.c | 58 ++++++++++++++++++++---------------------------
include/linux/hyperv.h | 3 +++
3 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 1caed01954f6..5bbcc964dbf7 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -181,6 +181,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
&vmbus_connection.chn_msg_list);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+ hv_event_tasklet_disable(newchannel);
+ hv_percpu_channel_enq(newchannel);
+ hv_event_tasklet_enable(newchannel);
+
ret = vmbus_post_msg(open_msg,
sizeof(struct vmbus_channel_open_channel), true);
@@ -193,23 +197,27 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
if (ret != 0) {
err = ret;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
if (newchannel->rescind) {
err = -ENODEV;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
if (open_info->response.open_result.status) {
err = -EAGAIN;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
newchannel->state = CHANNEL_OPENED_STATE;
kfree(open_info);
return 0;
+error_deq_channel:
+ hv_event_tasklet_disable(newchannel);
+ hv_percpu_channel_deq(newchannel);
+ hv_event_tasklet_enable(newchannel);
error_free_gpadl:
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
kfree(open_info);
@@ -555,6 +563,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
goto out;
}
+ hv_percpu_channel_deq(channel);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 3fda63bf60ab..e2fbfa290f1c 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -376,6 +376,30 @@ static void vmbus_release_relid(u32 relid)
true);
}
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
+{
+ if (channel->target_cpu != get_cpu())
+ smp_call_function_single(channel->target_cpu,
+ percpu_channel_enq,
+ channel, true);
+ else
+ percpu_channel_enq(channel);
+ put_cpu();
+
+}
+
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
+{
+ if (channel->target_cpu != get_cpu())
+ smp_call_function_single(channel->target_cpu,
+ percpu_channel_deq,
+ channel, true);
+ else
+ percpu_channel_deq(channel);
+ put_cpu();
+
+}
+
void hv_event_tasklet_disable(struct vmbus_channel *channel)
{
struct tasklet_struct *tasklet;
@@ -410,17 +434,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
BUG_ON(!channel->rescind);
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
- hv_event_tasklet_disable(channel);
- if (channel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(channel->target_cpu,
- percpu_channel_deq, channel, true);
- } else {
- percpu_channel_deq(channel);
- put_cpu();
- }
- hv_event_tasklet_enable(channel);
-
if (channel->primary_channel == NULL) {
list_del(&channel->listentry);
@@ -513,18 +526,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
init_vp_index(newchannel, dev_type);
- hv_event_tasklet_disable(newchannel);
- if (newchannel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(newchannel->target_cpu,
- percpu_channel_enq,
- newchannel, true);
- } else {
- percpu_channel_enq(newchannel);
- put_cpu();
- }
- hv_event_tasklet_enable(newchannel);
-
/*
* This state is used to indicate a successful open
* so that when we do close the channel normally, we
@@ -573,17 +574,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
list_del(&newchannel->listentry);
mutex_unlock(&vmbus_connection.channel_mutex);
- hv_event_tasklet_disable(newchannel);
- if (newchannel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(newchannel->target_cpu,
- percpu_channel_deq, newchannel, true);
- } else {
- percpu_channel_deq(newchannel);
- put_cpu();
- }
- hv_event_tasklet_enable(newchannel);
-
vmbus_release_relid(newchannel->offermsg.child_relid);
err_free_chan:
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 41e5ed87f833..0792d16f4b3e 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1467,6 +1467,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
void hv_event_tasklet_disable(struct vmbus_channel *channel);
void hv_event_tasklet_enable(struct vmbus_channel *channel);
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
+
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
void vmbus_setevent(struct vmbus_channel *channel);
--
2.11.0

View File

@ -0,0 +1,94 @@
From 6064d8207f1a62352f2476d09b8d6c6fba572359 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue, 7 Mar 2017 09:15:53 -0800
Subject: [PATCH 7/7] scsi: storvsc: Workaround for virtual DVD SCSI version
Hyper-V host emulation of SCSI for virtual DVD device reports SCSI
version 0 (UNKNOWN) but is still capable of supporting REPORTLUN.
Without this patch, a GEN2 Linux guest on Hyper-V will not boot 4.11
successfully with virtual DVD ROM device. What happens is that the SCSI
scan process falls back to doing sequential probing by INQUIRY. But the
storvsc driver has a previous workaround that masks/blocks all errors
reports from INQUIRY (or MODE_SENSE) commands. This workaround causes
the scan to then populate a full set of bogus LUN's on the target and
then sends kernel spinning off into a death spiral doing block reads on
the non-existent LUNs.
By setting the correct blacklist flags, the target with the DVD device
is scanned with REPORTLUN and that works correctly.
Patch needs to go in current 4.11, it is safe but not necessary in older
kernels.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit f1c635b439a5c01776fe3a25b1e2dc546ea82e6f)
---
drivers/scsi/storvsc_drv.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 7be04fc0d0e7..6f5d173ea9ff 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -400,8 +400,6 @@ MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels")
*/
static int storvsc_timeout = 180;
-static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
-
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
static struct scsi_transport_template *fc_transport_template;
#endif
@@ -1283,6 +1281,22 @@ static int storvsc_do_io(struct hv_device *device,
return ret;
}
+static int storvsc_device_alloc(struct scsi_device *sdevice)
+{
+ /*
+ * Set blist flag to permit the reading of the VPD pages even when
+ * the target may claim SPC-2 compliance. MSFT targets currently
+ * claim SPC-2 compliance while they implement post SPC-2 features.
+ * With this flag we can correctly handle WRITE_SAME_16 issues.
+ *
+ * Hypervisor reports SCSI_UNKNOWN type for DVD ROM device but
+ * still supports REPORT LUN.
+ */
+ sdevice->sdev_bflags = BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES;
+
+ return 0;
+}
+
static int storvsc_device_configure(struct scsi_device *sdevice)
{
@@ -1298,14 +1312,6 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
sdevice->no_write_same = 1;
/*
- * Add blist flags to permit the reading of the VPD pages even when
- * the target may claim SPC-2 compliance. MSFT targets currently
- * claim SPC-2 compliance while they implement post SPC-2 features.
- * With this patch we can correctly handle WRITE_SAME_16 issues.
- */
- sdevice->sdev_bflags |= msft_blist_flags;
-
- /*
* If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
* if the device is a MSFT virtual device. If the host is
* WIN10 or newer, allow write_same.
@@ -1569,6 +1575,7 @@ static struct scsi_host_template scsi_driver = {
.eh_host_reset_handler = storvsc_host_reset_handler,
.proc_name = "storvsc_host",
.eh_timed_out = storvsc_eh_timed_out,
+ .slave_alloc = storvsc_device_alloc,
.slave_configure = storvsc_device_configure,
.cmd_per_lun = 255,
.this_id = -1,
--
2.11.0