mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-11-04 00:46:00 +00:00 
			
		
		
		
	Merge pull request #2837 from rn/clean
Remove some stale files/projects
This commit is contained in:
		@@ -17,8 +17,6 @@ If you want to create a project, please submit a pull request to create a new di
 | 
				
			|||||||
- [Landlock LSM](landlock/) programmatic access control
 | 
					- [Landlock LSM](landlock/) programmatic access control
 | 
				
			||||||
- [Clear Containers](clear-containers/) Clear Containers image
 | 
					- [Clear Containers](clear-containers/) Clear Containers image
 | 
				
			||||||
- [Logging](logging/) Experimental logging tools
 | 
					- [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
 | 
					 | 
				
			||||||
- [IMA-namespace](ima-namespace/) patches for supporting per-mount-namespace
 | 
					- [IMA-namespace](ima-namespace/) patches for supporting per-mount-namespace
 | 
				
			||||||
  IMA policies
 | 
					  IMA policies
 | 
				
			||||||
- [shiftfs](shiftfs/) is a filesystem for mapping mountpoints across user
 | 
					- [shiftfs](shiftfs/) is a filesystem for mapping mountpoints across user
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,105 +0,0 @@
 | 
				
			|||||||
This directory contains files used in Moby/LinuxKit DockerCon 2017
 | 
					 | 
				
			||||||
keynote etcd cluster demo. They mostly serve as examples and probably
 | 
					 | 
				
			||||||
need adjustments to your specific environment. They may also break
 | 
					 | 
				
			||||||
over time :)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Prerequisites
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most of the scripts/files assume you are on a Mac.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Recent Docker for Mac installed (We used 17.05.0-ce-rc1-mac8 from the edge channel)
 | 
					 | 
				
			||||||
- For the GCP portion: `brew install google-cloud-sdk`
 | 
					 | 
				
			||||||
- Infrakit: Clone [infrakit](https://github.com/docker/infrakit) and
 | 
					 | 
				
			||||||
  the [GCP plugin](https://github.com/docker/infrakit.gcp) for
 | 
					 | 
				
			||||||
  infrakit.  The GCP plugin, needs to be v0.1. For each, `make
 | 
					 | 
				
			||||||
  build-in-container` and then copy the contents of `./build`
 | 
					 | 
				
			||||||
  somewhere in your path.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## etcd cluster setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
An `etcd` cluster can be bootstrapped in different ways (see the [Documentation](https://coreos.com/etcd/docs/latest/op-guide/clustering.html) for more details. For the demo we use configuration via static IP addresses. With Infrakit these are managed by assigning `LogicalID`s to cluster members. The `LogicalID` is interpreted as a IP address.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The `etcd` package takes the official `etcd` container and adds a
 | 
					 | 
				
			||||||
[script](./pkg/etcd.sh) to start `etcd`. [etcd.sh](./pkg/etcd.sh)
 | 
					 | 
				
			||||||
first attempts to join a new cluster. If that fails it attempts to
 | 
					 | 
				
			||||||
join an existing cluster. Note, the number and members of the cluster
 | 
					 | 
				
			||||||
are somewhat hard coded in the script.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Each node is also configured with a disk, which is mounted inside the
 | 
					 | 
				
			||||||
`etcd` container. `etcd` uses it to keep some state to help with
 | 
					 | 
				
			||||||
restarts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## GCP Setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You probably want to change the project/zone
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
export CLOUDSDK_CORE_PROJECT=docker4x
 | 
					 | 
				
			||||||
export CLOUDSDK_COMPUTE_ZONE=europe-west1-d
 | 
					 | 
				
			||||||
gcloud auth login
 | 
					 | 
				
			||||||
gcloud auth application-default login
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You may also want to create ssh-keys and upload them. See the [Generating a new SSH key-pair section](https://cloud.google.com/compute/docs/instances/connecting-to-instance)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note, the demo uses static IP addresses and they are specific to our
 | 
					 | 
				
			||||||
setup. The IP addresses need to be changed in the `infrakit-gcp.json`
 | 
					 | 
				
			||||||
config file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In order to use the static IP addresses we created a custom network:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
gcloud compute networks create rneugeba-demo --mode auto
 | 
					 | 
				
			||||||
gcloud compute networks subnets list
 | 
					 | 
				
			||||||
# get IP subnet for rneugeba-demo
 | 
					 | 
				
			||||||
gcloud compute firewall-rules create rneugeba-demo-internal --network \
 | 
					 | 
				
			||||||
    rneugeba-demo --allow tcp,udp,icmp --source-ranges 10.132.0.0/9
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
The firewall setup means that all our projects networks can talk to the demo
 | 
					 | 
				
			||||||
network.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Preparation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We create a number of local packages, not pulled from Hub. To build them, invoke `./build-pkg.sh` in the `./pkg` directory.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Then build the various YAML files using the `linuxkit` tool and package/upload them to Google Cloud using the `linuxkit` tool.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## InfraKit cluster setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This should create a HyperKit based, InfraKit managed `etcd` cluster with 5 `etcd` instances.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Start InfraKit:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
./start-infrakit
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note: The HyperKit InfraKit plugin must be started from the directory
 | 
					 | 
				
			||||||
where the `etcd` mobylinux image is located.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Now, commit the new config:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
infrakit group commit infrakit.json
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To check if everything is fine, we created (above) a local `etcd.local` docker image which already has the environment set up to contact the cluster:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
docker run --rm -ti etcd.local etcdctl member list
 | 
					 | 
				
			||||||
docker run --rm -ti etcd.local etcdctl cluster-health
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can perform rolling updates, by for example, switching the kernel version in `etcd.yml`, build a new LinuxKit, e.g., `linuxkit build -name etcd-4.10 etcd`, update `infrakit.json`, and then commit the new configuration to InfraKit: `infrakit group commit infrakit.json`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Infrakit GCP setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Start infrakit as above:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
./start-infrakit
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Commit the configuration:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
infrakit group commit infrakit-gcp.json
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Prometheus server
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The etcd nodes use the Prometheus node exported. You can use the prometheus server image, also in this directory, to collect statistics from etc node. We currently build a specific Prometheus images with hard coded IP addresses. Ideally, the information should be passed in via the metadata/userdata.
 | 
					 | 
				
			||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
kernel:
 | 
					 | 
				
			||||||
  image: linuxkit/kernel:4.9.74
 | 
					 | 
				
			||||||
  cmdline: "console=ttyS0 console=tty0 page_poison=1"
 | 
					 | 
				
			||||||
init:
 | 
					 | 
				
			||||||
  - linuxkit/init:5a577d070817b4f17821657823082651baafd4ed
 | 
					 | 
				
			||||||
  - linuxkit/runc:abc3f292653e64a2fd488e9675ace19a55ec7023
 | 
					 | 
				
			||||||
  - linuxkit/containerd:e58a382c33bb509ba3e0e8170dfaa5a100504c5b
 | 
					 | 
				
			||||||
  - linuxkit/ca-certificates:de21b84d9b055ad9dcecc57965b654a7a24ef8e0
 | 
					 | 
				
			||||||
onboot:
 | 
					 | 
				
			||||||
  - name: sysctl
 | 
					 | 
				
			||||||
    image: linuxkit/sysctl:4c1ef93bb5eb1a877318db4b2daa6768ed002e21
 | 
					 | 
				
			||||||
  - name: format
 | 
					 | 
				
			||||||
    image: linuxkit/format:e945016ec780a788a71dcddc81497d54d3b14bc7
 | 
					 | 
				
			||||||
  - name: mount
 | 
					 | 
				
			||||||
    image: linuxkit/mount:b346ec277b7074e5c9986128a879c10a1d18742b
 | 
					 | 
				
			||||||
    command: ["/usr/bin/mountie", "/var/lib/etcd"]
 | 
					 | 
				
			||||||
  - name: dhcpcd
 | 
					 | 
				
			||||||
    image: linuxkit/dhcpcd:0d59a6cc03412289ef4313f2491ec666c1715cc9
 | 
					 | 
				
			||||||
    command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
 | 
					 | 
				
			||||||
  - name: metadata
 | 
					 | 
				
			||||||
    image: linuxkit/metadata:2af15c9f4b0e73515c219b7cc14e6e65e1d4fd6d
 | 
					 | 
				
			||||||
services:
 | 
					 | 
				
			||||||
  - name: rngd
 | 
					 | 
				
			||||||
    image: linuxkit/rngd:94e01a4b16fadb053455cdc2269c4eb0b39199cd
 | 
					 | 
				
			||||||
  - name: ntpd
 | 
					 | 
				
			||||||
    image: linuxkit/openntpd:536e5947607c9e6a6771957c2ff817230cba0d3c
 | 
					 | 
				
			||||||
  - name: node_exporter
 | 
					 | 
				
			||||||
    image: linuxkit/node_exporter:db8ba40196c010d06f15ffd231132d360614d507
 | 
					 | 
				
			||||||
  - name: etcd
 | 
					 | 
				
			||||||
    image: moby/etcd
 | 
					 | 
				
			||||||
    capabilities:
 | 
					 | 
				
			||||||
     - CAP_CHOWN
 | 
					 | 
				
			||||||
     - CAP_SETUID
 | 
					 | 
				
			||||||
     - CAP_SETGID
 | 
					 | 
				
			||||||
     - CAP_DAC_OVERRIDE
 | 
					 | 
				
			||||||
     - CAP_SYS_ADMIN
 | 
					 | 
				
			||||||
     - CAP_MKNOD
 | 
					 | 
				
			||||||
    net: host
 | 
					 | 
				
			||||||
    binds:
 | 
					 | 
				
			||||||
     - /var/lib/etcd:/var/lib/etcd
 | 
					 | 
				
			||||||
     - /var/config/etcd:/etc/etcd
 | 
					 | 
				
			||||||
trust:
 | 
					 | 
				
			||||||
  org:
 | 
					 | 
				
			||||||
    - linuxkit
 | 
					 | 
				
			||||||
@@ -1,53 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    "ID": "etcd.gcp",
 | 
					 | 
				
			||||||
    "Properties": {
 | 
					 | 
				
			||||||
        "Allocation": {
 | 
					 | 
				
			||||||
            "LogicalIDs": [
 | 
					 | 
				
			||||||
                "10.132.0.200",
 | 
					 | 
				
			||||||
                "10.132.0.201",
 | 
					 | 
				
			||||||
                "10.132.0.202",
 | 
					 | 
				
			||||||
                "10.132.0.203",
 | 
					 | 
				
			||||||
                "10.132.0.204"
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "Instance": {
 | 
					 | 
				
			||||||
            "Plugin": "instance-gcp",
 | 
					 | 
				
			||||||
            "Properties": {
 | 
					 | 
				
			||||||
                "NamePrefix": "etcd-demo",
 | 
					 | 
				
			||||||
                "Description": "ETCD test cluster",
 | 
					 | 
				
			||||||
                "Network": "rneugeba-demo",
 | 
					 | 
				
			||||||
                "Connect" : true,
 | 
					 | 
				
			||||||
                "MachineType": "n1-standard-1",
 | 
					 | 
				
			||||||
                "DiskType": "pd-standard",
 | 
					 | 
				
			||||||
                "DiskSizeMb": 60,
 | 
					 | 
				
			||||||
                "DiskImage": "https://www.googleapis.com/compute/v1/projects/docker4x/global/images/etcd",
 | 
					 | 
				
			||||||
                "AutoDeleteDisk": true,
 | 
					 | 
				
			||||||
                "ReuseExistingDisk": false,
 | 
					 | 
				
			||||||
                "Scopes": [ ]
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "Flavor": {
 | 
					 | 
				
			||||||
            "Plugin": "flavor-vanilla",
 | 
					 | 
				
			||||||
            "Properties": {
 | 
					 | 
				
			||||||
                "Init": [
 | 
					 | 
				
			||||||
                    "{",
 | 
					 | 
				
			||||||
                    "  \"etcd\": {",
 | 
					 | 
				
			||||||
                    "    \"name_prefix\": {",
 | 
					 | 
				
			||||||
                    "      \"perm\": \"0644\",",
 | 
					 | 
				
			||||||
                    "      \"content\": \"server\"",
 | 
					 | 
				
			||||||
                         "},",
 | 
					 | 
				
			||||||
                    "    \"init_cluster\": {",
 | 
					 | 
				
			||||||
                    "      \"perm\": \"0644\",",
 | 
					 | 
				
			||||||
                    "      \"content\": \"server200=http://10.132.0.200:2380,server201=http://10.132.0.201:2380,server202=http://10.132.0.202:2380,server203=http://10.132.0.203:2380,server204=http://10.132.0.204:2380\"",
 | 
					 | 
				
			||||||
                         "}",
 | 
					 | 
				
			||||||
                       "}",
 | 
					 | 
				
			||||||
                    "}"
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                "Tags": {
 | 
					 | 
				
			||||||
                    "tier": "etcd-cluster",
 | 
					 | 
				
			||||||
                    "project": "infrakit"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,46 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    "ID": "etcd",
 | 
					 | 
				
			||||||
    "Properties": {
 | 
					 | 
				
			||||||
        "Allocation": {
 | 
					 | 
				
			||||||
            "LogicalIDs": [
 | 
					 | 
				
			||||||
                "192.168.65.200",
 | 
					 | 
				
			||||||
                "192.168.65.201",
 | 
					 | 
				
			||||||
                "192.168.65.202",
 | 
					 | 
				
			||||||
                "192.168.65.203",
 | 
					 | 
				
			||||||
                "192.168.65.204"
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "Instance": {
 | 
					 | 
				
			||||||
            "Plugin": "instance-hyperkit",
 | 
					 | 
				
			||||||
            "Properties": {
 | 
					 | 
				
			||||||
                "kernel+initrd": "etcd",
 | 
					 | 
				
			||||||
                "Disk" : 2048,
 | 
					 | 
				
			||||||
                "CPUs" : 1,
 | 
					 | 
				
			||||||
                "Memory" : 1024
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "Flavor": {
 | 
					 | 
				
			||||||
            "Plugin": "flavor-vanilla",
 | 
					 | 
				
			||||||
            "Properties": {
 | 
					 | 
				
			||||||
                "Init": [
 | 
					 | 
				
			||||||
                    "{",
 | 
					 | 
				
			||||||
                    "  \"etcd\": {",
 | 
					 | 
				
			||||||
                    "    \"name_prefix\": {",
 | 
					 | 
				
			||||||
                    "      \"perm\": \"0644\",",
 | 
					 | 
				
			||||||
                    "      \"content\": \"server\"",
 | 
					 | 
				
			||||||
                         "},",
 | 
					 | 
				
			||||||
                    "    \"init_cluster\": {",
 | 
					 | 
				
			||||||
                    "      \"perm\": \"0644\",",
 | 
					 | 
				
			||||||
                    "      \"content\": \"server200=http://192.168.65.200:2380,server201=http://192.168.65.201:2380,server202=http://192.168.65.202:2380,server203=http://192.168.65.203:2380,server204=http://192.168.65.204:2380\"",
 | 
					 | 
				
			||||||
                         "}",
 | 
					 | 
				
			||||||
                       "}",
 | 
					 | 
				
			||||||
                    "}"
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                "Tags": {
 | 
					 | 
				
			||||||
                    "tier": "etcd-cluster",
 | 
					 | 
				
			||||||
                    "project": "infrakit"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
FROM quay.io/coreos/etcd:v3.1.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY ./etcd.sh /
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENTRYPOINT ["/etcd.sh"]
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
# A dockerfile to build an etcd container image from the upstream one
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# It sets the environment to talk to the local cluster
 | 
					 | 
				
			||||||
FROM quay.io/coreos/etcd:v3.1.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENV ETCDCTL_ENDPOINTS="http://192.168.65.200:2379,http://192.168.65.201:2379,http://192.168.65.202:2379,http://192.168.65.203:2379,http://192.168.65.204:2379"
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
FROM prom/prometheus
 | 
					 | 
				
			||||||
ADD etc/prometheus-local.yml /etc/prometheus/prometheus.yml
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
FROM prom/prometheus
 | 
					 | 
				
			||||||
ADD etc/prometheus-us-central.yml /etc/prometheus/prometheus.yml
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
#! /bin/sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
docker build -t moby/etcd -f Dockerfile.etcd .
 | 
					 | 
				
			||||||
docker build -t etcd.local -f Dockerfile.etcd.local .
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
docker build -t moby/prom-us-central1-f -f Dockerfile.prom.us-central1-f .
 | 
					 | 
				
			||||||
docker build -t moby/prom-local -f Dockerfile.prom.local .
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
global:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
scrape_configs:
 | 
					 | 
				
			||||||
  # - job_name: 'prometheus'
 | 
					 | 
				
			||||||
  #   scrape_interval: 20s
 | 
					 | 
				
			||||||
  #   static_configs:
 | 
					 | 
				
			||||||
  #     - targets: ['localhost:9090']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Scrape the Node Exporter
 | 
					 | 
				
			||||||
  - job_name: 'node'
 | 
					 | 
				
			||||||
    scrape_interval: 20s
 | 
					 | 
				
			||||||
    static_configs:
 | 
					 | 
				
			||||||
      - targets: ['localhost:9100', 'localhost:9101', 'localhost:9102', 'localhost:9103', 'localhost:9104']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # # Scrape the containerd exporter
 | 
					 | 
				
			||||||
  # - job_name: 'containerd'
 | 
					 | 
				
			||||||
  #   scrape_interval: 15s
 | 
					 | 
				
			||||||
  #   static_configs:
 | 
					 | 
				
			||||||
  #     - targets: ['192.168.65.200:13337', '192.168.65.201:13337', '192.168.65.202:13337', '192.168.65.203:13337', '192.168.65.204:13337']
 | 
					 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
global:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
scrape_configs:
 | 
					 | 
				
			||||||
  - job_name: 'prometheus'
 | 
					 | 
				
			||||||
    scrape_interval: 20s
 | 
					 | 
				
			||||||
    static_configs:
 | 
					 | 
				
			||||||
      - targets: ['localhost:9090']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Scrape the Node Exporter
 | 
					 | 
				
			||||||
  - job_name: 'node'
 | 
					 | 
				
			||||||
    scrape_interval: 20s
 | 
					 | 
				
			||||||
    static_configs:
 | 
					 | 
				
			||||||
      - targets: ['10.128.0.200:9100', '10.128.0.201:9100', '10.128.0.202:9100', '10.128.0.203:9100', '10.128.0.204:9100']
 | 
					 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
global:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
scrape_configs:
 | 
					 | 
				
			||||||
  - job_name: 'prometheus'
 | 
					 | 
				
			||||||
    scrape_interval: 20s
 | 
					 | 
				
			||||||
    static_configs:
 | 
					 | 
				
			||||||
      - targets: ['localhost:9090']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Scrape the Node Exporter
 | 
					 | 
				
			||||||
  - job_name: 'node'
 | 
					 | 
				
			||||||
    scrape_interval: 20s
 | 
					 | 
				
			||||||
    static_configs:
 | 
					 | 
				
			||||||
      - targets: ['10.128.0.200:9100', '10.128.0.201:9100', '10.128.0.202:9100', '10.128.0.203:9100', '10.128.0.204:9100']
 | 
					 | 
				
			||||||
@@ -1,58 +0,0 @@
 | 
				
			|||||||
#! /bin/sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# debug
 | 
					 | 
				
			||||||
set -x
 | 
					 | 
				
			||||||
set -v
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Get initial cluster data from metadata
 | 
					 | 
				
			||||||
NAME_PREFIX="$(cat /etc/etcd/name_prefix)"
 | 
					 | 
				
			||||||
INIT_CLUSTER="$(cat /etc/etcd/init_cluster)"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Wait till we have an IP address
 | 
					 | 
				
			||||||
IP=""
 | 
					 | 
				
			||||||
while [ -z "$IP" ]; do
 | 
					 | 
				
			||||||
    IP=$(ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://')
 | 
					 | 
				
			||||||
    sleep 1
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Where to store data
 | 
					 | 
				
			||||||
DATADIR=/var/lib/etcd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Name is NAME_PREFIX+last octet of IP address
 | 
					 | 
				
			||||||
NUM=$(echo ${IP} | cut -d . -f 4)
 | 
					 | 
				
			||||||
NAME=${NAME_PREFIX}${NUM}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# We currently have no easy way to determine if we join a cluster for
 | 
					 | 
				
			||||||
# the first time or if we got restarted and need to join an existing
 | 
					 | 
				
			||||||
# cluster. So we first try joining a *new* cluster. This fails if we
 | 
					 | 
				
			||||||
# had already joined it previously. As a fallback we then try to join
 | 
					 | 
				
			||||||
# an existing cluster.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Try to join an new cluster
 | 
					 | 
				
			||||||
/usr/local/bin/etcd \
 | 
					 | 
				
			||||||
    --name ${NAME} \
 | 
					 | 
				
			||||||
    --debug \
 | 
					 | 
				
			||||||
    --log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
 | 
					 | 
				
			||||||
    --data-dir $DATADIR \
 | 
					 | 
				
			||||||
    --initial-advertise-peer-urls http://${IP}:2380 \
 | 
					 | 
				
			||||||
    --listen-peer-urls http://${IP}:2380 \
 | 
					 | 
				
			||||||
    --listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
 | 
					 | 
				
			||||||
    --advertise-client-urls http://${IP}:2379 \
 | 
					 | 
				
			||||||
    --initial-cluster-token etcd-cluster-1 \
 | 
					 | 
				
			||||||
    --initial-cluster ${INIT_CLUSTER} \
 | 
					 | 
				
			||||||
    --initial-cluster-state new
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[ $? -eq 0 ] && exit 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Try to join an existing cluster
 | 
					 | 
				
			||||||
/usr/local/bin/etcd \
 | 
					 | 
				
			||||||
    --name ${NAME} \
 | 
					 | 
				
			||||||
    --debug \
 | 
					 | 
				
			||||||
    --log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
 | 
					 | 
				
			||||||
    --data-dir $DATADIR \
 | 
					 | 
				
			||||||
    --initial-advertise-peer-urls http://${IP}:2380 \
 | 
					 | 
				
			||||||
    --listen-peer-urls http://${IP}:2380 \
 | 
					 | 
				
			||||||
    --listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
 | 
					 | 
				
			||||||
    --advertise-client-urls http://${IP}:2379 \
 | 
					 | 
				
			||||||
    --initial-cluster ${INIT_CLUSTER} \
 | 
					 | 
				
			||||||
    --initial-cluster-state existing
 | 
					 | 
				
			||||||
@@ -1,30 +0,0 @@
 | 
				
			|||||||
kernel:
 | 
					 | 
				
			||||||
  image: mobylinux/kernel:4.9.x
 | 
					 | 
				
			||||||
  cmdline: "console=ttyS0 page_poison=1"
 | 
					 | 
				
			||||||
init:
 | 
					 | 
				
			||||||
  - linuxkit/init:5a577d070817b4f17821657823082651baafd4ed
 | 
					 | 
				
			||||||
  - mobylinux/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
 | 
					 | 
				
			||||||
  - mobylinux/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b
 | 
					 | 
				
			||||||
  - mobylinux/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935
 | 
					 | 
				
			||||||
onboot:
 | 
					 | 
				
			||||||
  - name: sysctl
 | 
					 | 
				
			||||||
    image: linuxkit/sysctl:4c1ef93bb5eb1a877318db4b2daa6768ed002e21
 | 
					 | 
				
			||||||
  - name: dhcpcd
 | 
					 | 
				
			||||||
    image: linuxkit/dhcpcd:0d59a6cc03412289ef4313f2491ec666c1715cc9
 | 
					 | 
				
			||||||
    command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
 | 
					 | 
				
			||||||
  - name: metadata
 | 
					 | 
				
			||||||
    image: linuxkit/metadata:2af15c9f4b0e73515c219b7cc14e6e65e1d4fd6d
 | 
					 | 
				
			||||||
services:
 | 
					 | 
				
			||||||
  - name: rngd
 | 
					 | 
				
			||||||
    image: mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9
 | 
					 | 
				
			||||||
  - name: prometheus
 | 
					 | 
				
			||||||
    image: moby/prom-us-central1-f
 | 
					 | 
				
			||||||
    binds:
 | 
					 | 
				
			||||||
      - /dev:/dev
 | 
					 | 
				
			||||||
      - /var/lib/misc:/data
 | 
					 | 
				
			||||||
    capabilities:
 | 
					 | 
				
			||||||
      - all
 | 
					 | 
				
			||||||
    net: host
 | 
					 | 
				
			||||||
trust:
 | 
					 | 
				
			||||||
  image:
 | 
					 | 
				
			||||||
    - mobylinux/kernel
 | 
					 | 
				
			||||||
@@ -1,20 +0,0 @@
 | 
				
			|||||||
# !/bin/sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Start the infrakit plugins, save their PID
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
INFRAKIT_HOME=~/.infrakit
 | 
					 | 
				
			||||||
IK_PLUGINS=$INFRAKIT_HOME/plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rm -rf $INFRAKIT_HOME
 | 
					 | 
				
			||||||
mkdir -p $INFRAKIT_HOME/cli
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
infrakit-flavor-vanilla &
 | 
					 | 
				
			||||||
infrakit-instance-hyperkit &
 | 
					 | 
				
			||||||
infrakit-instance-gcp --project $CLOUDSDK_CORE_PROJECT --zone $CLOUDSDK_COMPUTE_ZONE &
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# start the group plugin in the foreground. If it exits, it will take
 | 
					 | 
				
			||||||
# the others down as well.
 | 
					 | 
				
			||||||
infrakit-group-default
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rm -rf $INFRAKIT_HOME
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								projects/kernel-config/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								projects/kernel-config/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
check-kernel-config.sh
 | 
					 | 
				
			||||||
@@ -1,75 +0,0 @@
 | 
				
			|||||||
FROM linuxkit/kernel-compile:1b396c221af673757703258159ddc8539843b02b@sha256:6b32d205bfc6407568324337b707d195d027328dbfec554428ea93e7b0a8299b AS kernel-build
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ARG KERNEL_VERSION
 | 
					 | 
				
			||||||
ARG KERNEL_SERIES
 | 
					 | 
				
			||||||
ARG ARCH
 | 
					 | 
				
			||||||
ARG DEBUG
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN mkdir /config
 | 
					 | 
				
			||||||
COPY kernel_config.* /config/
 | 
					 | 
				
			||||||
COPY *.sh /config/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN \
 | 
					 | 
				
			||||||
  if [ -n "${DEBUG}" ]; then dbg=kernel_config.debug; else dbg=; fi && \
 | 
					 | 
				
			||||||
  /config/makeconfig.sh \
 | 
					 | 
				
			||||||
    kernel_config.base \
 | 
					 | 
				
			||||||
    "kernel_config.${ARCH}" \
 | 
					 | 
				
			||||||
    "kernel_config.${ARCH}.${KERNEL_SERIES}" \
 | 
					 | 
				
			||||||
    "kernel_config.${KERNEL_SERIES}" \
 | 
					 | 
				
			||||||
    "$dbg"
 | 
					 | 
				
			||||||
RUN /config/check-kernel-config.sh /linux/.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN mkdir /out
 | 
					 | 
				
			||||||
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Kernel
 | 
					 | 
				
			||||||
RUN 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 )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM linuxkit/toybox-media:eee3dd4d72cd784801e95b1781e6c4f9d8a5e5eb@sha256:7f940e687164ee2676e11c61705c79f7dd2d144ee87ad17a494848a7045f5f53
 | 
					 | 
				
			||||||
ENTRYPOINT []
 | 
					 | 
				
			||||||
CMD []
 | 
					 | 
				
			||||||
WORKDIR /
 | 
					 | 
				
			||||||
COPY --from=kernel-build /out/* /
 | 
					 | 
				
			||||||
@@ -1,74 +0,0 @@
 | 
				
			|||||||
# 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
 | 
					 | 
				
			||||||
ARCH?=x86_64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.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
 | 
					 | 
				
			||||||
build_$(2)$(3): Dockerfile Makefile $(wildcard patches-$(2)/*) $(wildcard kernel_config.$(2)*) kernel_config.base kernel_config.$(ARCH)
 | 
					 | 
				
			||||||
	cp ../../test/pkg/kernel-config/check-kernel-config.sh .
 | 
					 | 
				
			||||||
	docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
 | 
					 | 
				
			||||||
		docker build \
 | 
					 | 
				
			||||||
			--build-arg KERNEL_VERSION=$(1) \
 | 
					 | 
				
			||||||
			--build-arg KERNEL_SERIES=$(2) \
 | 
					 | 
				
			||||||
			--build-arg ARCH=$(ARCH) \
 | 
					 | 
				
			||||||
			--build-arg DEBUG=$(3) \
 | 
					 | 
				
			||||||
			--no-cache -t linuxkit/$(IMAGE):$(1)$(3)-$(HASH) .
 | 
					 | 
				
			||||||
	-rm check-kernel-config.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.11.2,4.11.x))
 | 
					 | 
				
			||||||
$(eval $(call kernel,4.11.2,4.11.x,_dbg))
 | 
					 | 
				
			||||||
$(eval $(call kernel,4.10.17,4.10.x))
 | 
					 | 
				
			||||||
$(eval $(call kernel,4.10.17,4.10.x,_dbg))
 | 
					 | 
				
			||||||
$(eval $(call kernel,4.9.29,4.9.x))
 | 
					 | 
				
			||||||
$(eval $(call kernel,4.9.29,4.9.x,_dbg))
 | 
					 | 
				
			||||||
@@ -1,38 +0,0 @@
 | 
				
			|||||||
## kernel config project
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The intent of the kernel config project is to demonstrate a better way to
 | 
					 | 
				
			||||||
handle kernel config. Specifically:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* support for arch and version specific config
 | 
					 | 
				
			||||||
* make diffs as readable as possible
 | 
					 | 
				
			||||||
* ensure that all of our config settings are kept after oldconfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We achieve the goals by:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* having version-specific config in separate files, which are automatically
 | 
					 | 
				
			||||||
  merged
 | 
					 | 
				
			||||||
* only keeping track of visible symbols, only keeping track of a delta from
 | 
					 | 
				
			||||||
  defconfig, and keeping symbols sorted alphabetically
 | 
					 | 
				
			||||||
* checking after a `make oldconfig` in the kernel, that all of our symbols are
 | 
					 | 
				
			||||||
  set as we want them to be
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The bulk of this work happens in makeconfig.sh, which merges the configs (and
 | 
					 | 
				
			||||||
checks that the resulting config is okay).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
One important piece is generating a kernel config for a new version. There are
 | 
					 | 
				
			||||||
a few cases:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* A new kconfig symbol is introduced that we want to set a non-default value
 | 
					 | 
				
			||||||
  of: in this case, we introduce a new `kernel_config.${VERSION}` file, and set
 | 
					 | 
				
			||||||
  the value to what we want to set it to
 | 
					 | 
				
			||||||
* A config symbol that was no-default before become the default: in this case,
 | 
					 | 
				
			||||||
  we would move the non-default setting to version specific files for all of
 | 
					 | 
				
			||||||
  the other versions, and not set anything for this new kernel, since what we
 | 
					 | 
				
			||||||
  want is now the default.
 | 
					 | 
				
			||||||
* A symbol we want to set is removed (or renamed), similar to the above, we
 | 
					 | 
				
			||||||
  simply move the old symbol name to version specific files for older kernels
 | 
					 | 
				
			||||||
  and put the new symbol name (if it exists) in the new version specific file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When dropping support for an old kernel version, we just delete that version
 | 
					 | 
				
			||||||
specific file, and promote any option that is present in all other versions to
 | 
					 | 
				
			||||||
the common config file.
 | 
					 | 
				
			||||||
@@ -1,84 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import subprocess
 | 
					 | 
				
			||||||
import os.path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import kconfiglib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
KERNEL_VERSION="4.11.x"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LINUXKIT_KERNEL=os.path.expanduser("~/packages/linuxkit/kernel")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def collect_config(f):
 | 
					 | 
				
			||||||
    config = {}
 | 
					 | 
				
			||||||
    for line in f:
 | 
					 | 
				
			||||||
        line = line.strip()
 | 
					 | 
				
			||||||
        if line.startswith("# CONFIG_"):
 | 
					 | 
				
			||||||
            opt = line[len("# CONFIG_"):-len(" is not set")]
 | 
					 | 
				
			||||||
            value = "n"
 | 
					 | 
				
			||||||
        elif line.startswith("CONFIG_"):
 | 
					 | 
				
			||||||
            [opt, value] = line.strip().split("=")
 | 
					 | 
				
			||||||
            opt = opt[len("CONFIG_"):]
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        config[opt] = value
 | 
					 | 
				
			||||||
    return config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
with open(os.path.join(LINUXKIT_KERNEL, "kernel_config-%s" % KERNEL_VERSION)) as f:
 | 
					 | 
				
			||||||
    config = collect_config(f)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
opts = sorted(config.keys())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
klib = kconfiglib.Config(sys.argv[1])
 | 
					 | 
				
			||||||
# this needs to be `make defconfig`
 | 
					 | 
				
			||||||
klib.load_config(".config")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ours = kconfiglib.Config(sys.argv[1])
 | 
					 | 
				
			||||||
ours.load_config(os.path.join(LINUXKIT_KERNEL, "kernel_config-%s" % KERNEL_VERSION))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
arch = []
 | 
					 | 
				
			||||||
generic = []
 | 
					 | 
				
			||||||
for o in opts:
 | 
					 | 
				
			||||||
    # our hyperv patch stuff
 | 
					 | 
				
			||||||
    if o in ("AF_KCM", "HYPERV_SOCK", "VIRTIO_VSOCKETS", "VIRTIO_VSOCKETS_COMMON", "HYPERV_VSOCKETS"):
 | 
					 | 
				
			||||||
        generic.append(o)
 | 
					 | 
				
			||||||
        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sym = klib.get_symbol(o)
 | 
					 | 
				
			||||||
    if sym is None:
 | 
					 | 
				
			||||||
        print("symbol %s unknown" % o)
 | 
					 | 
				
			||||||
        sys.exit(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    oursym = ours.get_symbol(o)
 | 
					 | 
				
			||||||
    if sym is None:
 | 
					 | 
				
			||||||
        print("symbol %s unknown" % o)
 | 
					 | 
				
			||||||
        sys.exit(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # don't render invisble symbols
 | 
					 | 
				
			||||||
    if oursym.get_visibility() == 'n':
 | 
					 | 
				
			||||||
        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # If defconfig of this symbol matches our value, we don't need to track it:
 | 
					 | 
				
			||||||
    value = config[o]
 | 
					 | 
				
			||||||
    if value == sym.get_value():
 | 
					 | 
				
			||||||
        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if sym.get_def_locations()[0][0].startswith("arch"):
 | 
					 | 
				
			||||||
        arch.append(o)
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        generic.append(o)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def render_diff(diff):
 | 
					 | 
				
			||||||
    for o in sorted(diff):
 | 
					 | 
				
			||||||
        value = config[o]
 | 
					 | 
				
			||||||
        if value == "n":
 | 
					 | 
				
			||||||
            print("# CONFIG_%s is not set" % o)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            print("CONFIG_%s=%s" % (o, value))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print("ARCH\n\n")
 | 
					 | 
				
			||||||
render_diff(arch)
 | 
					 | 
				
			||||||
print("\n\nGENRIC\n\n")
 | 
					 | 
				
			||||||
render_diff(generic)
 | 
					 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
CONFIG_CRYPTO_CMAC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DEV_VIRTIO=m
 | 
					 | 
				
			||||||
CONFIG_HYPERV_SOCK=y
 | 
					 | 
				
			||||||
CONFIG_LWTUNNEL_BPF=y
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
 | 
					 | 
				
			||||||
# CONFIG_SYNC_FILE is not set
 | 
					 | 
				
			||||||
# CONFIG_TIMER_STATS is not set
 | 
					 | 
				
			||||||
CONFIG_UPROBE_EVENT=y
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
CONFIG_HYPERV_VSOCKETS=y
 | 
					 | 
				
			||||||
CONFIG_INPUT_MOUSEDEV=y
 | 
					 | 
				
			||||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 | 
					 | 
				
			||||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 | 
					 | 
				
			||||||
CONFIG_PTP_1588_CLOCK_KVM=y
 | 
					 | 
				
			||||||
# CONFIG_R8169 is not set
 | 
					 | 
				
			||||||
# CONFIG_RCU_TRACE is not set
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
CONFIG_CRYPTO_CMAC=y
 | 
					 | 
				
			||||||
# CONFIG_DEVKMEM is not set
 | 
					 | 
				
			||||||
CONFIG_HYPERV_SOCK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
 | 
					 | 
				
			||||||
# CONFIG_TIMER_STATS is not set
 | 
					 | 
				
			||||||
CONFIG_UPROBE_EVENT=y
 | 
					 | 
				
			||||||
@@ -1,834 +0,0 @@
 | 
				
			|||||||
CONFIG_8139CP=y
 | 
					 | 
				
			||||||
# CONFIG_8139TOO is not set
 | 
					 | 
				
			||||||
CONFIG_9P_FS=y
 | 
					 | 
				
			||||||
CONFIG_9P_FSCACHE=y
 | 
					 | 
				
			||||||
CONFIG_9P_FS_POSIX_ACL=y
 | 
					 | 
				
			||||||
CONFIG_9P_FS_SECURITY=y
 | 
					 | 
				
			||||||
CONFIG_ACPI_APEI=y
 | 
					 | 
				
			||||||
CONFIG_ACPI_APEI_GHES=y
 | 
					 | 
				
			||||||
CONFIG_ACPI_HED=y
 | 
					 | 
				
			||||||
CONFIG_ACPI_PROCESSOR_AGGREGATOR=y
 | 
					 | 
				
			||||||
# CONFIG_ACPI_REV_OVERRIDE_POSSIBLE is not set
 | 
					 | 
				
			||||||
CONFIG_ACPI_SBS=y
 | 
					 | 
				
			||||||
CONFIG_ACPI_WMI=y
 | 
					 | 
				
			||||||
# CONFIG_AF_KCM is not set
 | 
					 | 
				
			||||||
# CONFIG_AGP is not set
 | 
					 | 
				
			||||||
# CONFIG_AMIGA_PARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
 | 
					 | 
				
			||||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
 | 
					 | 
				
			||||||
CONFIG_ATA_GENERIC=y
 | 
					 | 
				
			||||||
CONFIG_ATA_OVER_ETH=y
 | 
					 | 
				
			||||||
# CONFIG_ATA_VERBOSE_ERROR is not set
 | 
					 | 
				
			||||||
# CONFIG_AUTOFS4_FS is not set
 | 
					 | 
				
			||||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 | 
					 | 
				
			||||||
CONFIG_BALLOON_COMPACTION=y
 | 
					 | 
				
			||||||
CONFIG_BIG_KEYS=y
 | 
					 | 
				
			||||||
CONFIG_BLK_CGROUP=y
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_CRYPTOLOOP=y
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_INTEGRITY=y
 | 
					 | 
				
			||||||
# CONFIG_BLK_DEV_MD is not set
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_NBD=y
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_NVME=y
 | 
					 | 
				
			||||||
# CONFIG_BLK_DEV_SR_VENDOR is not set
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_THROTTLING=y
 | 
					 | 
				
			||||||
CONFIG_BONDING=y
 | 
					 | 
				
			||||||
CONFIG_BPF_JIT=y
 | 
					 | 
				
			||||||
CONFIG_BPF_SYSCALL=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_802_3=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_AMONG=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_ARP=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_ARPREPLY=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_BROUTE=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_DNAT=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_IP=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_IP6=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_LIMIT=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_LOG=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_MARK=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_MARK_T=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_NFLOG=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_PKTTYPE=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_REDIRECT=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_SNAT=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_STP=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_T_FILTER=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_T_NAT=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_EBT_VLAN=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_IGMP_SNOOPING=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_NETFILTER=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_NF_EBTABLES=y
 | 
					 | 
				
			||||||
CONFIG_BRIDGE_VLAN_FILTERING=y
 | 
					 | 
				
			||||||
# CONFIG_BSD_DISKLABEL is not set
 | 
					 | 
				
			||||||
CONFIG_BSD_PROCESS_ACCT_V3=y
 | 
					 | 
				
			||||||
CONFIG_BTRFS_FS=m
 | 
					 | 
				
			||||||
CONFIG_BTRFS_FS_POSIX_ACL=y
 | 
					 | 
				
			||||||
CONFIG_CACHEFILES=y
 | 
					 | 
				
			||||||
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
 | 
					 | 
				
			||||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 | 
					 | 
				
			||||||
CONFIG_CFQ_GROUP_IOSCHED=y
 | 
					 | 
				
			||||||
CONFIG_CFS_BANDWIDTH=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_DEVICE=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_HUGETLB=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_NET_CLASSID=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_NET_PRIO=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_PERF=y
 | 
					 | 
				
			||||||
CONFIG_CGROUP_PIDS=y
 | 
					 | 
				
			||||||
CONFIG_CHECKPOINT_RESTORE=y
 | 
					 | 
				
			||||||
CONFIG_CIFS=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_DEBUG=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_DFS_UPCALL=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_FSCACHE=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_POSIX=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_SMB2=y
 | 
					 | 
				
			||||||
CONFIG_CIFS_XATTR=y
 | 
					 | 
				
			||||||
CONFIG_CLS_U32_MARK=y
 | 
					 | 
				
			||||||
CONFIG_CLS_U32_PERF=y
 | 
					 | 
				
			||||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 | 
					 | 
				
			||||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 | 
					 | 
				
			||||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 | 
					 | 
				
			||||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 | 
					 | 
				
			||||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 | 
					 | 
				
			||||||
CONFIG_CPU_FREQ_STAT=y
 | 
					 | 
				
			||||||
CONFIG_CPU_IDLE_GOV_LADDER=y
 | 
					 | 
				
			||||||
CONFIG_CRC_ITU_T=y
 | 
					 | 
				
			||||||
CONFIG_CRC_T10DIF=y
 | 
					 | 
				
			||||||
CONFIG_CROSS_COMPILE=""
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_842=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_AES_NI_INTEL=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_AES_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_ANSI_CPRNG=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_ANUBIS=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_BLOWFISH=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_BLOWFISH_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAMELLIA=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAMELLIA_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAST5=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAST5_AVX_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAST6=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CAST6_AVX_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CHACHA20=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CHACHA20POLY1305=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CHACHA20_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CRC32=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CRC32C_INTEL=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CRC32_PCLMUL=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CRCT10DIF=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CRYPTD=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_CTS=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DEFLATE=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DES3_EDE_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DEV_PADLOCK=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DEV_PADLOCK_AES=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_DEV_PADLOCK_SHA=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_ECB=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_FCRYPT=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_KEYWRAP=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_KHAZAD=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_LRW=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_LZ4=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_LZ4HC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_LZO=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_MD4=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_MICHAEL_MIC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_PCBC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_POLY1305=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_POLY1305_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_RMD128=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_RMD160=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_RMD256=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_RMD320=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_RSA=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SALSA20=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SALSA20_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SEED=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SERPENT=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SERPENT_AVX2_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SERPENT_AVX_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SHA1_SSSE3=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SHA256_SSSE3=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SHA512=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_SHA512_SSSE3=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TEA=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TGR192=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TWOFISH=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TWOFISH_X86_64=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_USER=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_USER_API_AEAD=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_USER_API_HASH=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_USER_API_RNG=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_VMAC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_WP512=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_XCBC=y
 | 
					 | 
				
			||||||
CONFIG_CRYPTO_XTS=y
 | 
					 | 
				
			||||||
CONFIG_CUSE=y
 | 
					 | 
				
			||||||
CONFIG_DEBUG_CREDENTIALS=y
 | 
					 | 
				
			||||||
# CONFIG_DEBUG_DEVRES is not set
 | 
					 | 
				
			||||||
CONFIG_DEBUG_INFO=y
 | 
					 | 
				
			||||||
CONFIG_DEBUG_INFO_SPLIT=y
 | 
					 | 
				
			||||||
CONFIG_DEBUG_LIST=y
 | 
					 | 
				
			||||||
CONFIG_DEBUG_NOTIFIERS=y
 | 
					 | 
				
			||||||
# CONFIG_DEBUG_STACKOVERFLOW is not set
 | 
					 | 
				
			||||||
# CONFIG_DEBUG_STACK_USAGE is not set
 | 
					 | 
				
			||||||
# CONFIG_DEFAULT_CFQ is not set
 | 
					 | 
				
			||||||
CONFIG_DEFAULT_DEADLINE=y
 | 
					 | 
				
			||||||
CONFIG_DEFAULT_HOSTNAME="(none)"
 | 
					 | 
				
			||||||
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
 | 
					 | 
				
			||||||
CONFIG_DEFAULT_SECURITY_DAC=y
 | 
					 | 
				
			||||||
CONFIG_DETECT_HUNG_TASK=y
 | 
					 | 
				
			||||||
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
 | 
					 | 
				
			||||||
# CONFIG_DEVTMPFS_MOUNT is not set
 | 
					 | 
				
			||||||
# CONFIG_DMADEVICES is not set
 | 
					 | 
				
			||||||
CONFIG_DMI_SYSFS=y
 | 
					 | 
				
			||||||
CONFIG_DM_CRYPT=y
 | 
					 | 
				
			||||||
# CONFIG_DM_MIRROR is not set
 | 
					 | 
				
			||||||
CONFIG_DM_SNAPSHOT=y
 | 
					 | 
				
			||||||
CONFIG_DM_THIN_PROVISIONING=y
 | 
					 | 
				
			||||||
# CONFIG_DM_ZERO is not set
 | 
					 | 
				
			||||||
# CONFIG_DRM is not set
 | 
					 | 
				
			||||||
CONFIG_DUMMY=y
 | 
					 | 
				
			||||||
CONFIG_DYNAMIC_FTRACE=y
 | 
					 | 
				
			||||||
# CONFIG_E100 is not set
 | 
					 | 
				
			||||||
# CONFIG_EDAC is not set
 | 
					 | 
				
			||||||
# CONFIG_EFIVAR_FS is not set
 | 
					 | 
				
			||||||
CONFIG_EFI_VARS_PSTORE=y
 | 
					 | 
				
			||||||
# CONFIG_ENABLE_MUST_CHECK is not set
 | 
					 | 
				
			||||||
CONFIG_ENA_ETHERNET=y
 | 
					 | 
				
			||||||
CONFIG_ENCRYPTED_KEYS=y
 | 
					 | 
				
			||||||
CONFIG_EXPERT=y
 | 
					 | 
				
			||||||
CONFIG_EXTRA_FIRMWARE=""
 | 
					 | 
				
			||||||
CONFIG_FANOTIFY=y
 | 
					 | 
				
			||||||
CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
 | 
					 | 
				
			||||||
# CONFIG_FB_EFI is not set
 | 
					 | 
				
			||||||
CONFIG_FB_HYPERV=y
 | 
					 | 
				
			||||||
# CONFIG_FB_MODE_HELPERS is not set
 | 
					 | 
				
			||||||
# CONFIG_FB_TILEBLITTING is not set
 | 
					 | 
				
			||||||
CONFIG_FB_VESA=y
 | 
					 | 
				
			||||||
# CONFIG_FDDI is not set
 | 
					 | 
				
			||||||
# CONFIG_FRAME_POINTER is not set
 | 
					 | 
				
			||||||
CONFIG_FRAME_WARN=1024
 | 
					 | 
				
			||||||
CONFIG_FSCACHE=y
 | 
					 | 
				
			||||||
CONFIG_FSCACHE_STATS=y
 | 
					 | 
				
			||||||
CONFIG_FS_ENCRYPTION=y
 | 
					 | 
				
			||||||
CONFIG_FTRACE_SYSCALLS=y
 | 
					 | 
				
			||||||
CONFIG_FUNCTION_GRAPH_TRACER=y
 | 
					 | 
				
			||||||
CONFIG_FUNCTION_PROFILER=y
 | 
					 | 
				
			||||||
CONFIG_FUNCTION_TRACER=y
 | 
					 | 
				
			||||||
CONFIG_FUSE_FS=y
 | 
					 | 
				
			||||||
CONFIG_FUSION=y
 | 
					 | 
				
			||||||
CONFIG_FUSION_MAX_SGE=128
 | 
					 | 
				
			||||||
CONFIG_FUSION_SPI=y
 | 
					 | 
				
			||||||
CONFIG_GACT_PROB=y
 | 
					 | 
				
			||||||
CONFIG_GENERIC_PHY=y
 | 
					 | 
				
			||||||
CONFIG_GENEVE=y
 | 
					 | 
				
			||||||
# CONFIG_HAMRADIO is not set
 | 
					 | 
				
			||||||
CONFIG_HANGCHECK_TIMER=y
 | 
					 | 
				
			||||||
CONFIG_HARDENED_USERCOPY=y
 | 
					 | 
				
			||||||
# CONFIG_HIBERNATION is not set
 | 
					 | 
				
			||||||
# CONFIG_HIDRAW is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_A4TECH is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_APPLE is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_BELKIN is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_CHERRY is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_CHICONY is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_CYPRESS is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_EZKEY is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_GYRATION is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_KENSINGTON is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_LOGITECH is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_MICROSOFT is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_MONTEREY is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_PANTHERLORD is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_PETALYNX is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_SAMSUNG is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_SUNPLUS is not set
 | 
					 | 
				
			||||||
# CONFIG_HID_TOPSEED is not set
 | 
					 | 
				
			||||||
CONFIG_HOTPLUG_PCI_PCIE=y
 | 
					 | 
				
			||||||
CONFIG_HOTPLUG_PCI_SHPC=y
 | 
					 | 
				
			||||||
CONFIG_HPET_MMAP=y
 | 
					 | 
				
			||||||
CONFIG_HPET_MMAP_DEFAULT=y
 | 
					 | 
				
			||||||
CONFIG_HVC_XEN=y
 | 
					 | 
				
			||||||
CONFIG_HVC_XEN_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_HW_RANDOM_AMD=y
 | 
					 | 
				
			||||||
CONFIG_HW_RANDOM_INTEL=y
 | 
					 | 
				
			||||||
CONFIG_HW_RANDOM_TIMERIOMEM=y
 | 
					 | 
				
			||||||
CONFIG_HW_RANDOM_VIRTIO=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV_BALLOON=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV_KEYBOARD=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV_NET=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV_STORAGE=y
 | 
					 | 
				
			||||||
CONFIG_HYPERV_UTILS=y
 | 
					 | 
				
			||||||
CONFIG_HZ_100=y
 | 
					 | 
				
			||||||
# CONFIG_HZ_1000 is not set
 | 
					 | 
				
			||||||
CONFIG_I2C_CHARDEV=y
 | 
					 | 
				
			||||||
# CONFIG_I2C_I801 is not set
 | 
					 | 
				
			||||||
CONFIG_I2C_MUX=y
 | 
					 | 
				
			||||||
CONFIG_IGB=y
 | 
					 | 
				
			||||||
CONFIG_IGBVF=y
 | 
					 | 
				
			||||||
CONFIG_IGB_HWMON=y
 | 
					 | 
				
			||||||
CONFIG_IKCONFIG=y
 | 
					 | 
				
			||||||
CONFIG_IKCONFIG_PROC=y
 | 
					 | 
				
			||||||
CONFIG_INET6_IPCOMP=y
 | 
					 | 
				
			||||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y
 | 
					 | 
				
			||||||
CONFIG_INET_AH=y
 | 
					 | 
				
			||||||
CONFIG_INET_DIAG=y
 | 
					 | 
				
			||||||
CONFIG_INET_ESP=y
 | 
					 | 
				
			||||||
CONFIG_INET_IPCOMP=y
 | 
					 | 
				
			||||||
CONFIG_INET_UDP_DIAG=y
 | 
					 | 
				
			||||||
CONFIG_INET_XFRM_MODE_BEET=y
 | 
					 | 
				
			||||||
CONFIG_INET_XFRM_MODE_TRANSPORT=y
 | 
					 | 
				
			||||||
CONFIG_INET_XFRM_MODE_TUNNEL=y
 | 
					 | 
				
			||||||
CONFIG_INITRAMFS_SOURCE=""
 | 
					 | 
				
			||||||
CONFIG_INPUT_ATLAS_BTNS=y
 | 
					 | 
				
			||||||
CONFIG_INPUT_JOYDEV=y
 | 
					 | 
				
			||||||
# CONFIG_INPUT_JOYSTICK is not set
 | 
					 | 
				
			||||||
# CONFIG_INPUT_MOUSE is not set
 | 
					 | 
				
			||||||
CONFIG_INPUT_MOUSEDEV_PSAUX=y
 | 
					 | 
				
			||||||
CONFIG_INPUT_PCSPKR=y
 | 
					 | 
				
			||||||
# CONFIG_INPUT_TABLET is not set
 | 
					 | 
				
			||||||
# CONFIG_INPUT_TOUCHSCREEN is not set
 | 
					 | 
				
			||||||
CONFIG_INPUT_UINPUT=y
 | 
					 | 
				
			||||||
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_INTEL_IDLE=y
 | 
					 | 
				
			||||||
CONFIG_INTEL_IPS=y
 | 
					 | 
				
			||||||
# CONFIG_IOMMU_SUPPORT is not set
 | 
					 | 
				
			||||||
CONFIG_IO_STRICT_DEVMEM=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_AH=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_EUI64=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_FRAG=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_HL=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_MH=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_OPTS=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_RPFILTER=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_MATCH_RT=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_NAT=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_RAW=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_SECURITY=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_TARGET_HL=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_TARGET_MASQUERADE=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_TARGET_NPT=y
 | 
					 | 
				
			||||||
CONFIG_IP6_NF_TARGET_SYNPROXY=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_GRE=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_ILA=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_MIP6=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_MULTIPLE_TABLES=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_ROUTER_PREF=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_SIT_6RD=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_SUBTREES=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_TUNNEL=y
 | 
					 | 
				
			||||||
CONFIG_IPV6_VTI=y
 | 
					 | 
				
			||||||
CONFIG_IPVLAN=y
 | 
					 | 
				
			||||||
CONFIG_IP_FIB_TRIE_STATS=y
 | 
					 | 
				
			||||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_ARPFILTER=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_ARPTABLES=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_ARP_MANGLE=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_MATCH_AH=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_MATCH_ECN=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_MATCH_RPFILTER=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_MATCH_TTL=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_NAT=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_RAW=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_SECURITY=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_CLUSTERIP=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_ECN=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_NETMAP=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_REDIRECT=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_SYNPROXY=y
 | 
					 | 
				
			||||||
CONFIG_IP_NF_TARGET_TTL=y
 | 
					 | 
				
			||||||
# CONFIG_IP_PNP_BOOTP is not set
 | 
					 | 
				
			||||||
# CONFIG_IP_PNP_RARP is not set
 | 
					 | 
				
			||||||
CONFIG_IP_SET=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_BITMAP_IP=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_BITMAP_IPMAC=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_BITMAP_PORT=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_IP=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_IPPORT=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_IPPORTIP=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_IPPORTNET=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_NET=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_NETIFACE=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_HASH_NETPORT=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_LIST_SET=y
 | 
					 | 
				
			||||||
CONFIG_IP_SET_MAX=256
 | 
					 | 
				
			||||||
CONFIG_IP_VS=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_DEBUG=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_DH=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_FO=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_FTP=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_LBLC=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_LBLCR=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_LC=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_NFCT=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_NQ=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_OVF=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_PROTO_AH=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_PROTO_ESP=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_PROTO_SCTP=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_PROTO_TCP=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_PROTO_UDP=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_RR=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_SED=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_SH=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_SH_TAB_BITS=8
 | 
					 | 
				
			||||||
CONFIG_IP_VS_TAB_BITS=12
 | 
					 | 
				
			||||||
CONFIG_IP_VS_WLC=y
 | 
					 | 
				
			||||||
CONFIG_IP_VS_WRR=y
 | 
					 | 
				
			||||||
CONFIG_IXGB=y
 | 
					 | 
				
			||||||
CONFIG_IXGBE=y
 | 
					 | 
				
			||||||
CONFIG_IXGBEVF=y
 | 
					 | 
				
			||||||
CONFIG_IXGBE_HWMON=y
 | 
					 | 
				
			||||||
# CONFIG_KARMA_PARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_KEY_DH_OPERATIONS=y
 | 
					 | 
				
			||||||
CONFIG_KSM=y
 | 
					 | 
				
			||||||
CONFIG_L2TP=y
 | 
					 | 
				
			||||||
CONFIG_LIBCRC32C=y
 | 
					 | 
				
			||||||
CONFIG_LOCALVERSION="-linuxkit"
 | 
					 | 
				
			||||||
CONFIG_LOCKUP_DETECTOR=y
 | 
					 | 
				
			||||||
# CONFIG_LOGO is not set
 | 
					 | 
				
			||||||
CONFIG_LOG_BUF_SHIFT=17
 | 
					 | 
				
			||||||
CONFIG_LPC_ICH=y
 | 
					 | 
				
			||||||
CONFIG_LPC_SCH=y
 | 
					 | 
				
			||||||
CONFIG_LWTUNNEL=y
 | 
					 | 
				
			||||||
# CONFIG_MACINTOSH_DRIVERS is not set
 | 
					 | 
				
			||||||
CONFIG_MACVLAN=y
 | 
					 | 
				
			||||||
CONFIG_MACVTAP=y
 | 
					 | 
				
			||||||
# CONFIG_MAC_PARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_MEMCG=y
 | 
					 | 
				
			||||||
CONFIG_MEMCG_SWAP=y
 | 
					 | 
				
			||||||
CONFIG_MEMCG_SWAP_ENABLED=y
 | 
					 | 
				
			||||||
CONFIG_MEMORY_HOTPLUG=y
 | 
					 | 
				
			||||||
CONFIG_MEMORY_HOTREMOVE=y
 | 
					 | 
				
			||||||
CONFIG_MFD_SM501=y
 | 
					 | 
				
			||||||
CONFIG_MFD_VX855=y
 | 
					 | 
				
			||||||
CONFIG_MFD_WL1273_CORE=y
 | 
					 | 
				
			||||||
# CONFIG_MINIX_SUBPARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_MMIOTRACE=y
 | 
					 | 
				
			||||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
 | 
					 | 
				
			||||||
CONFIG_MPLS=y
 | 
					 | 
				
			||||||
CONFIG_MXM_WMI=y
 | 
					 | 
				
			||||||
# CONFIG_NETCONSOLE is not set
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_ADVANCED=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_NETLINK_ACCT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_NETLINK_QUEUE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_CONNMARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_BPF=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CGROUP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_CPU=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_DCCP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_DSCP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_ECN=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_ESP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_HL=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_IPVS=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_L2TP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_NFACCT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_OSF=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_OWNER=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_RATEEST=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_REALM=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_RECENT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_SCTP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_MATCH_U32=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_NAT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_SET=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_CT=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_DSCP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_HL=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_HMARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_NETMAP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_RATEEST=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
 | 
					 | 
				
			||||||
# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_TEE=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
 | 
					 | 
				
			||||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
 | 
					 | 
				
			||||||
CONFIG_NETLINK_DIAG=y
 | 
					 | 
				
			||||||
CONFIG_NET_9P=y
 | 
					 | 
				
			||||||
CONFIG_NET_9P_VIRTIO=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_BPF=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_CSUM=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_GACT=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_IPT=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_MIRRED=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_NAT=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_PEDIT=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_POLICE=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_SIMP=y
 | 
					 | 
				
			||||||
CONFIG_NET_ACT_SKBEDIT=y
 | 
					 | 
				
			||||||
# CONFIG_NET_CADENCE is not set
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_BASIC=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_BPF=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_CGROUP=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_FLOW=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_FW=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_IND=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_MATCHALL=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_ROUTE4=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_RSVP=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_RSVP6=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_TCINDEX=y
 | 
					 | 
				
			||||||
CONFIG_NET_CLS_U32=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_CMP=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_IPSET=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_META=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_NBYTE=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_TEXT=y
 | 
					 | 
				
			||||||
CONFIG_NET_EMATCH_U32=y
 | 
					 | 
				
			||||||
CONFIG_NET_FOU=y
 | 
					 | 
				
			||||||
CONFIG_NET_FOU_IP_TUNNELS=y
 | 
					 | 
				
			||||||
CONFIG_NET_IPGRE=y
 | 
					 | 
				
			||||||
CONFIG_NET_IPGRE_BROADCAST=y
 | 
					 | 
				
			||||||
CONFIG_NET_IPGRE_DEMUX=y
 | 
					 | 
				
			||||||
CONFIG_NET_IPIP=y
 | 
					 | 
				
			||||||
CONFIG_NET_IPVTI=y
 | 
					 | 
				
			||||||
CONFIG_NET_KEY=y
 | 
					 | 
				
			||||||
CONFIG_NET_KEY_MIGRATE=y
 | 
					 | 
				
			||||||
CONFIG_NET_L3_MASTER_DEV=y
 | 
					 | 
				
			||||||
CONFIG_NET_MPLS_GSO=y
 | 
					 | 
				
			||||||
# CONFIG_NET_PACKET_ENGINE is not set
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_CBQ=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_CHOKE=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_DRR=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_DSMARK=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_GRED=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_HFSC=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_HTB=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_INGRESS=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_MQPRIO=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_MULTIQ=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_NETEM=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_PRIO=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_QFQ=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_RED=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_SFB=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_SFQ=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_TBF=y
 | 
					 | 
				
			||||||
CONFIG_NET_SCH_TEQL=y
 | 
					 | 
				
			||||||
CONFIG_NET_SWITCHDEV=y
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_3COM is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_ADAPTEC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_AGERE is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_ALTEON is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_AMD is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_ARC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_ATHEROS is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_BROADCOM is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_BROCADE is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_CAVIUM is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_CHELSIO is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_CISCO is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_DEC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_DLINK is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_EMULEX is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_EXAR is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_EZCHIP is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_HP is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_I825XX is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_MARVELL is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_MICREL is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_MYRI is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_NATSEMI is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_NVIDIA is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_OKI is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_QLOGIC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_QUALCOMM is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_RDC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_RENESAS is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_ROCKER is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SEEQ is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SILAN is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SIS is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SMSC is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_STMICRO is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_SUN is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_TEHUTI is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_TI is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_VIA is not set
 | 
					 | 
				
			||||||
# CONFIG_NET_VENDOR_WIZNET is not set
 | 
					 | 
				
			||||||
# CONFIG_NEW_LEDS is not set
 | 
					 | 
				
			||||||
CONFIG_NFSD=y
 | 
					 | 
				
			||||||
CONFIG_NFSD_V3=y
 | 
					 | 
				
			||||||
CONFIG_NFSD_V4=y
 | 
					 | 
				
			||||||
CONFIG_NFS_FSCACHE=y
 | 
					 | 
				
			||||||
# CONFIG_NFS_V2 is not set
 | 
					 | 
				
			||||||
# CONFIG_NFS_V3_ACL is not set
 | 
					 | 
				
			||||||
CONFIG_NFS_V4_1=y
 | 
					 | 
				
			||||||
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
 | 
					 | 
				
			||||||
CONFIG_NFS_V4_2=y
 | 
					 | 
				
			||||||
CONFIG_NFT_BRIDGE_META=y
 | 
					 | 
				
			||||||
CONFIG_NFT_BRIDGE_REJECT=y
 | 
					 | 
				
			||||||
CONFIG_NFT_CHAIN_NAT_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NFT_CHAIN_NAT_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NFT_CHAIN_ROUTE_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NFT_CHAIN_ROUTE_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NFT_COMPAT=y
 | 
					 | 
				
			||||||
CONFIG_NFT_COUNTER=y
 | 
					 | 
				
			||||||
CONFIG_NFT_CT=y
 | 
					 | 
				
			||||||
CONFIG_NFT_DUP_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NFT_DUP_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NFT_DUP_NETDEV=y
 | 
					 | 
				
			||||||
CONFIG_NFT_EXTHDR=y
 | 
					 | 
				
			||||||
CONFIG_NFT_FWD_NETDEV=y
 | 
					 | 
				
			||||||
CONFIG_NFT_HASH=y
 | 
					 | 
				
			||||||
CONFIG_NFT_LIMIT=y
 | 
					 | 
				
			||||||
CONFIG_NFT_LOG=y
 | 
					 | 
				
			||||||
CONFIG_NFT_MASQ=y
 | 
					 | 
				
			||||||
CONFIG_NFT_MASQ_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NFT_MASQ_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NFT_META=y
 | 
					 | 
				
			||||||
CONFIG_NFT_NAT=y
 | 
					 | 
				
			||||||
CONFIG_NFT_QUEUE=y
 | 
					 | 
				
			||||||
CONFIG_NFT_REDIR=y
 | 
					 | 
				
			||||||
CONFIG_NFT_REDIR_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NFT_REDIR_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NFT_REJECT=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_AMANDA=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_EVENTS=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_H323=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_MARK=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_PPTP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_SANE=y
 | 
					 | 
				
			||||||
# CONFIG_NF_CONNTRACK_SECMARK is not set
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_SNMP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_TFTP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_TIMEOUT=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_TIMESTAMP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CONNTRACK_ZONES=y
 | 
					 | 
				
			||||||
CONFIG_NF_CT_NETLINK_HELPER=y
 | 
					 | 
				
			||||||
CONFIG_NF_CT_NETLINK_TIMEOUT=y
 | 
					 | 
				
			||||||
CONFIG_NF_CT_PROTO_DCCP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CT_PROTO_SCTP=y
 | 
					 | 
				
			||||||
CONFIG_NF_CT_PROTO_UDPLITE=y
 | 
					 | 
				
			||||||
CONFIG_NF_DUP_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NF_DUP_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NF_DUP_NETDEV=y
 | 
					 | 
				
			||||||
CONFIG_NF_LOG_ARP=y
 | 
					 | 
				
			||||||
CONFIG_NF_LOG_BRIDGE=y
 | 
					 | 
				
			||||||
CONFIG_NF_LOG_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NF_LOG_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_MASQUERADE_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_MASQUERADE_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_REDIRECT=y
 | 
					 | 
				
			||||||
CONFIG_NF_NAT_SNMP_BASIC=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_ARP=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_BRIDGE=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_INET=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_IPV4=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_IPV6=y
 | 
					 | 
				
			||||||
CONFIG_NF_TABLES_NETDEV=y
 | 
					 | 
				
			||||||
CONFIG_NLMON=y
 | 
					 | 
				
			||||||
CONFIG_NLS_DEFAULT="iso8859-1"
 | 
					 | 
				
			||||||
CONFIG_NOZOMI=y
 | 
					 | 
				
			||||||
CONFIG_NTFS_FS=y
 | 
					 | 
				
			||||||
CONFIG_OPENVSWITCH=y
 | 
					 | 
				
			||||||
CONFIG_OPENVSWITCH_GENEVE=y
 | 
					 | 
				
			||||||
CONFIG_OPENVSWITCH_GRE=y
 | 
					 | 
				
			||||||
CONFIG_OPENVSWITCH_VXLAN=y
 | 
					 | 
				
			||||||
# CONFIG_OSF_PARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_OVERLAY_FS=y
 | 
					 | 
				
			||||||
CONFIG_PACKET_DIAG=y
 | 
					 | 
				
			||||||
CONFIG_PAGE_EXTENSION=y
 | 
					 | 
				
			||||||
CONFIG_PAGE_POISONING=y
 | 
					 | 
				
			||||||
CONFIG_PAGE_POISONING_NO_SANITY=y
 | 
					 | 
				
			||||||
CONFIG_PAGE_POISONING_ZERO=y
 | 
					 | 
				
			||||||
CONFIG_PANIC_ON_OOPS=y
 | 
					 | 
				
			||||||
# CONFIG_PATA_AMD is not set
 | 
					 | 
				
			||||||
# CONFIG_PATA_OLDPIIX is not set
 | 
					 | 
				
			||||||
# CONFIG_PATA_SCH is not set
 | 
					 | 
				
			||||||
CONFIG_PATA_SIS=y
 | 
					 | 
				
			||||||
# CONFIG_PCCARD is not set
 | 
					 | 
				
			||||||
# CONFIG_PCIEAER is not set
 | 
					 | 
				
			||||||
CONFIG_PCI_IOV=y
 | 
					 | 
				
			||||||
CONFIG_PCI_STUB=y
 | 
					 | 
				
			||||||
CONFIG_PERSISTENT_KEYRINGS=y
 | 
					 | 
				
			||||||
# CONFIG_PHYLIB is not set
 | 
					 | 
				
			||||||
CONFIG_PKCS7_MESSAGE_PARSER=y
 | 
					 | 
				
			||||||
# CONFIG_PM_DEBUG is not set
 | 
					 | 
				
			||||||
CONFIG_PM_DEVFREQ=y
 | 
					 | 
				
			||||||
# CONFIG_PNP_DEBUG_MESSAGES is not set
 | 
					 | 
				
			||||||
CONFIG_PPP=y
 | 
					 | 
				
			||||||
CONFIG_PPPOE=y
 | 
					 | 
				
			||||||
CONFIG_PPPOL2TP=y
 | 
					 | 
				
			||||||
CONFIG_PPP_ASYNC=y
 | 
					 | 
				
			||||||
CONFIG_PPP_BSDCOMP=y
 | 
					 | 
				
			||||||
CONFIG_PPP_DEFLATE=y
 | 
					 | 
				
			||||||
CONFIG_PPP_FILTER=y
 | 
					 | 
				
			||||||
CONFIG_PPP_MPPE=y
 | 
					 | 
				
			||||||
CONFIG_PPP_MULTILINK=y
 | 
					 | 
				
			||||||
CONFIG_PPP_SYNC_TTY=y
 | 
					 | 
				
			||||||
CONFIG_PPTP=y
 | 
					 | 
				
			||||||
CONFIG_PRINT_QUOTA_WARNING=y
 | 
					 | 
				
			||||||
CONFIG_PROC_CHILDREN=y
 | 
					 | 
				
			||||||
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
 | 
					 | 
				
			||||||
CONFIG_PSTORE=y
 | 
					 | 
				
			||||||
CONFIG_PSTORE_ZLIB_COMPRESS=y
 | 
					 | 
				
			||||||
# CONFIG_QFMT_V2 is not set
 | 
					 | 
				
			||||||
# CONFIG_RAS is not set
 | 
					 | 
				
			||||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
 | 
					 | 
				
			||||||
# CONFIG_RD_BZIP2 is not set
 | 
					 | 
				
			||||||
# CONFIG_RD_LZ4 is not set
 | 
					 | 
				
			||||||
# CONFIG_RD_LZMA is not set
 | 
					 | 
				
			||||||
# CONFIG_RD_LZO is not set
 | 
					 | 
				
			||||||
# CONFIG_RD_XZ is not set
 | 
					 | 
				
			||||||
CONFIG_RESET_CONTROLLER=y
 | 
					 | 
				
			||||||
# CONFIG_RFKILL is not set
 | 
					 | 
				
			||||||
# CONFIG_ROOT_NFS is not set
 | 
					 | 
				
			||||||
CONFIG_RPCSEC_GSS_KRB5=y
 | 
					 | 
				
			||||||
CONFIG_RTC_HCTOSYS=y
 | 
					 | 
				
			||||||
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
 | 
					 | 
				
			||||||
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
 | 
					 | 
				
			||||||
CONFIG_RT_GROUP_SCHED=y
 | 
					 | 
				
			||||||
CONFIG_SATA_MV=y
 | 
					 | 
				
			||||||
CONFIG_SATA_NV=y
 | 
					 | 
				
			||||||
# CONFIG_SATA_PMP is not set
 | 
					 | 
				
			||||||
CONFIG_SATA_PROMISE=y
 | 
					 | 
				
			||||||
CONFIG_SATA_SIL=y
 | 
					 | 
				
			||||||
CONFIG_SATA_SIS=y
 | 
					 | 
				
			||||||
CONFIG_SATA_SVW=y
 | 
					 | 
				
			||||||
CONFIG_SATA_ULI=y
 | 
					 | 
				
			||||||
CONFIG_SATA_VIA=y
 | 
					 | 
				
			||||||
CONFIG_SATA_VITESSE=y
 | 
					 | 
				
			||||||
# CONFIG_SCHEDSTATS is not set
 | 
					 | 
				
			||||||
CONFIG_SCHED_AUTOGROUP=y
 | 
					 | 
				
			||||||
CONFIG_SCHED_DEBUG=y
 | 
					 | 
				
			||||||
# CONFIG_SCSI_CONSTANTS is not set
 | 
					 | 
				
			||||||
CONFIG_SCSI_LOWLEVEL=y
 | 
					 | 
				
			||||||
CONFIG_SCSI_VIRTIO=y
 | 
					 | 
				
			||||||
CONFIG_SECURITYFS=y
 | 
					 | 
				
			||||||
CONFIG_SECURITY_DMESG_RESTRICT=y
 | 
					 | 
				
			||||||
CONFIG_SECURITY_NETWORK_XFRM=y
 | 
					 | 
				
			||||||
CONFIG_SECURITY_PATH=y
 | 
					 | 
				
			||||||
# CONFIG_SECURITY_SELINUX is not set
 | 
					 | 
				
			||||||
CONFIG_SECURITY_YAMA=y
 | 
					 | 
				
			||||||
# CONFIG_SERIAL_8250_EXTENDED is not set
 | 
					 | 
				
			||||||
# CONFIG_SERIAL_8250_MID is not set
 | 
					 | 
				
			||||||
# CONFIG_SERIAL_NONSTANDARD is not set
 | 
					 | 
				
			||||||
CONFIG_SERIO_PCIPS2=y
 | 
					 | 
				
			||||||
CONFIG_SERIO_RAW=y
 | 
					 | 
				
			||||||
# CONFIG_SGI_PARTITION is not set
 | 
					 | 
				
			||||||
CONFIG_SLAB=y
 | 
					 | 
				
			||||||
CONFIG_SLAB_FREELIST_RANDOM=y
 | 
					 | 
				
			||||||
# CONFIG_SLUB is not set
 | 
					 | 
				
			||||||
# CONFIG_SOLARIS_X86_PARTITION is not set
 | 
					 | 
				
			||||||
# CONFIG_SOUND is not set
 | 
					 | 
				
			||||||
CONFIG_STACK_TRACER=y
 | 
					 | 
				
			||||||
CONFIG_STRICT_DEVMEM=y
 | 
					 | 
				
			||||||
# CONFIG_SUN_PARTITION is not set
 | 
					 | 
				
			||||||
# CONFIG_SUSPEND is not set
 | 
					 | 
				
			||||||
# CONFIG_TASK_XACCT is not set
 | 
					 | 
				
			||||||
# CONFIG_TCP_CONG_ADVANCED is not set
 | 
					 | 
				
			||||||
# CONFIG_THERMAL_GOV_USER_SPACE is not set
 | 
					 | 
				
			||||||
# CONFIG_THERMAL_HWMON is not set
 | 
					 | 
				
			||||||
# CONFIG_THERMAL_WRITABLE_TRIPS is not set
 | 
					 | 
				
			||||||
# CONFIG_TMPFS_POSIX_ACL is not set
 | 
					 | 
				
			||||||
CONFIG_TRANSPARENT_HUGEPAGE=y
 | 
					 | 
				
			||||||
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
 | 
					 | 
				
			||||||
CONFIG_TUN=y
 | 
					 | 
				
			||||||
CONFIG_UBSAN=y
 | 
					 | 
				
			||||||
CONFIG_UDF_FS=y
 | 
					 | 
				
			||||||
CONFIG_UEVENT_HELPER_PATH=""
 | 
					 | 
				
			||||||
# CONFIG_UNIXWARE_DISKLABEL is not set
 | 
					 | 
				
			||||||
CONFIG_UNIX_DIAG=y
 | 
					 | 
				
			||||||
# CONFIG_USB_SUPPORT is not set
 | 
					 | 
				
			||||||
# CONFIG_USELIB is not set
 | 
					 | 
				
			||||||
CONFIG_USER_NS=y
 | 
					 | 
				
			||||||
CONFIG_VETH=y
 | 
					 | 
				
			||||||
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
 | 
					 | 
				
			||||||
# CONFIG_VGA_ARB is not set
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_BALLOON=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_BLK=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_CONSOLE=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_INPUT=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_MMIO=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_NET=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_PCI=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_PCI_LEGACY=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_VSOCKETS=y
 | 
					 | 
				
			||||||
CONFIG_VIRTIO_VSOCKETS_COMMON=y
 | 
					 | 
				
			||||||
CONFIG_VLAN_8021Q=y
 | 
					 | 
				
			||||||
CONFIG_VMWARE_PVSCSI=y
 | 
					 | 
				
			||||||
CONFIG_VMXNET3=y
 | 
					 | 
				
			||||||
CONFIG_VSOCKETS=y
 | 
					 | 
				
			||||||
CONFIG_VXLAN=y
 | 
					 | 
				
			||||||
# CONFIG_WATCHDOG is not set
 | 
					 | 
				
			||||||
# CONFIG_WIRELESS is not set
 | 
					 | 
				
			||||||
# CONFIG_WLAN is not set
 | 
					 | 
				
			||||||
CONFIG_WQ_WATCHDOG=y
 | 
					 | 
				
			||||||
CONFIG_X509_CERTIFICATE_PARSER=y
 | 
					 | 
				
			||||||
CONFIG_X86_P4_CLOCKMOD=y
 | 
					 | 
				
			||||||
CONFIG_X86_PCC_CPUFREQ=y
 | 
					 | 
				
			||||||
CONFIG_X86_POWERNOW_K8=y
 | 
					 | 
				
			||||||
CONFIG_XENFS=y
 | 
					 | 
				
			||||||
CONFIG_XEN_ACPI_PROCESSOR=y
 | 
					 | 
				
			||||||
CONFIG_XEN_BALLOON=y
 | 
					 | 
				
			||||||
CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y
 | 
					 | 
				
			||||||
CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT=512
 | 
					 | 
				
			||||||
CONFIG_XEN_BLKDEV_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_XEN_COMPAT_XENFS=y
 | 
					 | 
				
			||||||
CONFIG_XEN_DEV_EVTCHN=y
 | 
					 | 
				
			||||||
CONFIG_XEN_FBDEV_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_XEN_GNTDEV=y
 | 
					 | 
				
			||||||
CONFIG_XEN_GRANT_DEV_ALLOC=y
 | 
					 | 
				
			||||||
CONFIG_XEN_NETDEV_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_XEN_PCIDEV_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_XEN_SCRUB_PAGES=y
 | 
					 | 
				
			||||||
CONFIG_XEN_SCSI_FRONTEND=y
 | 
					 | 
				
			||||||
CONFIG_XEN_SYS_HYPERVISOR=y
 | 
					 | 
				
			||||||
CONFIG_XFRM_MIGRATE=y
 | 
					 | 
				
			||||||
CONFIG_XFRM_STATISTICS=y
 | 
					 | 
				
			||||||
CONFIG_XFRM_SUB_POLICY=y
 | 
					 | 
				
			||||||
CONFIG_XFS_FS=y
 | 
					 | 
				
			||||||
CONFIG_XFS_POSIX_ACL=y
 | 
					 | 
				
			||||||
CONFIG_XFS_QUOTA=y
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 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
 | 
					 | 
				
			||||||
# CONFIG_PANIC_ON_OOPS is not set
 | 
					 | 
				
			||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
# CONFIG_CALGARY_IOMMU is not set
 | 
					 | 
				
			||||||
# CONFIG_CC_STACKPROTECTOR_NONE is not set
 | 
					 | 
				
			||||||
CONFIG_CC_STACKPROTECTOR_STRONG=y
 | 
					 | 
				
			||||||
# CONFIG_CRASH_DUMP is not set
 | 
					 | 
				
			||||||
# CONFIG_DEBUG_BOOT_PARAMS is not set
 | 
					 | 
				
			||||||
# CONFIG_EARLY_PRINTK_DBGP is not set
 | 
					 | 
				
			||||||
CONFIG_EFI_STUB=y
 | 
					 | 
				
			||||||
CONFIG_HYPERVISOR_GUEST=y
 | 
					 | 
				
			||||||
# CONFIG_KEXEC is not set
 | 
					 | 
				
			||||||
CONFIG_KVM_GUEST=y
 | 
					 | 
				
			||||||
# CONFIG_LEGACY_VSYSCALL_EMULATE is not set
 | 
					 | 
				
			||||||
CONFIG_LEGACY_VSYSCALL_NONE=y
 | 
					 | 
				
			||||||
# CONFIG_MODIFY_LDT_SYSCALL is not set
 | 
					 | 
				
			||||||
CONFIG_MTRR_SANITIZER=y
 | 
					 | 
				
			||||||
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
 | 
					 | 
				
			||||||
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
 | 
					 | 
				
			||||||
CONFIG_NR_CPUS=128
 | 
					 | 
				
			||||||
# CONFIG_NUMA is not set
 | 
					 | 
				
			||||||
CONFIG_OPROFILE=y
 | 
					 | 
				
			||||||
CONFIG_PARAVIRT=y
 | 
					 | 
				
			||||||
CONFIG_PARAVIRT_SPINLOCKS=y
 | 
					 | 
				
			||||||
CONFIG_PHYSICAL_ALIGN=0x1000000
 | 
					 | 
				
			||||||
CONFIG_RANDOMIZE_BASE=y
 | 
					 | 
				
			||||||
CONFIG_RANDOMIZE_MEMORY=y
 | 
					 | 
				
			||||||
CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0xa
 | 
					 | 
				
			||||||
# CONFIG_SCHED_SMT is not set
 | 
					 | 
				
			||||||
# CONFIG_VIRTUALIZATION is not set
 | 
					 | 
				
			||||||
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
 | 
					 | 
				
			||||||
# CONFIG_X86_EXTENDED_PLATFORM is not set
 | 
					 | 
				
			||||||
# CONFIG_X86_MCE is not set
 | 
					 | 
				
			||||||
CONFIG_XEN=y
 | 
					 | 
				
			||||||
CONFIG_XEN_512GB=y
 | 
					 | 
				
			||||||
CONFIG_XEN_PVH=y
 | 
					 | 
				
			||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
CONFIG_DEBUG_SET_MODULE_RONX=y
 | 
					 | 
				
			||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
CONFIG_DEBUG_SET_MODULE_RONX=y
 | 
					 | 
				
			||||||
@@ -1,64 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cd /linux && make defconfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function merge_config()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    config=$1
 | 
					 | 
				
			||||||
    if [ ! -f "$config" ]; then
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # A slightly more intelligent merge algorithm: rather than just catting
 | 
					 | 
				
			||||||
    # files together (and getting random results), let's explicitly delete the
 | 
					 | 
				
			||||||
    # old setting, and then insert our new one.
 | 
					 | 
				
			||||||
    while read line; do
 | 
					 | 
				
			||||||
        if echo ${line} | grep "is not set" >/dev/null; then
 | 
					 | 
				
			||||||
            cfg=$(echo ${line/ is not set/} | cut -c3-)
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            cfg=$(echo ${line} | cut -f1 -d=)
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        sed -i -e "/${cfg} is not set/d" -e "/${cfg}=/d" /linux/.config
 | 
					 | 
				
			||||||
        echo ${line} >> /linux/.config
 | 
					 | 
				
			||||||
    done < "$config"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cd /linux && make defconfig && make oldconfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for config in "$@"; do
 | 
					 | 
				
			||||||
  merge_config "$config"
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cd /linux && make oldconfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Let's make sure things are the way we want, i.e. every option we explicitly
 | 
					 | 
				
			||||||
# set is set the same way in the resulting config.
 | 
					 | 
				
			||||||
function check_config()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if [ ! -f "$1" ]; then return; fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while read line; do
 | 
					 | 
				
			||||||
      # CONFIG_PANIC_ON_OOPS is special, and set both ways, depending on
 | 
					 | 
				
			||||||
      # whether DEBUG is set or not.
 | 
					 | 
				
			||||||
      if [ "$line" == *"CONFIG_PANIC_ON_OOPS"* ]; then continue; fi
 | 
					 | 
				
			||||||
      value="$(grep "^${line}$" /linux/.config || true)"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      # It's okay to for the merging script to have simply not listed values we
 | 
					 | 
				
			||||||
      # require to be unset.
 | 
					 | 
				
			||||||
      if echo "${line}" | grep "is not set" >/dev/null && [ "$value" = "" ]; then
 | 
					 | 
				
			||||||
          continue
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
      if [ "${value}" = "${line}" ]; then
 | 
					 | 
				
			||||||
          continue
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      echo "$line set incorrectly" && false
 | 
					 | 
				
			||||||
    done < $1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for config in "$@"; do
 | 
					 | 
				
			||||||
  check_config "$config"
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,492 +0,0 @@
 | 
				
			|||||||
From d9aa9429204658ccfc3563b99ea555207d3ce455 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/6] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,118 +0,0 @@
 | 
				
			|||||||
From 3ed1bbf668019a7fdc4ec8e2f398552db9bd6b7e 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/6] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
From 6a0b3a8e2da9cb321723fbba5bb0c1783f99e985 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/6] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,59 +0,0 @@
 | 
				
			|||||||
From ddfa35f8ed42cd04e98144489a08ab9e56106529 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/6] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,177 +0,0 @@
 | 
				
			|||||||
From 939735a0c5e6a26d202fff4a636dab6c0e4f0b5e 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/6] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,369 +0,0 @@
 | 
				
			|||||||
From a1b252ef7f38e04a2f5c8218adab6c1689fc3418 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: stephen hemminger <stephen@networkplumber.org>
 | 
					 | 
				
			||||||
Date: Mon, 27 Feb 2017 10:26:48 -0800
 | 
					 | 
				
			||||||
Subject: [PATCH 1/9] vmbus: introduce in-place packet iterator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is mostly just a refactoring of previous functions
 | 
					 | 
				
			||||||
(get_pkt_next_raw, put_pkt_raw and commit_rd_index) to make it easier
 | 
					 | 
				
			||||||
to use for other drivers and NAPI.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
					 | 
				
			||||||
(cherry picked from commit f3dd3f4797652c311df9c074436d420f1ad3566e)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/ring_buffer.c    | 94 +++++++++++++++++++++++++++++++++++++++++++-
 | 
					 | 
				
			||||||
 drivers/net/hyperv/netvsc.c | 34 +++++-----------
 | 
					 | 
				
			||||||
 include/linux/hyperv.h      | 96 ++++++++++++++-------------------------------
 | 
					 | 
				
			||||||
 3 files changed, 133 insertions(+), 91 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
 | 
					 | 
				
			||||||
index 87799e81af97..c3f1a9e33cef 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/ring_buffer.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/ring_buffer.c
 | 
					 | 
				
			||||||
@@ -32,6 +32,8 @@
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #include "hyperv_vmbus.h"
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+#define VMBUS_PKT_TRAILER	8
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 /*
 | 
					 | 
				
			||||||
  * When we write to the ring buffer, check if the host needs to
 | 
					 | 
				
			||||||
  * be signaled. Here is the details of this protocol:
 | 
					 | 
				
			||||||
@@ -336,6 +338,12 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
 	return 0;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+static inline void
 | 
					 | 
				
			||||||
+init_cached_read_index(struct hv_ring_buffer_info *rbi)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	rbi->cached_read_index = rbi->ring_buffer->read_index;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 int hv_ringbuffer_read(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
 		       void *buffer, u32 buflen, u32 *buffer_actual_len,
 | 
					 | 
				
			||||||
 		       u64 *requestid, bool raw)
 | 
					 | 
				
			||||||
@@ -366,7 +374,8 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
 		return ret;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	init_cached_read_index(channel);
 | 
					 | 
				
			||||||
+	init_cached_read_index(inring_info);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	next_read_location = hv_get_next_read_location(inring_info);
 | 
					 | 
				
			||||||
 	next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc,
 | 
					 | 
				
			||||||
 						    sizeof(desc),
 | 
					 | 
				
			||||||
@@ -410,3 +419,86 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	return ret;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Determine number of bytes available in ring buffer after
 | 
					 | 
				
			||||||
+ * the current iterator (priv_read_index) location.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * This is similar to hv_get_bytes_to_read but with private
 | 
					 | 
				
			||||||
+ * read index instead.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	u32 priv_read_loc = rbi->priv_read_index;
 | 
					 | 
				
			||||||
+	u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (write_loc >= priv_read_loc)
 | 
					 | 
				
			||||||
+		return write_loc - priv_read_loc;
 | 
					 | 
				
			||||||
+	else
 | 
					 | 
				
			||||||
+		return (rbi->ring_datasize - priv_read_loc) + write_loc;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Get first vmbus packet from ring buffer after read_index
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * If ring buffer is empty, returns NULL and no other action needed.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hv_ring_buffer_info *rbi = &channel->inbound;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* set state for later hv_signal_on_read() */
 | 
					 | 
				
			||||||
+	init_cached_read_index(rbi);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
 | 
					 | 
				
			||||||
+		return NULL;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+EXPORT_SYMBOL_GPL(hv_pkt_iter_first);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Get next vmbus packet from ring buffer.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Advances the current location (priv_read_index) and checks for more
 | 
					 | 
				
			||||||
+ * data. If the end of the ring buffer is reached, then return NULL.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+struct vmpacket_descriptor *
 | 
					 | 
				
			||||||
+__hv_pkt_iter_next(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
+		   const struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hv_ring_buffer_info *rbi = &channel->inbound;
 | 
					 | 
				
			||||||
+	u32 packetlen = desc->len8 << 3;
 | 
					 | 
				
			||||||
+	u32 dsize = rbi->ring_datasize;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* bump offset to next potential packet */
 | 
					 | 
				
			||||||
+	rbi->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
 | 
					 | 
				
			||||||
+	if (rbi->priv_read_index >= dsize)
 | 
					 | 
				
			||||||
+		rbi->priv_read_index -= dsize;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* more data? */
 | 
					 | 
				
			||||||
+	if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
 | 
					 | 
				
			||||||
+		return NULL;
 | 
					 | 
				
			||||||
+	else
 | 
					 | 
				
			||||||
+		return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Update host ring buffer after iterating over packets.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+void hv_pkt_iter_close(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hv_ring_buffer_info *rbi = &channel->inbound;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/*
 | 
					 | 
				
			||||||
+	 * Make sure all reads are done before we update the read index since
 | 
					 | 
				
			||||||
+	 * the writer may start writing to the read area once the read index
 | 
					 | 
				
			||||||
+	 * is updated.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	virt_rmb();
 | 
					 | 
				
			||||||
+	rbi->ring_buffer->read_index = rbi->priv_read_index;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hv_signal_on_read(channel);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
 | 
					 | 
				
			||||||
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
 | 
					 | 
				
			||||||
index 15ef713d96c0..ab9fe48ec133 100644
 | 
					 | 
				
			||||||
--- a/drivers/net/hyperv/netvsc.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/hyperv/netvsc.c
 | 
					 | 
				
			||||||
@@ -646,14 +646,11 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
 | 
					 | 
				
			||||||
 static void netvsc_send_completion(struct netvsc_device *net_device,
 | 
					 | 
				
			||||||
 				   struct vmbus_channel *incoming_channel,
 | 
					 | 
				
			||||||
 				   struct hv_device *device,
 | 
					 | 
				
			||||||
-				   struct vmpacket_descriptor *packet)
 | 
					 | 
				
			||||||
+				   const struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct nvsp_message *nvsp_packet;
 | 
					 | 
				
			||||||
+	struct nvsp_message *nvsp_packet = hv_pkt_data(desc);
 | 
					 | 
				
			||||||
 	struct net_device *ndev = hv_get_drvdata(device);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
 | 
					 | 
				
			||||||
-					      (packet->offset8 << 3));
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	switch (nvsp_packet->hdr.msg_type) {
 | 
					 | 
				
			||||||
 	case NVSP_MSG_TYPE_INIT_COMPLETE:
 | 
					 | 
				
			||||||
 	case NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE:
 | 
					 | 
				
			||||||
@@ -667,7 +664,7 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	case NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE:
 | 
					 | 
				
			||||||
 		netvsc_send_tx_complete(net_device, incoming_channel,
 | 
					 | 
				
			||||||
-					device, packet);
 | 
					 | 
				
			||||||
+					device, desc);
 | 
					 | 
				
			||||||
 		break;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	default:
 | 
					 | 
				
			||||||
@@ -1070,9 +1067,11 @@ static void netvsc_receive(struct net_device *ndev,
 | 
					 | 
				
			||||||
 		   struct net_device_context *net_device_ctx,
 | 
					 | 
				
			||||||
 		   struct hv_device *device,
 | 
					 | 
				
			||||||
 		   struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
-		   struct vmtransfer_page_packet_header *vmxferpage_packet,
 | 
					 | 
				
			||||||
+		   const struct vmpacket_descriptor *desc,
 | 
					 | 
				
			||||||
 		   struct nvsp_message *nvsp)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
+	const struct vmtransfer_page_packet_header *vmxferpage_packet
 | 
					 | 
				
			||||||
+		= container_of(desc, const struct vmtransfer_page_packet_header, d);
 | 
					 | 
				
			||||||
 	char *recv_buf = net_device->recv_buf;
 | 
					 | 
				
			||||||
 	u32 status = NVSP_STAT_SUCCESS;
 | 
					 | 
				
			||||||
 	int i;
 | 
					 | 
				
			||||||
@@ -1180,12 +1179,10 @@ static void netvsc_process_raw_pkt(struct hv_device *device,
 | 
					 | 
				
			||||||
 				   struct netvsc_device *net_device,
 | 
					 | 
				
			||||||
 				   struct net_device *ndev,
 | 
					 | 
				
			||||||
 				   u64 request_id,
 | 
					 | 
				
			||||||
-				   struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
+				   const struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
 	struct net_device_context *net_device_ctx = netdev_priv(ndev);
 | 
					 | 
				
			||||||
-	struct nvsp_message *nvmsg
 | 
					 | 
				
			||||||
-		= (struct nvsp_message *)((unsigned long)desc
 | 
					 | 
				
			||||||
-					  + (desc->offset8 << 3));
 | 
					 | 
				
			||||||
+	struct nvsp_message *nvmsg = hv_pkt_data(desc);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	switch (desc->type) {
 | 
					 | 
				
			||||||
 	case VM_PKT_COMP:
 | 
					 | 
				
			||||||
@@ -1194,9 +1191,7 @@ static void netvsc_process_raw_pkt(struct hv_device *device,
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	case VM_PKT_DATA_USING_XFER_PAGES:
 | 
					 | 
				
			||||||
 		netvsc_receive(ndev, net_device, net_device_ctx,
 | 
					 | 
				
			||||||
-			       device, channel,
 | 
					 | 
				
			||||||
-			       (struct vmtransfer_page_packet_header *)desc,
 | 
					 | 
				
			||||||
-			       nvmsg);
 | 
					 | 
				
			||||||
+			       device, channel, desc, nvmsg);
 | 
					 | 
				
			||||||
 		break;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	case VM_PKT_DATA_INBAND:
 | 
					 | 
				
			||||||
@@ -1218,7 +1213,6 @@ void netvsc_channel_cb(void *context)
 | 
					 | 
				
			||||||
 	struct netvsc_device *net_device;
 | 
					 | 
				
			||||||
 	struct vmpacket_descriptor *desc;
 | 
					 | 
				
			||||||
 	struct net_device *ndev;
 | 
					 | 
				
			||||||
-	bool need_to_commit = false;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	if (channel->primary_channel != NULL)
 | 
					 | 
				
			||||||
 		device = channel->primary_channel->device_obj;
 | 
					 | 
				
			||||||
@@ -1237,20 +1231,12 @@ void netvsc_channel_cb(void *context)
 | 
					 | 
				
			||||||
 		     netvsc_channel_idle(net_device, q_idx)))
 | 
					 | 
				
			||||||
 		return;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	/* commit_rd_index() -> hv_signal_on_read() needs this. */
 | 
					 | 
				
			||||||
-	init_cached_read_index(channel);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	while ((desc = get_next_pkt_raw(channel)) != NULL) {
 | 
					 | 
				
			||||||
+	foreach_vmbus_pkt(desc, channel) {
 | 
					 | 
				
			||||||
 		netvsc_process_raw_pkt(device, channel, net_device,
 | 
					 | 
				
			||||||
 				       ndev, desc->trans_id, desc);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-		put_pkt_raw(channel, desc);
 | 
					 | 
				
			||||||
-		need_to_commit = true;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	if (need_to_commit)
 | 
					 | 
				
			||||||
-		commit_rd_index(channel);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	netvsc_chk_recv_comp(net_device, channel, q_idx);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
index 970771a5f739..0c170a3f0d8b 100644
 | 
					 | 
				
			||||||
--- a/include/linux/hyperv.h
 | 
					 | 
				
			||||||
+++ b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
@@ -1508,14 +1508,6 @@ static inline  void hv_signal_on_read(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
 	return;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-static inline void
 | 
					 | 
				
			||||||
-init_cached_read_index(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
-{
 | 
					 | 
				
			||||||
-	struct hv_ring_buffer_info *rbi = &channel->inbound;
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	rbi->cached_read_index = rbi->ring_buffer->read_index;
 | 
					 | 
				
			||||||
-}
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 /*
 | 
					 | 
				
			||||||
  * Mask off host interrupt callback notifications
 | 
					 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
@@ -1549,76 +1541,48 @@ static inline u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 | 
					 | 
				
			||||||
 /*
 | 
					 | 
				
			||||||
  * An API to support in-place processing of incoming VMBUS packets.
 | 
					 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
-#define VMBUS_PKT_TRAILER	8
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-static inline struct vmpacket_descriptor *
 | 
					 | 
				
			||||||
-get_next_pkt_raw(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
+/* Get data payload associated with descriptor */
 | 
					 | 
				
			||||||
+static inline void *hv_pkt_data(const struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct hv_ring_buffer_info *ring_info = &channel->inbound;
 | 
					 | 
				
			||||||
-	u32 priv_read_loc = ring_info->priv_read_index;
 | 
					 | 
				
			||||||
-	void *ring_buffer = hv_get_ring_buffer(ring_info);
 | 
					 | 
				
			||||||
-	u32 dsize = ring_info->ring_datasize;
 | 
					 | 
				
			||||||
-	/*
 | 
					 | 
				
			||||||
-	 * delta is the difference between what is available to read and
 | 
					 | 
				
			||||||
-	 * what was already consumed in place. We commit read index after
 | 
					 | 
				
			||||||
-	 * the whole batch is processed.
 | 
					 | 
				
			||||||
-	 */
 | 
					 | 
				
			||||||
-	u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ?
 | 
					 | 
				
			||||||
-		priv_read_loc - ring_info->ring_buffer->read_index :
 | 
					 | 
				
			||||||
-		(dsize - ring_info->ring_buffer->read_index) + priv_read_loc;
 | 
					 | 
				
			||||||
-	u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
 | 
					 | 
				
			||||||
-		return NULL;
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	return ring_buffer + priv_read_loc;
 | 
					 | 
				
			||||||
+	return (void *)((unsigned long)desc + (desc->offset8 << 3));
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-/*
 | 
					 | 
				
			||||||
- * A helper function to step through packets "in-place"
 | 
					 | 
				
			||||||
- * This API is to be called after each successful call
 | 
					 | 
				
			||||||
- * get_next_pkt_raw().
 | 
					 | 
				
			||||||
- */
 | 
					 | 
				
			||||||
-static inline void put_pkt_raw(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
-				struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
+/* Get data size associated with descriptor */
 | 
					 | 
				
			||||||
+static inline u32 hv_pkt_datalen(const struct vmpacket_descriptor *desc)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct hv_ring_buffer_info *ring_info = &channel->inbound;
 | 
					 | 
				
			||||||
-	u32 packetlen = desc->len8 << 3;
 | 
					 | 
				
			||||||
-	u32 dsize = ring_info->ring_datasize;
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	/*
 | 
					 | 
				
			||||||
-	 * Include the packet trailer.
 | 
					 | 
				
			||||||
-	 */
 | 
					 | 
				
			||||||
-	ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
 | 
					 | 
				
			||||||
-	ring_info->priv_read_index %= dsize;
 | 
					 | 
				
			||||||
+	return (desc->len8 << 3) - (desc->offset8 << 3);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+struct vmpacket_descriptor *
 | 
					 | 
				
			||||||
+hv_pkt_iter_first(struct vmbus_channel *channel);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+struct vmpacket_descriptor *
 | 
					 | 
				
			||||||
+__hv_pkt_iter_next(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
+		   const struct vmpacket_descriptor *pkt);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+void hv_pkt_iter_close(struct vmbus_channel *channel);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 /*
 | 
					 | 
				
			||||||
- * This call commits the read index and potentially signals the host.
 | 
					 | 
				
			||||||
- * Here is the pattern for using the "in-place" consumption APIs:
 | 
					 | 
				
			||||||
- *
 | 
					 | 
				
			||||||
- * init_cached_read_index();
 | 
					 | 
				
			||||||
- *
 | 
					 | 
				
			||||||
- * while (get_next_pkt_raw() {
 | 
					 | 
				
			||||||
- *	process the packet "in-place";
 | 
					 | 
				
			||||||
- *	put_pkt_raw();
 | 
					 | 
				
			||||||
- * }
 | 
					 | 
				
			||||||
- * if (packets processed in place)
 | 
					 | 
				
			||||||
- *	commit_rd_index();
 | 
					 | 
				
			||||||
+ * Get next packet descriptor from iterator
 | 
					 | 
				
			||||||
+ * If at end of list, return NULL and update host.
 | 
					 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
-static inline void commit_rd_index(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
+static inline struct vmpacket_descriptor *
 | 
					 | 
				
			||||||
+hv_pkt_iter_next(struct vmbus_channel *channel,
 | 
					 | 
				
			||||||
+		 const struct vmpacket_descriptor *pkt)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct hv_ring_buffer_info *ring_info = &channel->inbound;
 | 
					 | 
				
			||||||
-	/*
 | 
					 | 
				
			||||||
-	 * Make sure all reads are done before we update the read index since
 | 
					 | 
				
			||||||
-	 * the writer may start writing to the read area once the read index
 | 
					 | 
				
			||||||
-	 * is updated.
 | 
					 | 
				
			||||||
-	 */
 | 
					 | 
				
			||||||
-	virt_rmb();
 | 
					 | 
				
			||||||
-	ring_info->ring_buffer->read_index = ring_info->priv_read_index;
 | 
					 | 
				
			||||||
+	struct vmpacket_descriptor *nxt;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	nxt = __hv_pkt_iter_next(channel, pkt);
 | 
					 | 
				
			||||||
+	if (!nxt)
 | 
					 | 
				
			||||||
+		hv_pkt_iter_close(channel);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	hv_signal_on_read(channel);
 | 
					 | 
				
			||||||
+	return nxt;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+#define foreach_vmbus_pkt(pkt, channel) \
 | 
					 | 
				
			||||||
+	for (pkt = hv_pkt_iter_first(channel); pkt; \
 | 
					 | 
				
			||||||
+	    pkt = hv_pkt_iter_next(channel, pkt))
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #endif /* _HYPERV_H */
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,34 +0,0 @@
 | 
				
			|||||||
From 0cf4173a76cf771d4d4406f48c59fcb85b5a5400 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:12 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 2/9] vmbus: vmbus_open(): reset onchannel_callback on error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
No real issue is observed without the patch, but let's add this
 | 
					 | 
				
			||||||
just in case.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit c248b14174e1337c1461f9b13a573ad90a136e1c)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/channel.c | 2 ++
 | 
					 | 
				
			||||||
 1 file changed, 2 insertions(+)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
index 321b8833fa6f..628d6fde1887 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
@@ -220,6 +220,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 | 
					 | 
				
			||||||
 		     get_order(send_ringbuffer_size + recv_ringbuffer_size));
 | 
					 | 
				
			||||||
 error_set_chnstate:
 | 
					 | 
				
			||||||
 	newchannel->state = CHANNEL_OPEN_STATE;
 | 
					 | 
				
			||||||
+	newchannel->onchannel_callback = NULL;
 | 
					 | 
				
			||||||
+	newchannel->channel_callback_context = NULL;
 | 
					 | 
				
			||||||
 	return err;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 EXPORT_SYMBOL_GPL(vmbus_open);
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
From d1d1e90f2106c7048feab6a6da955fc2ed521896 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:15 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 3/9] vmbus: add the matching tasklet_enable() in
 | 
					 | 
				
			||||||
 vmbus_close_internal()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If we disable a tasklet that is scheduled but hasn't started to run,
 | 
					 | 
				
			||||||
the tasklet has no chance to run any longer, so later we'll hang
 | 
					 | 
				
			||||||
in free_channel() -> tasklet_kill(), because the TASKLET_STATE_SCHED
 | 
					 | 
				
			||||||
can't be cleared in tasklet_action().
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With the patch, before free_channel() -> tasklet_kill() returns, the
 | 
					 | 
				
			||||||
tasklet still has a chance to run with a NULL channel->onchannel_callback,
 | 
					 | 
				
			||||||
which will be ignored safely, e.g. by vmbus_on_event().
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes: dad72a1d2844 ("vmbus: remove hv_event_tasklet_disable/enable")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 008d8d8bc0c86473a8549a365bee9a479243e412)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/channel.c | 1 +
 | 
					 | 
				
			||||||
 1 file changed, 1 insertion(+)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
index 628d6fde1887..7cd2bd9fd1f1 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
@@ -608,6 +608,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
 		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 out:
 | 
					 | 
				
			||||||
+	tasklet_enable(&channel->callback_event);
 | 
					 | 
				
			||||||
 	return ret;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,62 +0,0 @@
 | 
				
			|||||||
From 3fe617c0af23272071c320b295fb987f69f0ac77 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:20 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 4/9] 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>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 4713066c11b2396eafd2873cbed7bdd72d1571eb)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 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 7cd2bd9fd1f1..db5e6f8730d2 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
@@ -180,17 +180,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;
 | 
					 | 
				
			||||||
@@ -205,11 +206,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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,189 +0,0 @@
 | 
				
			|||||||
From 3809a76e095d648d7d99cb1822ce17844a22ad2a Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:23 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 5/9] vmbus: dynamically enqueue/dequeue a channel on
 | 
					 | 
				
			||||||
 vmbus_open/close
 | 
					 | 
				
			||||||
MIME-Version: 1.0
 | 
					 | 
				
			||||||
Content-Type: text/plain; charset=UTF-8
 | 
					 | 
				
			||||||
Content-Transfer-Encoding: 8bit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A just-closed channel may have a pending interrupt, and later when a new
 | 
					 | 
				
			||||||
channel with the same channel ID is not being fully initialized, the
 | 
					 | 
				
			||||||
pending interrupt of the previous channel with the same channel ID can run
 | 
					 | 
				
			||||||
the channel callback on the new channel data structure, causing a crash
 | 
					 | 
				
			||||||
of NULL pointer dereferencing.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Normally it’s pretty hard to reproduce the race condition, but it can
 | 
					 | 
				
			||||||
indeed happen with specially-designed hv_sock stress test cases.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
 | 
					 | 
				
			||||||
Tested-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 1df677b35ff010d0def33f5420773015815cf843)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/channel.c      | 12 +++++++++---
 | 
					 | 
				
			||||||
 drivers/hv/channel_mgmt.c | 50 +++++++++++++++++++++--------------------------
 | 
					 | 
				
			||||||
 include/linux/hyperv.h    |  3 +++
 | 
					 | 
				
			||||||
 3 files changed, 34 insertions(+), 31 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
index db5e6f8730d2..f288e506fba0 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel.c
 | 
					 | 
				
			||||||
@@ -177,6 +177,8 @@ 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_percpu_channel_enq(newchannel);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	ret = vmbus_post_msg(open_msg,
 | 
					 | 
				
			||||||
 			     sizeof(struct vmbus_channel_open_channel), true);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -189,23 +191,25 @@ 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_percpu_channel_deq(newchannel);
 | 
					 | 
				
			||||||
 error_free_gpadl:
 | 
					 | 
				
			||||||
 	vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
 | 
					 | 
				
			||||||
 	kfree(open_info);
 | 
					 | 
				
			||||||
@@ -551,6 +555,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 fbcb06352308..c5a01a4d589e 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
@@ -363,6 +363,17 @@ static void percpu_channel_enq(void *arg)
 | 
					 | 
				
			||||||
 	list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+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();
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 static void percpu_channel_deq(void *arg)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
 	struct vmbus_channel *channel = arg;
 | 
					 | 
				
			||||||
@@ -370,6 +381,17 @@ static void percpu_channel_deq(void *arg)
 | 
					 | 
				
			||||||
 	list_del_rcu(&channel->percpu_list);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+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();
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 static void vmbus_release_relid(u32 relid)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
@@ -390,15 +412,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));
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	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();
 | 
					 | 
				
			||||||
-	}
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	if (channel->primary_channel == NULL) {
 | 
					 | 
				
			||||||
 		list_del(&channel->listentry);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -491,16 +504,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	init_vp_index(newchannel, dev_type);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	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();
 | 
					 | 
				
			||||||
-	}
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	/*
 | 
					 | 
				
			||||||
 	 * This state is used to indicate a successful open
 | 
					 | 
				
			||||||
 	 * so that when we do close the channel normally, we
 | 
					 | 
				
			||||||
@@ -549,15 +552,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 | 
					 | 
				
			||||||
 	list_del(&newchannel->listentry);
 | 
					 | 
				
			||||||
 	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	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();
 | 
					 | 
				
			||||||
-	}
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	vmbus_release_relid(newchannel->offermsg.child_relid);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 err_free_chan:
 | 
					 | 
				
			||||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
index 0c170a3f0d8b..ba93b7e4a972 100644
 | 
					 | 
				
			||||||
--- a/include/linux/hyperv.h
 | 
					 | 
				
			||||||
+++ b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
@@ -1437,6 +1437,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
 | 
					 | 
				
			||||||
 				const int *srv_version, int srv_vercnt,
 | 
					 | 
				
			||||||
 				int *nego_fw_version, int *nego_srv_version);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,934 +0,0 @@
 | 
				
			|||||||
From 189479e4a60fcdb92439aebd7a116f4ba0eede0d Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:26 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 6/9] hv_sock: implements Hyper-V transport for Virtual Sockets
 | 
					 | 
				
			||||||
 (AF_VSOCK)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
 | 
					 | 
				
			||||||
mechanism between the host and the guest. It uses VMBus ringbuffer as the
 | 
					 | 
				
			||||||
transportation layer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With hv_sock, applications between the host (Windows 10, Windows Server
 | 
					 | 
				
			||||||
2016 or newer) and the guest can talk with each other using the traditional
 | 
					 | 
				
			||||||
socket APIs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
More info about Hyper-V Sockets is available here:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"Make your own integration services":
 | 
					 | 
				
			||||||
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The patch implements the necessary support in Linux guest by introducing a new
 | 
					 | 
				
			||||||
vsock transport for AF_VSOCK.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Andy King <acking@vmware.com>
 | 
					 | 
				
			||||||
Cc: Dmitry Torokhov <dtor@vmware.com>
 | 
					 | 
				
			||||||
Cc: George Zhang <georgezhang@vmware.com>
 | 
					 | 
				
			||||||
Cc: Jorgen Hansen <jhansen@vmware.com>
 | 
					 | 
				
			||||||
Cc: Reilly Grant <grantr@vmware.com>
 | 
					 | 
				
			||||||
Cc: Asias He <asias@redhat.com>
 | 
					 | 
				
			||||||
Cc: Stefan Hajnoczi <stefanha@redhat.com>
 | 
					 | 
				
			||||||
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
 | 
					 | 
				
			||||||
Cc: Cathy Avery <cavery@redhat.com>
 | 
					 | 
				
			||||||
Cc: Rolf Neugebauer <rolf.neugebauer@docker.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 3476be340d2ff777609fca3e763da0292acbfc45)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 MAINTAINERS                      |   1 +
 | 
					 | 
				
			||||||
 net/vmw_vsock/Kconfig            |  12 +
 | 
					 | 
				
			||||||
 net/vmw_vsock/Makefile           |   3 +
 | 
					 | 
				
			||||||
 net/vmw_vsock/hyperv_transport.c | 829 +++++++++++++++++++++++++++++++++++++++
 | 
					 | 
				
			||||||
 4 files changed, 845 insertions(+)
 | 
					 | 
				
			||||||
 create mode 100644 net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/MAINTAINERS b/MAINTAINERS
 | 
					 | 
				
			||||||
index 38d3e4ed7208..53bf52ce3173 100644
 | 
					 | 
				
			||||||
--- a/MAINTAINERS
 | 
					 | 
				
			||||||
+++ b/MAINTAINERS
 | 
					 | 
				
			||||||
@@ -6077,6 +6077,7 @@ F:	drivers/net/hyperv/
 | 
					 | 
				
			||||||
 F:	drivers/scsi/storvsc_drv.c
 | 
					 | 
				
			||||||
 F:	drivers/uio/uio_hv_generic.c
 | 
					 | 
				
			||||||
 F:	drivers/video/fbdev/hyperv_fb.c
 | 
					 | 
				
			||||||
+F:	net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
 F:	include/linux/hyperv.h
 | 
					 | 
				
			||||||
 F:	tools/hv/
 | 
					 | 
				
			||||||
 F:	Documentation/ABI/stable/sysfs-bus-vmbus
 | 
					 | 
				
			||||||
diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig
 | 
					 | 
				
			||||||
index 8831e7c42167..a24369d175fd 100644
 | 
					 | 
				
			||||||
--- a/net/vmw_vsock/Kconfig
 | 
					 | 
				
			||||||
+++ b/net/vmw_vsock/Kconfig
 | 
					 | 
				
			||||||
@@ -46,3 +46,15 @@ config VIRTIO_VSOCKETS_COMMON
 | 
					 | 
				
			||||||
 	  This option is selected by any driver which needs to access
 | 
					 | 
				
			||||||
 	  the virtio_vsock.  The module will be called
 | 
					 | 
				
			||||||
 	  vmw_vsock_virtio_transport_common.
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+config HYPERV_VSOCKETS
 | 
					 | 
				
			||||||
+	tristate "Hyper-V transport for Virtual Sockets"
 | 
					 | 
				
			||||||
+	depends on VSOCKETS && HYPERV
 | 
					 | 
				
			||||||
+	help
 | 
					 | 
				
			||||||
+	  This module implements a Hyper-V transport for Virtual Sockets.
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	  Enable this transport if your Virtual Machine host supports Virtual
 | 
					 | 
				
			||||||
+	  Sockets over Hyper-V VMBus.
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	  To compile this driver as a module, choose M here: the module will be
 | 
					 | 
				
			||||||
+	  called hv_sock. If unsure, say N.
 | 
					 | 
				
			||||||
diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile
 | 
					 | 
				
			||||||
index bc27c70e0e59..f70f3e70ce9e 100644
 | 
					 | 
				
			||||||
--- a/net/vmw_vsock/Makefile
 | 
					 | 
				
			||||||
+++ b/net/vmw_vsock/Makefile
 | 
					 | 
				
			||||||
@@ -2,6 +2,7 @@ obj-$(CONFIG_VSOCKETS) += vsock.o
 | 
					 | 
				
			||||||
 obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
 | 
					 | 
				
			||||||
 obj-$(CONFIG_VIRTIO_VSOCKETS) += vmw_vsock_virtio_transport.o
 | 
					 | 
				
			||||||
 obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += vmw_vsock_virtio_transport_common.o
 | 
					 | 
				
			||||||
+obj-$(CONFIG_HYPERV_VSOCKETS) += hv_sock.o
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 vsock-y += af_vsock.o vsock_addr.o
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -11,3 +12,5 @@ vmw_vsock_vmci_transport-y += vmci_transport.o vmci_transport_notify.o \
 | 
					 | 
				
			||||||
 vmw_vsock_virtio_transport-y += virtio_transport.o
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 vmw_vsock_virtio_transport_common-y += virtio_transport_common.o
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+hv_sock-y += hyperv_transport.o
 | 
					 | 
				
			||||||
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
new file mode 100644
 | 
					 | 
				
			||||||
index 000000000000..fd89bf357617
 | 
					 | 
				
			||||||
--- /dev/null
 | 
					 | 
				
			||||||
+++ b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
@@ -0,0 +1,829 @@
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Hyper-V transport for vsock
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Hyper-V Sockets supplies a byte-stream based communication mechanism
 | 
					 | 
				
			||||||
+ * between the host and the VM. This driver implements the necessary
 | 
					 | 
				
			||||||
+ * support in the VM by introducing the new vsock transport.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Copyright (c) 2017, Microsoft Corporation.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * This program is free software; you can redistribute it and/or modify it
 | 
					 | 
				
			||||||
+ * under the terms and conditions of the GNU General Public License,
 | 
					 | 
				
			||||||
+ * version 2, as published by the Free Software Foundation.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * This program is distributed in the hope it will be useful, but WITHOUT
 | 
					 | 
				
			||||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
					 | 
				
			||||||
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 | 
					 | 
				
			||||||
+ * more details.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+#include <linux/module.h>
 | 
					 | 
				
			||||||
+#include <linux/vmalloc.h>
 | 
					 | 
				
			||||||
+#include <linux/hyperv.h>
 | 
					 | 
				
			||||||
+#include <net/sock.h>
 | 
					 | 
				
			||||||
+#include <net/af_vsock.h>
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* The host side's design of the feature requires 6 exact 4KB pages for
 | 
					 | 
				
			||||||
+ * recv/send rings respectively -- this is suboptimal considering memory
 | 
					 | 
				
			||||||
+ * consumption, however unluckily we have to live with it, before the
 | 
					 | 
				
			||||||
+ * host comes up with a better design in the future.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+#define PAGE_SIZE_4K		4096
 | 
					 | 
				
			||||||
+#define RINGBUFFER_HVS_RCV_SIZE (PAGE_SIZE_4K * 6)
 | 
					 | 
				
			||||||
+#define RINGBUFFER_HVS_SND_SIZE (PAGE_SIZE_4K * 6)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* The MTU is 16KB per the host side's design */
 | 
					 | 
				
			||||||
+#define HVS_MTU_SIZE		(1024 * 16)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+struct vmpipe_proto_header {
 | 
					 | 
				
			||||||
+	u32 pkt_type;
 | 
					 | 
				
			||||||
+	u32 data_size;
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* For recv, we use the VMBus in-place packet iterator APIs to directly copy
 | 
					 | 
				
			||||||
+ * data from the ringbuffer into the userspace buffer.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+struct hvs_recv_buf {
 | 
					 | 
				
			||||||
+	/* The header before the payload data */
 | 
					 | 
				
			||||||
+	struct vmpipe_proto_header hdr;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The payload */
 | 
					 | 
				
			||||||
+	u8 data[HVS_MTU_SIZE];
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* We can send up to HVS_MTU_SIZE bytes of payload to the host, but let's use
 | 
					 | 
				
			||||||
+ * a small size, i.e. HVS_SEND_BUF_SIZE, to minimize the dynamically-allocated
 | 
					 | 
				
			||||||
+ * buffer, because tests show there is no significant performance difference.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Note: the buffer can be eliminated in the future when we add new VMBus
 | 
					 | 
				
			||||||
+ * ringbuffer APIs that allow us to directly copy data from userspace buffer
 | 
					 | 
				
			||||||
+ * to VMBus ringbuffer.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+#define HVS_SEND_BUF_SIZE (PAGE_SIZE_4K - sizeof(struct vmpipe_proto_header))
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+struct hvs_send_buf {
 | 
					 | 
				
			||||||
+	/* The header before the payload data */
 | 
					 | 
				
			||||||
+	struct vmpipe_proto_header hdr;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The payload */
 | 
					 | 
				
			||||||
+	u8 data[HVS_SEND_BUF_SIZE];
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#define HVS_HEADER_LEN	(sizeof(struct vmpacket_descriptor) + \
 | 
					 | 
				
			||||||
+			 sizeof(struct vmpipe_proto_header))
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write(), and
 | 
					 | 
				
			||||||
+ * __hv_pkt_iter_next().
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+#define VMBUS_PKT_TRAILER	(sizeof(u64))
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#define HVS_PKT_LEN(payload_len)	(HVS_HEADER_LEN + \
 | 
					 | 
				
			||||||
+					 ALIGN((payload_len), 8) + \
 | 
					 | 
				
			||||||
+					 VMBUS_PKT_TRAILER)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* Per-socket state (accessed via vsk->trans) */
 | 
					 | 
				
			||||||
+struct hvsock {
 | 
					 | 
				
			||||||
+	struct vsock_sock *vsk;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	uuid_le	vm_srv_id;
 | 
					 | 
				
			||||||
+	uuid_le	host_srv_id;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan;
 | 
					 | 
				
			||||||
+	struct vmpacket_descriptor *recv_desc;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The length of the payload not delivered to userland yet */
 | 
					 | 
				
			||||||
+	u32 recv_data_len;
 | 
					 | 
				
			||||||
+	/* The offset of the payload */
 | 
					 | 
				
			||||||
+	u32 recv_data_off;
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* In the VM, we support Hyper-V Sockets with AF_VSOCK, and the endpoint is
 | 
					 | 
				
			||||||
+ * <cid, port> (see struct sockaddr_vm). Note: cid is not really used here:
 | 
					 | 
				
			||||||
+ * when we write apps to connect to the host, we can only use VMADDR_CID_ANY
 | 
					 | 
				
			||||||
+ * or VMADDR_CID_HOST (both are equivalent) as the remote cid, and when we
 | 
					 | 
				
			||||||
+ * write apps to bind() & listen() in the VM, we can only use VMADDR_CID_ANY
 | 
					 | 
				
			||||||
+ * as the local cid.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * On the host, Hyper-V Sockets are supported by Winsock AF_HYPERV:
 | 
					 | 
				
			||||||
+ * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-
 | 
					 | 
				
			||||||
+ * guide/make-integration-service, and the endpoint is <VmID, ServiceId> with
 | 
					 | 
				
			||||||
+ * the below sockaddr:
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * struct SOCKADDR_HV
 | 
					 | 
				
			||||||
+ * {
 | 
					 | 
				
			||||||
+ *    ADDRESS_FAMILY Family;
 | 
					 | 
				
			||||||
+ *    USHORT Reserved;
 | 
					 | 
				
			||||||
+ *    GUID VmId;
 | 
					 | 
				
			||||||
+ *    GUID ServiceId;
 | 
					 | 
				
			||||||
+ * };
 | 
					 | 
				
			||||||
+ * Note: VmID is not used by Linux VM and actually it isn't transmitted via
 | 
					 | 
				
			||||||
+ * VMBus, because here it's obvious the host and the VM can easily identify
 | 
					 | 
				
			||||||
+ * each other. Though the VmID is useful on the host, especially in the case
 | 
					 | 
				
			||||||
+ * of Windows container, Linux VM doesn't need it at all.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * To make use of the AF_VSOCK infrastructure in Linux VM, we have to limit
 | 
					 | 
				
			||||||
+ * the available GUID space of SOCKADDR_HV so that we can create a mapping
 | 
					 | 
				
			||||||
+ * between AF_VSOCK port and SOCKADDR_HV Service GUID. The rule of writing
 | 
					 | 
				
			||||||
+ * Hyper-V Sockets apps on the host and in Linux VM is:
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ ****************************************************************************
 | 
					 | 
				
			||||||
+ * the only valid Service GUIDs, from the perspectives of both the host and *
 | 
					 | 
				
			||||||
+ * Linux VM, that can be connected by the other end, must conform to this   *
 | 
					 | 
				
			||||||
+ * format: <port>-facb-11e6-bd58-64006a7986d3, and the "port" must be in    *
 | 
					 | 
				
			||||||
+ * this range [0, 0x7FFFFFFF].                                              *
 | 
					 | 
				
			||||||
+ ****************************************************************************
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * When we write apps on the host to connect(), the GUID ServiceID is used.
 | 
					 | 
				
			||||||
+ * When we write apps in Linux VM to connect(), we only need to specify the
 | 
					 | 
				
			||||||
+ * port and the driver will form the GUID and use that to request the host.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * From the perspective of Linux VM:
 | 
					 | 
				
			||||||
+ * 1. the local ephemeral port (i.e. the local auto-bound port when we call
 | 
					 | 
				
			||||||
+ * connect() without explicit bind()) is generated by __vsock_bind_stream(),
 | 
					 | 
				
			||||||
+ * and the range is [1024, 0xFFFFFFFF).
 | 
					 | 
				
			||||||
+ * 2. the remote ephemeral port (i.e. the auto-generated remote port for
 | 
					 | 
				
			||||||
+ * a connect request initiated by the host's connect()) is generated by
 | 
					 | 
				
			||||||
+ * hvs_remote_addr_init() and the range is [0x80000000, 0xFFFFFFFF).
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#define MAX_LISTEN_PORT			((u32)0x7FFFFFFF)
 | 
					 | 
				
			||||||
+#define MAX_VM_LISTEN_PORT		MAX_LISTEN_PORT
 | 
					 | 
				
			||||||
+#define MAX_HOST_LISTEN_PORT		MAX_LISTEN_PORT
 | 
					 | 
				
			||||||
+#define MIN_HOST_EPHEMERAL_PORT		(MAX_HOST_LISTEN_PORT + 1)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* 00000000-facb-11e6-bd58-64006a7986d3 */
 | 
					 | 
				
			||||||
+static const uuid_le srv_id_template =
 | 
					 | 
				
			||||||
+	UUID_LE(0x00000000, 0xfacb, 0x11e6, 0xbd, 0x58,
 | 
					 | 
				
			||||||
+		0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static inline bool is_valid_srv_id(const uuid_le *id)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return !memcmp(&id->b[4], &srv_id_template.b[4], sizeof(uuid_le) - 4);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static inline unsigned int get_port_by_srv_id(const uuid_le *svr_id)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return *((unsigned int *)svr_id);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static inline void hvs_addr_init(struct sockaddr_vm *addr,
 | 
					 | 
				
			||||||
+				 const uuid_le *svr_id)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	unsigned int port = get_port_by_srv_id(svr_id);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	vsock_addr_init(addr, VMADDR_CID_ANY, port);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static inline void hvs_remote_addr_init(struct sockaddr_vm *remote,
 | 
					 | 
				
			||||||
+					struct sockaddr_vm *local)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	static u32 host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
 | 
					 | 
				
			||||||
+	struct sock *sk;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	vsock_addr_init(remote, VMADDR_CID_ANY, VMADDR_PORT_ANY);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	while (1) {
 | 
					 | 
				
			||||||
+		/* Wrap around ? */
 | 
					 | 
				
			||||||
+		if (host_ephemeral_port < MIN_HOST_EPHEMERAL_PORT ||
 | 
					 | 
				
			||||||
+		    host_ephemeral_port == VMADDR_PORT_ANY)
 | 
					 | 
				
			||||||
+			host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		remote->svm_port = host_ephemeral_port++;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		sk = vsock_find_connected_socket(remote, local);
 | 
					 | 
				
			||||||
+		if (!sk) {
 | 
					 | 
				
			||||||
+			/* Found an available ephemeral port */
 | 
					 | 
				
			||||||
+			return;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		/* Release refcnt got in vsock_find_connected_socket */
 | 
					 | 
				
			||||||
+		sock_put(sk);
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static bool hvs_channel_readable(struct vmbus_channel *chan)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	u32 readable = hv_get_bytes_to_read(&chan->inbound);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* 0-size payload means FIN */
 | 
					 | 
				
			||||||
+	return readable >= HVS_PKT_LEN(0);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_channel_readable_payload(struct vmbus_channel *chan)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	u32 readable = hv_get_bytes_to_read(&chan->inbound);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (readable > HVS_PKT_LEN(0)) {
 | 
					 | 
				
			||||||
+		/* At least we have 1 byte to read. We don't need to return
 | 
					 | 
				
			||||||
+		 * the exact readable bytes: see vsock_stream_recvmsg() ->
 | 
					 | 
				
			||||||
+		 * vsock_stream_has_data().
 | 
					 | 
				
			||||||
+		 */
 | 
					 | 
				
			||||||
+		return 1;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (readable == HVS_PKT_LEN(0)) {
 | 
					 | 
				
			||||||
+		/* 0-size payload means FIN */
 | 
					 | 
				
			||||||
+		return 0;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* No payload or FIN */
 | 
					 | 
				
			||||||
+	return -1;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static inline size_t hvs_channel_writable_bytes(struct vmbus_channel *chan)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	u32 writeable = hv_get_bytes_to_write(&chan->outbound);
 | 
					 | 
				
			||||||
+	size_t ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The ringbuffer mustn't be 100% full, and we should reserve a
 | 
					 | 
				
			||||||
+	 * zero-length-payload packet for the FIN: see hv_ringbuffer_write()
 | 
					 | 
				
			||||||
+	 * and hvs_shutdown().
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (writeable <= HVS_PKT_LEN(1) + HVS_PKT_LEN(0))
 | 
					 | 
				
			||||||
+		return 0;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = writeable - HVS_PKT_LEN(1) - HVS_PKT_LEN(0);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return round_down(ret, 8);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_send_data(struct vmbus_channel *chan,
 | 
					 | 
				
			||||||
+			 struct hvs_send_buf *send_buf, size_t to_write)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	send_buf->hdr.pkt_type = 1;
 | 
					 | 
				
			||||||
+	send_buf->hdr.data_size = to_write;
 | 
					 | 
				
			||||||
+	return vmbus_sendpacket(chan, &send_buf->hdr,
 | 
					 | 
				
			||||||
+				sizeof(send_buf->hdr) + to_write,
 | 
					 | 
				
			||||||
+				0, VM_PKT_DATA_INBAND, 0);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_channel_cb(void *ctx)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct sock *sk = (struct sock *)ctx;
 | 
					 | 
				
			||||||
+	struct vsock_sock *vsk = vsock_sk(sk);
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hvs->chan;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (hvs_channel_readable(chan))
 | 
					 | 
				
			||||||
+		sk->sk_data_ready(sk);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* Mark it writable only if there is enough space */
 | 
					 | 
				
			||||||
+	if (hvs_channel_writable_bytes(chan) >= HVS_SEND_BUF_SIZE)
 | 
					 | 
				
			||||||
+		sk->sk_write_space(sk);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_close_connection(struct vmbus_channel *chan)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct sock *sk = get_per_channel_state(chan);
 | 
					 | 
				
			||||||
+	struct vsock_sock *vsk = vsock_sk(sk);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	sk->sk_state = SS_UNCONNECTED;
 | 
					 | 
				
			||||||
+	sock_set_flag(sk, SOCK_DONE);
 | 
					 | 
				
			||||||
+	vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	sk->sk_state_change(sk);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_open_connection(struct vmbus_channel *chan)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	uuid_le *if_instance, *if_type;
 | 
					 | 
				
			||||||
+	unsigned char conn_from_host;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	struct sockaddr_vm addr;
 | 
					 | 
				
			||||||
+	struct sock *sk, *new = NULL;
 | 
					 | 
				
			||||||
+	struct vsock_sock *vnew;
 | 
					 | 
				
			||||||
+	struct hvsock *hvs, *hvs_new;
 | 
					 | 
				
			||||||
+	int ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if_type = &chan->offermsg.offer.if_type;
 | 
					 | 
				
			||||||
+	if_instance = &chan->offermsg.offer.if_instance;
 | 
					 | 
				
			||||||
+	conn_from_host = chan->offermsg.offer.u.pipe.user_def[0];
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The host or the VM should only listen on a port in
 | 
					 | 
				
			||||||
+	 * [0, MAX_LISTEN_PORT]
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (!is_valid_srv_id(if_type) ||
 | 
					 | 
				
			||||||
+	    get_port_by_srv_id(if_type) > MAX_LISTEN_PORT)
 | 
					 | 
				
			||||||
+		return;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs_addr_init(&addr, conn_from_host ? if_type : if_instance);
 | 
					 | 
				
			||||||
+	sk = vsock_find_bound_socket(&addr);
 | 
					 | 
				
			||||||
+	if (!sk)
 | 
					 | 
				
			||||||
+		return;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) ||
 | 
					 | 
				
			||||||
+	    (!conn_from_host && sk->sk_state != SS_CONNECTING))
 | 
					 | 
				
			||||||
+		goto out;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (conn_from_host) {
 | 
					 | 
				
			||||||
+		if (sk->sk_ack_backlog >= sk->sk_max_ack_backlog)
 | 
					 | 
				
			||||||
+			goto out;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		new = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL,
 | 
					 | 
				
			||||||
+				     sk->sk_type, 0);
 | 
					 | 
				
			||||||
+		if (!new)
 | 
					 | 
				
			||||||
+			goto out;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		new->sk_state = SS_CONNECTING;
 | 
					 | 
				
			||||||
+		vnew = vsock_sk(new);
 | 
					 | 
				
			||||||
+		hvs_new = vnew->trans;
 | 
					 | 
				
			||||||
+		hvs_new->chan = chan;
 | 
					 | 
				
			||||||
+	} else {
 | 
					 | 
				
			||||||
+		hvs = vsock_sk(sk)->trans;
 | 
					 | 
				
			||||||
+		hvs->chan = chan;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	set_channel_read_mode(chan, HV_CALL_DIRECT);
 | 
					 | 
				
			||||||
+	ret = vmbus_open(chan, RINGBUFFER_HVS_SND_SIZE,
 | 
					 | 
				
			||||||
+			 RINGBUFFER_HVS_RCV_SIZE, NULL, 0,
 | 
					 | 
				
			||||||
+			 hvs_channel_cb, conn_from_host ? new : sk);
 | 
					 | 
				
			||||||
+	if (ret != 0) {
 | 
					 | 
				
			||||||
+		if (conn_from_host) {
 | 
					 | 
				
			||||||
+			hvs_new->chan = NULL;
 | 
					 | 
				
			||||||
+			sock_put(new);
 | 
					 | 
				
			||||||
+		} else {
 | 
					 | 
				
			||||||
+			hvs->chan = NULL;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
+		goto out;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	set_per_channel_state(chan, conn_from_host ? new : sk);
 | 
					 | 
				
			||||||
+	vmbus_set_chn_rescind_callback(chan, hvs_close_connection);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* See hvs_channel_cb() and hvs_notify_poll_out()  */
 | 
					 | 
				
			||||||
+	set_channel_pending_send_size(chan,
 | 
					 | 
				
			||||||
+				      HVS_PKT_LEN(HVS_SEND_BUF_SIZE) + 1);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (conn_from_host) {
 | 
					 | 
				
			||||||
+		new->sk_state = SS_CONNECTED;
 | 
					 | 
				
			||||||
+		sk->sk_ack_backlog++;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		hvs_addr_init(&vnew->local_addr, if_type);
 | 
					 | 
				
			||||||
+		hvs_remote_addr_init(&vnew->remote_addr, &vnew->local_addr);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		hvs_new->vm_srv_id = *if_type;
 | 
					 | 
				
			||||||
+		hvs_new->host_srv_id = *if_instance;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		vsock_insert_connected(vnew);
 | 
					 | 
				
			||||||
+		vsock_enqueue_accept(sk, new);
 | 
					 | 
				
			||||||
+	} else {
 | 
					 | 
				
			||||||
+		sk->sk_state = SS_CONNECTED;
 | 
					 | 
				
			||||||
+		sk->sk_socket->state = SS_CONNECTED;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		vsock_insert_connected(vsock_sk(sk));
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	sk->sk_state_change(sk);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+out:
 | 
					 | 
				
			||||||
+	/* Release refcnt obtained when we called vsock_find_bound_socket() */
 | 
					 | 
				
			||||||
+	sock_put(sk);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static u32 hvs_get_local_cid(void)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return VMADDR_CID_ANY;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_sock_init(struct vsock_sock *vsk, struct vsock_sock *psk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs = kzalloc(sizeof(*hvs), GFP_KERNEL);
 | 
					 | 
				
			||||||
+	if (!hvs)
 | 
					 | 
				
			||||||
+		return -ENOMEM;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	vsk->trans = hvs;
 | 
					 | 
				
			||||||
+	hvs->vsk = vsk;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_connect(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *h = vsk->trans;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	h->vm_srv_id = srv_id_template;
 | 
					 | 
				
			||||||
+	h->host_srv_id = srv_id_template;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	*((u32 *)&h->vm_srv_id) = vsk->local_addr.svm_port;
 | 
					 | 
				
			||||||
+	*((u32 *)&h->host_srv_id) = vsk->remote_addr.svm_port;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return vmbus_send_tl_connect_request(&h->vm_srv_id, &h->host_srv_id);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_shutdown(struct vsock_sock *vsk, int mode)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct vmpipe_proto_header hdr;
 | 
					 | 
				
			||||||
+	struct hvs_send_buf *send_buf;
 | 
					 | 
				
			||||||
+	struct hvsock *hvs;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (!(mode & SEND_SHUTDOWN))
 | 
					 | 
				
			||||||
+		return 0;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs = vsk->trans;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	send_buf = (struct hvs_send_buf *)&hdr;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* It can't fail: see hvs_channel_writable_bytes(). */
 | 
					 | 
				
			||||||
+	(void)hvs_send_data(hvs->chan, send_buf, 0);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_release(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hvs->chan;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (chan)
 | 
					 | 
				
			||||||
+		hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	vsock_remove_sock(vsk);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_destruct(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hvs->chan;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (chan)
 | 
					 | 
				
			||||||
+		vmbus_hvsock_device_unregister(chan);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	kfree(hvs);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -EOPNOTSUPP;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_dgram_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
 | 
					 | 
				
			||||||
+			     size_t len, int flags)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -EOPNOTSUPP;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_dgram_enqueue(struct vsock_sock *vsk,
 | 
					 | 
				
			||||||
+			     struct sockaddr_vm *remote, struct msghdr *msg,
 | 
					 | 
				
			||||||
+			     size_t dgram_len)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -EOPNOTSUPP;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static bool hvs_dgram_allow(u32 cid, u32 port)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return false;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
 | 
					 | 
				
			||||||
+				  size_t len, int flags)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	bool need_refill = !hvs->recv_desc;
 | 
					 | 
				
			||||||
+	struct hvs_recv_buf *recv_buf;
 | 
					 | 
				
			||||||
+	u32 payload_len, to_read;
 | 
					 | 
				
			||||||
+	int ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (flags & MSG_PEEK)
 | 
					 | 
				
			||||||
+		return -EOPNOTSUPP;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (need_refill) {
 | 
					 | 
				
			||||||
+		hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
 | 
					 | 
				
			||||||
+		recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		payload_len = recv_buf->hdr.data_size;
 | 
					 | 
				
			||||||
+		if (payload_len == 0 || payload_len > HVS_MTU_SIZE)
 | 
					 | 
				
			||||||
+			return -EIO;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		hvs->recv_data_len = payload_len;
 | 
					 | 
				
			||||||
+		hvs->recv_data_off = 0;
 | 
					 | 
				
			||||||
+	} else {
 | 
					 | 
				
			||||||
+		recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	to_read = min_t(u32, len, hvs->recv_data_len);
 | 
					 | 
				
			||||||
+	ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read);
 | 
					 | 
				
			||||||
+	if (ret != 0)
 | 
					 | 
				
			||||||
+		return ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs->recv_data_len -= to_read;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (hvs->recv_data_len == 0)
 | 
					 | 
				
			||||||
+		hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
 | 
					 | 
				
			||||||
+	else
 | 
					 | 
				
			||||||
+		hvs->recv_data_off += to_read;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return to_read;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
 | 
					 | 
				
			||||||
+				  size_t len)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hvs->chan;
 | 
					 | 
				
			||||||
+	struct hvs_send_buf *send_buf;
 | 
					 | 
				
			||||||
+	size_t to_write, max_writable, ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	BUILD_BUG_ON(sizeof(*send_buf) != PAGE_SIZE_4K);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	send_buf = kmalloc(sizeof(*send_buf), GFP_KERNEL);
 | 
					 | 
				
			||||||
+	if (!send_buf)
 | 
					 | 
				
			||||||
+		return -ENOMEM;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	max_writable = hvs_channel_writable_bytes(chan);
 | 
					 | 
				
			||||||
+	to_write = min_t(size_t, len, max_writable);
 | 
					 | 
				
			||||||
+	to_write = min_t(size_t, to_write, HVS_SEND_BUF_SIZE);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = memcpy_from_msg(send_buf->data, msg, to_write);
 | 
					 | 
				
			||||||
+	if (ret < 0)
 | 
					 | 
				
			||||||
+		goto out;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = hvs_send_data(hvs->chan, send_buf, to_write);
 | 
					 | 
				
			||||||
+	if (ret < 0)
 | 
					 | 
				
			||||||
+		goto out;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = to_write;
 | 
					 | 
				
			||||||
+out:
 | 
					 | 
				
			||||||
+	kfree(send_buf);
 | 
					 | 
				
			||||||
+	return ret;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static s64 hvs_stream_has_data(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+	s64 ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	switch (hvs_channel_readable_payload(hvs->chan)) {
 | 
					 | 
				
			||||||
+	case 1:
 | 
					 | 
				
			||||||
+		ret = 1;
 | 
					 | 
				
			||||||
+		break;
 | 
					 | 
				
			||||||
+	case 0:
 | 
					 | 
				
			||||||
+		vsk->peer_shutdown |= SEND_SHUTDOWN;
 | 
					 | 
				
			||||||
+		ret = 0;
 | 
					 | 
				
			||||||
+		break;
 | 
					 | 
				
			||||||
+	default: /* -1 */
 | 
					 | 
				
			||||||
+		ret = 0;
 | 
					 | 
				
			||||||
+		break;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return ret;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static s64 hvs_stream_has_space(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return hvs_channel_writable_bytes(hvs->chan);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static u64 hvs_stream_rcvhiwat(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return HVS_MTU_SIZE + 1;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static bool hvs_stream_is_active(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return hvs->chan != NULL;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static bool hvs_stream_allow(u32 cid, u32 port)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	static const u32 valid_cids[] = {
 | 
					 | 
				
			||||||
+		VMADDR_CID_ANY,
 | 
					 | 
				
			||||||
+		VMADDR_CID_HOST,
 | 
					 | 
				
			||||||
+	};
 | 
					 | 
				
			||||||
+	int i;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* The host's port range [MIN_HOST_EPHEMERAL_PORT, 0xFFFFFFFF) is
 | 
					 | 
				
			||||||
+	 * reserved as ephemeral ports, which are used as the host's ports
 | 
					 | 
				
			||||||
+	 * when the host initiates connections.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (port > MAX_HOST_LISTEN_PORT)
 | 
					 | 
				
			||||||
+		return false;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	for (i = 0; i < ARRAY_SIZE(valid_cids); i++) {
 | 
					 | 
				
			||||||
+		if (cid == valid_cids[i])
 | 
					 | 
				
			||||||
+			return true;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return false;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_poll_in(struct vsock_sock *vsk, size_t target, bool *readable)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	*readable = hvs_channel_readable(hvs->chan);
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_poll_out(struct vsock_sock *vsk, size_t target, bool *writable)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	/* Report writable only if there is enough space */
 | 
					 | 
				
			||||||
+	*writable = hvs_stream_has_space(vsk) >= HVS_SEND_BUF_SIZE;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_recv_init(struct vsock_sock *vsk, size_t target,
 | 
					 | 
				
			||||||
+			 struct vsock_transport_recv_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_recv_pre_block(struct vsock_sock *vsk, size_t target,
 | 
					 | 
				
			||||||
+			      struct vsock_transport_recv_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_recv_pre_dequeue(struct vsock_sock *vsk, size_t target,
 | 
					 | 
				
			||||||
+				struct vsock_transport_recv_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_recv_post_dequeue(struct vsock_sock *vsk, size_t target,
 | 
					 | 
				
			||||||
+				 ssize_t copied, bool data_read,
 | 
					 | 
				
			||||||
+				 struct vsock_transport_recv_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_send_init(struct vsock_sock *vsk,
 | 
					 | 
				
			||||||
+			 struct vsock_transport_send_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_send_pre_block(struct vsock_sock *vsk,
 | 
					 | 
				
			||||||
+			      struct vsock_transport_send_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_send_pre_enqueue(struct vsock_sock *vsk,
 | 
					 | 
				
			||||||
+				struct vsock_transport_send_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static
 | 
					 | 
				
			||||||
+int hvs_notify_send_post_enqueue(struct vsock_sock *vsk, ssize_t written,
 | 
					 | 
				
			||||||
+				 struct vsock_transport_send_notify_data *d)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_set_buffer_size(struct vsock_sock *vsk, u64 val)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	/* Ignored. */
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_set_min_buffer_size(struct vsock_sock *vsk, u64 val)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	/* Ignored. */
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void hvs_set_max_buffer_size(struct vsock_sock *vsk, u64 val)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	/* Ignored. */
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static u64 hvs_get_buffer_size(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -ENOPROTOOPT;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static u64 hvs_get_min_buffer_size(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -ENOPROTOOPT;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static u64 hvs_get_max_buffer_size(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return -ENOPROTOOPT;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static struct vsock_transport hvs_transport = {
 | 
					 | 
				
			||||||
+	.get_local_cid            = hvs_get_local_cid,
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	.init                     = hvs_sock_init,
 | 
					 | 
				
			||||||
+	.destruct                 = hvs_destruct,
 | 
					 | 
				
			||||||
+	.release                  = hvs_release,
 | 
					 | 
				
			||||||
+	.connect                  = hvs_connect,
 | 
					 | 
				
			||||||
+	.shutdown                 = hvs_shutdown,
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	.dgram_bind               = hvs_dgram_bind,
 | 
					 | 
				
			||||||
+	.dgram_dequeue            = hvs_dgram_dequeue,
 | 
					 | 
				
			||||||
+	.dgram_enqueue            = hvs_dgram_enqueue,
 | 
					 | 
				
			||||||
+	.dgram_allow              = hvs_dgram_allow,
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	.stream_dequeue           = hvs_stream_dequeue,
 | 
					 | 
				
			||||||
+	.stream_enqueue           = hvs_stream_enqueue,
 | 
					 | 
				
			||||||
+	.stream_has_data          = hvs_stream_has_data,
 | 
					 | 
				
			||||||
+	.stream_has_space         = hvs_stream_has_space,
 | 
					 | 
				
			||||||
+	.stream_rcvhiwat          = hvs_stream_rcvhiwat,
 | 
					 | 
				
			||||||
+	.stream_is_active         = hvs_stream_is_active,
 | 
					 | 
				
			||||||
+	.stream_allow             = hvs_stream_allow,
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	.notify_poll_in           = hvs_notify_poll_in,
 | 
					 | 
				
			||||||
+	.notify_poll_out          = hvs_notify_poll_out,
 | 
					 | 
				
			||||||
+	.notify_recv_init         = hvs_notify_recv_init,
 | 
					 | 
				
			||||||
+	.notify_recv_pre_block    = hvs_notify_recv_pre_block,
 | 
					 | 
				
			||||||
+	.notify_recv_pre_dequeue  = hvs_notify_recv_pre_dequeue,
 | 
					 | 
				
			||||||
+	.notify_recv_post_dequeue = hvs_notify_recv_post_dequeue,
 | 
					 | 
				
			||||||
+	.notify_send_init         = hvs_notify_send_init,
 | 
					 | 
				
			||||||
+	.notify_send_pre_block    = hvs_notify_send_pre_block,
 | 
					 | 
				
			||||||
+	.notify_send_pre_enqueue  = hvs_notify_send_pre_enqueue,
 | 
					 | 
				
			||||||
+	.notify_send_post_enqueue = hvs_notify_send_post_enqueue,
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	.set_buffer_size          = hvs_set_buffer_size,
 | 
					 | 
				
			||||||
+	.set_min_buffer_size      = hvs_set_min_buffer_size,
 | 
					 | 
				
			||||||
+	.set_max_buffer_size      = hvs_set_max_buffer_size,
 | 
					 | 
				
			||||||
+	.get_buffer_size          = hvs_get_buffer_size,
 | 
					 | 
				
			||||||
+	.get_min_buffer_size      = hvs_get_min_buffer_size,
 | 
					 | 
				
			||||||
+	.get_max_buffer_size      = hvs_get_max_buffer_size,
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_probe(struct hv_device *hdev,
 | 
					 | 
				
			||||||
+		     const struct hv_vmbus_device_id *dev_id)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hdev->channel;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs_open_connection(chan);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/* Always return success to suppress the unnecessary error message
 | 
					 | 
				
			||||||
+	 * in vmbus_probe(): on error the host will rescind the device in
 | 
					 | 
				
			||||||
+	 * 30 seconds and we can do cleanup at that time in
 | 
					 | 
				
			||||||
+	 * vmbus_onoffer_rescind().
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int hvs_remove(struct hv_device *hdev)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct vmbus_channel *chan = hdev->channel;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	vmbus_close(chan);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/* This isn't really used. See vmbus_match() and vmbus_probe() */
 | 
					 | 
				
			||||||
+static const struct hv_vmbus_device_id id_table[] = {
 | 
					 | 
				
			||||||
+	{},
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static struct hv_driver hvs_drv = {
 | 
					 | 
				
			||||||
+	.name		= "hv_sock",
 | 
					 | 
				
			||||||
+	.hvsock		= true,
 | 
					 | 
				
			||||||
+	.id_table	= id_table,
 | 
					 | 
				
			||||||
+	.probe		= hvs_probe,
 | 
					 | 
				
			||||||
+	.remove		= hvs_remove,
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static int __init hvs_init(void)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	int ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (vmbus_proto_version < VERSION_WIN10)
 | 
					 | 
				
			||||||
+		return -ENODEV;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = vmbus_driver_register(&hvs_drv);
 | 
					 | 
				
			||||||
+	if (ret != 0)
 | 
					 | 
				
			||||||
+		return ret;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ret = vsock_core_init(&hvs_transport);
 | 
					 | 
				
			||||||
+	if (ret) {
 | 
					 | 
				
			||||||
+		vmbus_driver_unregister(&hvs_drv);
 | 
					 | 
				
			||||||
+		return ret;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+static void __exit hvs_exit(void)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	vsock_core_exit();
 | 
					 | 
				
			||||||
+	vmbus_driver_unregister(&hvs_drv);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+module_init(hvs_init);
 | 
					 | 
				
			||||||
+module_exit(hvs_exit);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+MODULE_DESCRIPTION("Hyper-V sockets");
 | 
					 | 
				
			||||||
+MODULE_VERSION("1.0.0");
 | 
					 | 
				
			||||||
+MODULE_LICENSE("GPL");
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,64 +0,0 @@
 | 
				
			|||||||
From f467ed8a4c51eed215f9f8db32cad8f240a59a2e Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:29 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 7/9] VMCI: only try to load on VMware hypervisor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Without the patch, vmw_vsock_vmci_transport.ko and vmw_vmci.ko can
 | 
					 | 
				
			||||||
automatically load when an application creates an AF_VSOCK socket.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is the expected good behavior on VMware hypervisor, but as we
 | 
					 | 
				
			||||||
are adding hv_sock.ko (i.e. Hyper-V transport for AF_VSOCK), we should
 | 
					 | 
				
			||||||
make sure vmw_vsock_vmci_transport.ko can't load on Hyper-V, otherwise
 | 
					 | 
				
			||||||
there is a -EBUSY conflict when both vmw_vsock_vmci_transport.ko and
 | 
					 | 
				
			||||||
hv_sock.ko try to call vsock_core_init().
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On the other hand, hv_sock.ko can only load on Hyper-V, because it
 | 
					 | 
				
			||||||
depends on hv_vmbus.ko, which deteces Hyper-V in hv_acpi_init().
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
KVM's vsock_virtio_transport doesn't have the issue because it doesn't
 | 
					 | 
				
			||||||
define MODULE_ALIAS_NETPROTO(PF_VSOCK).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Alok Kataria <akataria@vmware.com>
 | 
					 | 
				
			||||||
Cc: Andy King <acking@vmware.com>
 | 
					 | 
				
			||||||
Cc: Adit Ranadive <aditr@vmware.com>
 | 
					 | 
				
			||||||
Cc: George Zhang <georgezhang@vmware.com>
 | 
					 | 
				
			||||||
Cc: Jorgen Hansen <jhansen@vmware.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit b5566b1b6e5cb19b381590587f841f950caabe4d)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/misc/vmw_vmci/vmci_driver.c | 8 ++++++++
 | 
					 | 
				
			||||||
 1 file changed, 8 insertions(+)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c
 | 
					 | 
				
			||||||
index d7eaf1eb11e7..1789ea71ff5d 100644
 | 
					 | 
				
			||||||
--- a/drivers/misc/vmw_vmci/vmci_driver.c
 | 
					 | 
				
			||||||
+++ b/drivers/misc/vmw_vmci/vmci_driver.c
 | 
					 | 
				
			||||||
@@ -19,6 +19,7 @@
 | 
					 | 
				
			||||||
 #include <linux/kernel.h>
 | 
					 | 
				
			||||||
 #include <linux/module.h>
 | 
					 | 
				
			||||||
 #include <linux/init.h>
 | 
					 | 
				
			||||||
+#include <linux/hypervisor.h>
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #include "vmci_driver.h"
 | 
					 | 
				
			||||||
 #include "vmci_event.h"
 | 
					 | 
				
			||||||
@@ -58,6 +59,13 @@ static int __init vmci_drv_init(void)
 | 
					 | 
				
			||||||
 	int vmci_err;
 | 
					 | 
				
			||||||
 	int error;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	/*
 | 
					 | 
				
			||||||
+	 * Check if we are running on VMware's hypervisor and bail out
 | 
					 | 
				
			||||||
+	 * if we are not.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (x86_hyper != &x86_hyper_vmware)
 | 
					 | 
				
			||||||
+		return -ENODEV;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	vmci_err = vmci_event_init();
 | 
					 | 
				
			||||||
 	if (vmci_err < VMCI_SUCCESS) {
 | 
					 | 
				
			||||||
 		pr_err("Failed to initialize VMCIEvent (result=%d)\n",
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,30 +0,0 @@
 | 
				
			|||||||
From 1ee84d4b4cceac4c7f42573476c1253b06e8cdaf Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 5 May 2017 16:57:35 -0600
 | 
					 | 
				
			||||||
Subject: [PATCH 8/9] hv_sock: add the support of auto-loading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
After we disable VMWare virtual sockets driver's auto-loading on Hyper-V,
 | 
					 | 
				
			||||||
we can enable hv_sock's auto-loading now.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Cc: K. Y. Srinivasan <kys@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
 | 
					 | 
				
			||||||
Cc: Stephen Hemminger <sthemmin@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 6f1aa69011356ff95ed6c57400095e5f2d9eb900)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 net/vmw_vsock/hyperv_transport.c | 1 +
 | 
					 | 
				
			||||||
 1 file changed, 1 insertion(+)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
index fd89bf357617..f465b0b662df 100644
 | 
					 | 
				
			||||||
--- a/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
+++ b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
@@ -827,3 +827,4 @@ module_exit(hvs_exit);
 | 
					 | 
				
			||||||
 MODULE_DESCRIPTION("Hyper-V sockets");
 | 
					 | 
				
			||||||
 MODULE_VERSION("1.0.0");
 | 
					 | 
				
			||||||
 MODULE_LICENSE("GPL");
 | 
					 | 
				
			||||||
+MODULE_ALIAS_NETPROTO(PF_VSOCK);
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,113 +0,0 @@
 | 
				
			|||||||
From d0e6020dd2b25f8880b8d25305c356cf4a22f12d Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Tue, 16 May 2017 22:14:03 +0800
 | 
					 | 
				
			||||||
Subject: [PATCH 9/9] hvsock: fix a race in hvs_stream_dequeue()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If hv_pkt_iter_next() returns a non-NULL pointer, we must update
 | 
					 | 
				
			||||||
the recv_data_len/data_off info, otherwise the received data will
 | 
					 | 
				
			||||||
be silently dropped, and let's fix hvs_stream_has_data() accordingly.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Thank Rolf for finding this!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
 | 
					 | 
				
			||||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Origin: https://github.com/dcui/linux/commits/decui/hv_sock/v4.11/20170511
 | 
					 | 
				
			||||||
(cherry picked from commit 83c8635b893bbc0b5b329c632cea0382d5479763)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 net/vmw_vsock/hyperv_transport.c | 50 +++++++++++++++++++++++++++++-----------
 | 
					 | 
				
			||||||
 1 file changed, 36 insertions(+), 14 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
index f465b0b662df..30154836acd0 100644
 | 
					 | 
				
			||||||
--- a/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
+++ b/net/vmw_vsock/hyperv_transport.c
 | 
					 | 
				
			||||||
@@ -476,13 +476,33 @@ static bool hvs_dgram_allow(u32 cid, u32 port)
 | 
					 | 
				
			||||||
 	return false;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+static int hvs_update_recv_data(struct hvsock *hvs)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct hvs_recv_buf *recv_buf;
 | 
					 | 
				
			||||||
+	u32 payload_len;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
+	payload_len = recv_buf->hdr.data_size;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (payload_len > HVS_MTU_SIZE)
 | 
					 | 
				
			||||||
+		return -EIO;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (payload_len == 0)
 | 
					 | 
				
			||||||
+		hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	hvs->recv_data_len = payload_len;
 | 
					 | 
				
			||||||
+	hvs->recv_data_off = 0;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
 | 
					 | 
				
			||||||
 				  size_t len, int flags)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
 	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
 	bool need_refill = !hvs->recv_desc;
 | 
					 | 
				
			||||||
 	struct hvs_recv_buf *recv_buf;
 | 
					 | 
				
			||||||
-	u32 payload_len, to_read;
 | 
					 | 
				
			||||||
+	u32 to_read;
 | 
					 | 
				
			||||||
 	int ret;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	if (flags & MSG_PEEK)
 | 
					 | 
				
			||||||
@@ -490,29 +510,28 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	if (need_refill) {
 | 
					 | 
				
			||||||
 		hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
 | 
					 | 
				
			||||||
-		recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-		payload_len = recv_buf->hdr.data_size;
 | 
					 | 
				
			||||||
-		if (payload_len == 0 || payload_len > HVS_MTU_SIZE)
 | 
					 | 
				
			||||||
-			return -EIO;
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-		hvs->recv_data_len = payload_len;
 | 
					 | 
				
			||||||
-		hvs->recv_data_off = 0;
 | 
					 | 
				
			||||||
-	} else {
 | 
					 | 
				
			||||||
-		recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
+		ret = hvs_update_recv_data(hvs);
 | 
					 | 
				
			||||||
+		if (ret)
 | 
					 | 
				
			||||||
+			return ret;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
 | 
					 | 
				
			||||||
 	to_read = min_t(u32, len, hvs->recv_data_len);
 | 
					 | 
				
			||||||
 	ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read);
 | 
					 | 
				
			||||||
 	if (ret != 0)
 | 
					 | 
				
			||||||
 		return ret;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	hvs->recv_data_len -= to_read;
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	if (hvs->recv_data_len == 0)
 | 
					 | 
				
			||||||
+	if (hvs->recv_data_len == 0) {
 | 
					 | 
				
			||||||
 		hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
 | 
					 | 
				
			||||||
-	else
 | 
					 | 
				
			||||||
+		if (hvs->recv_desc) {
 | 
					 | 
				
			||||||
+			ret = hvs_update_recv_data(hvs);
 | 
					 | 
				
			||||||
+			if (ret)
 | 
					 | 
				
			||||||
+				return ret;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
+	} else {
 | 
					 | 
				
			||||||
 		hvs->recv_data_off += to_read;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	return to_read;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
@@ -554,6 +573,9 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
 | 
					 | 
				
			||||||
 	struct hvsock *hvs = vsk->trans;
 | 
					 | 
				
			||||||
 	s64 ret;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	if (hvs->recv_data_len > 0)
 | 
					 | 
				
			||||||
+		return 1;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	switch (hvs_channel_readable_payload(hvs->chan)) {
 | 
					 | 
				
			||||||
 	case 1:
 | 
					 | 
				
			||||||
 		ret = 1;
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,30 +0,0 @@
 | 
				
			|||||||
From 43b90bff8334b8d4df02f1832df2510ede671bd1 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
 | 
					 | 
				
			||||||
Date: Mon, 23 May 2016 18:55:45 +0100
 | 
					 | 
				
			||||||
Subject: [PATCH 02/10] vmbus: Don't spam the logs with unknown GUIDs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With Hyper-V sockets device types are introduced on the fly. The pr_info()
 | 
					 | 
				
			||||||
then prints a message on every connection, which is way too verbose.  Since
 | 
					 | 
				
			||||||
there doesn't seem to be an easy way to check for registered services,
 | 
					 | 
				
			||||||
disable the pr_info() completely.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/channel_mgmt.c | 1 -
 | 
					 | 
				
			||||||
 1 file changed, 1 deletion(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
index d8bc4b910192..8df02f3ca0b2 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
@@ -192,7 +192,6 @@ static u16 hv_get_dev_type(const struct vmbus_channel *channel)
 | 
					 | 
				
			||||||
 		if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
 | 
					 | 
				
			||||||
 			return i;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
-	pr_info("Unknown GUID: %pUl\n", guid);
 | 
					 | 
				
			||||||
 	return i;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,48 +0,0 @@
 | 
				
			|||||||
From 83b5940282a6afe82fa26fd4cab93e88d705ec86 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Alex Ng <alexng@messages.microsoft.com>
 | 
					 | 
				
			||||||
Date: Sun, 6 Nov 2016 13:14:07 -0800
 | 
					 | 
				
			||||||
Subject: [PATCH 03/10] Drivers: hv: utils: Fix the mapping between host
 | 
					 | 
				
			||||||
 version and protocol to use
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We should intentionally declare the protocols to use for every known host
 | 
					 | 
				
			||||||
and default to using the latest protocol if the host is unknown or new.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Alex Ng <alexng@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 3da0401b4d0e17aea7526db0235d98fa535d903e)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/hv_util.c | 9 ++++++---
 | 
					 | 
				
			||||||
 1 file changed, 6 insertions(+), 3 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
 | 
					 | 
				
			||||||
index bcd06306f3e8..e7707747f56d 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/hv_util.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/hv_util.c
 | 
					 | 
				
			||||||
@@ -389,16 +389,19 @@ static int util_probe(struct hv_device *dev,
 | 
					 | 
				
			||||||
 		ts_srv_version = TS_VERSION_1;
 | 
					 | 
				
			||||||
 		hb_srv_version = HB_VERSION_1;
 | 
					 | 
				
			||||||
 		break;
 | 
					 | 
				
			||||||
-	case(VERSION_WIN10):
 | 
					 | 
				
			||||||
+	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;
 | 
					 | 
				
			||||||
+		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_3;
 | 
					 | 
				
			||||||
+		ts_srv_version = TS_VERSION;
 | 
					 | 
				
			||||||
 		hb_srv_version = HB_VERSION;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,105 +0,0 @@
 | 
				
			|||||||
From b370e69e9fce43cfeec7704adb70adbbc9f81806 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Alex Ng <alexng@messages.microsoft.com>
 | 
					 | 
				
			||||||
Date: Sun, 6 Nov 2016 13:14:10 -0800
 | 
					 | 
				
			||||||
Subject: [PATCH 04/10] Drivers: hv: vss: Improve log messages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Adding log messages to help troubleshoot error cases and transaction
 | 
					 | 
				
			||||||
handling.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Alex Ng <alexng@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 23d2cc0c29eb0e7c6fe4cac88098306c31c40208)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/hv_snapshot.c | 25 +++++++++++++++++++------
 | 
					 | 
				
			||||||
 1 file changed, 19 insertions(+), 6 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
index a76e3db0d01f..b1446d51ef45 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
@@ -121,7 +121,7 @@ static int vss_handle_handshake(struct hv_vss_msg *vss_msg)
 | 
					 | 
				
			||||||
 	default:
 | 
					 | 
				
			||||||
 		return -EINVAL;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
-	pr_debug("VSS: userspace daemon ver. %d connected\n", dm_reg_value);
 | 
					 | 
				
			||||||
+	pr_info("VSS: userspace daemon ver. %d connected\n", dm_reg_value);
 | 
					 | 
				
			||||||
 	return 0;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -129,8 +129,10 @@ static int vss_on_msg(void *msg, int len)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
 	struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	if (len != sizeof(*vss_msg))
 | 
					 | 
				
			||||||
+	if (len != sizeof(*vss_msg)) {
 | 
					 | 
				
			||||||
+		pr_debug("VSS: Message size does not match length\n");
 | 
					 | 
				
			||||||
 		return -EINVAL;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER ||
 | 
					 | 
				
			||||||
 	    vss_msg->vss_hdr.operation == VSS_OP_REGISTER1) {
 | 
					 | 
				
			||||||
@@ -138,8 +140,11 @@ static int vss_on_msg(void *msg, int len)
 | 
					 | 
				
			||||||
 		 * Don't process registration messages if we're in the middle
 | 
					 | 
				
			||||||
 		 * of a transaction processing.
 | 
					 | 
				
			||||||
 		 */
 | 
					 | 
				
			||||||
-		if (vss_transaction.state > HVUTIL_READY)
 | 
					 | 
				
			||||||
+		if (vss_transaction.state > HVUTIL_READY) {
 | 
					 | 
				
			||||||
+			pr_debug("VSS: Got unexpected registration request\n");
 | 
					 | 
				
			||||||
 			return -EINVAL;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 		return vss_handle_handshake(vss_msg);
 | 
					 | 
				
			||||||
 	} else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) {
 | 
					 | 
				
			||||||
 		vss_transaction.state = HVUTIL_USERSPACE_RECV;
 | 
					 | 
				
			||||||
@@ -156,7 +161,7 @@ static int vss_on_msg(void *msg, int len)
 | 
					 | 
				
			||||||
 		}
 | 
					 | 
				
			||||||
 	} else {
 | 
					 | 
				
			||||||
 		/* This is a spurious call! */
 | 
					 | 
				
			||||||
-		pr_warn("VSS: Transaction not active\n");
 | 
					 | 
				
			||||||
+		pr_debug("VSS: Transaction not active\n");
 | 
					 | 
				
			||||||
 		return -EINVAL;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 	return 0;
 | 
					 | 
				
			||||||
@@ -169,8 +174,10 @@ static void vss_send_op(void)
 | 
					 | 
				
			||||||
 	struct hv_vss_msg *vss_msg;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	/* The transaction state is wrong. */
 | 
					 | 
				
			||||||
-	if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
 | 
					 | 
				
			||||||
+	if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED) {
 | 
					 | 
				
			||||||
+		pr_debug("VSS: Unexpected attempt to send to daemon\n");
 | 
					 | 
				
			||||||
 		return;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
 | 
					 | 
				
			||||||
 	if (!vss_msg)
 | 
					 | 
				
			||||||
@@ -211,9 +218,13 @@ static void vss_handle_request(struct work_struct *dummy)
 | 
					 | 
				
			||||||
 	case VSS_OP_HOT_BACKUP:
 | 
					 | 
				
			||||||
 		if (vss_transaction.state < HVUTIL_READY) {
 | 
					 | 
				
			||||||
 			/* Userspace is not registered yet */
 | 
					 | 
				
			||||||
+			pr_debug("VSS: Not ready for request.\n");
 | 
					 | 
				
			||||||
 			vss_respond_to_host(HV_E_FAIL);
 | 
					 | 
				
			||||||
 			return;
 | 
					 | 
				
			||||||
 		}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		pr_debug("VSS: Received request for op code: %d\n",
 | 
					 | 
				
			||||||
+			vss_transaction.msg->vss_hdr.operation);
 | 
					 | 
				
			||||||
 		vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
 | 
					 | 
				
			||||||
 		vss_send_op();
 | 
					 | 
				
			||||||
 		return;
 | 
					 | 
				
			||||||
@@ -356,8 +367,10 @@ hv_vss_init(struct hv_util_service *srv)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
 | 
					 | 
				
			||||||
 				    vss_on_msg, vss_on_reset);
 | 
					 | 
				
			||||||
-	if (!hvt)
 | 
					 | 
				
			||||||
+	if (!hvt) {
 | 
					 | 
				
			||||||
+		pr_warn("VSS: Failed to initialize transport\n");
 | 
					 | 
				
			||||||
 		return -EFAULT;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	return 0;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,48 +0,0 @@
 | 
				
			|||||||
From a33a84158f9f16747d3f6608b7c4e9f1769802e0 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Alex Ng <alexng@messages.microsoft.com>
 | 
					 | 
				
			||||||
Date: Sun, 6 Nov 2016 13:14:11 -0800
 | 
					 | 
				
			||||||
Subject: [PATCH 05/10] Drivers: hv: vss: Operation timeouts should match host
 | 
					 | 
				
			||||||
 expectation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Increase the timeout of backup operations. When system is under I/O load,
 | 
					 | 
				
			||||||
it needs more time to freeze. These timeout values should also match the
 | 
					 | 
				
			||||||
host timeout values more closely.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Alex Ng <alexng@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 b357fd3908c1191f2f56e38aa77f2aecdae18bc8)
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 drivers/hv/hv_snapshot.c | 8 ++++++--
 | 
					 | 
				
			||||||
 1 file changed, 6 insertions(+), 2 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
index b1446d51ef45..4e543dbb731a 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/hv_snapshot.c
 | 
					 | 
				
			||||||
@@ -31,7 +31,10 @@
 | 
					 | 
				
			||||||
 #define VSS_MINOR  0
 | 
					 | 
				
			||||||
 #define VSS_VERSION    (VSS_MAJOR << 16 | VSS_MINOR)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-#define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000))
 | 
					 | 
				
			||||||
+/*
 | 
					 | 
				
			||||||
+ * Timeout values are based on expecations from host
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+#define VSS_FREEZE_TIMEOUT (15 * 60)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 /*
 | 
					 | 
				
			||||||
  * Global state maintained for transaction that is being processed. For a class
 | 
					 | 
				
			||||||
@@ -187,7 +190,8 @@ static void vss_send_op(void)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	vss_transaction.state = HVUTIL_USERSPACE_REQ;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	schedule_delayed_work(&vss_timeout_work, VSS_USERSPACE_TIMEOUT);
 | 
					 | 
				
			||||||
+	schedule_delayed_work(&vss_timeout_work, op == VSS_OP_FREEZE ?
 | 
					 | 
				
			||||||
+			VSS_FREEZE_TIMEOUT * HZ : HV_UTIL_TIMEOUT * HZ);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
 | 
					 | 
				
			||||||
 	if (rc) {
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,492 +0,0 @@
 | 
				
			|||||||
From 18bbea8bb178648186dfcf70f57f6ddfd7ca1151 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 06/10] 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 8df02f3ca0b2..e7949b64bfbc 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
@@ -202,33 +202,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)];
 | 
					 | 
				
			||||||
@@ -244,13 +245,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)
 | 
					 | 
				
			||||||
@@ -258,14 +268,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;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	/*
 | 
					 | 
				
			||||||
@@ -282,6 +304,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 489ad74c1e6e..956acfc93487 100644
 | 
					 | 
				
			||||||
--- a/include/linux/hyperv.h
 | 
					 | 
				
			||||||
+++ b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
@@ -1453,9 +1453,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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,118 +0,0 @@
 | 
				
			|||||||
From 32a6b98612216b754fb89fc3a69b13acdd566eb8 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 07/10] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
From d7c92ad3b3d30f4d790a651070d71fa8a0e5923f Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Sun, 26 Mar 2017 16:42:20 +0800
 | 
					 | 
				
			||||||
Subject: [PATCH 08/10] 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 e7949b64bfbc..2fe024e86209 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
@@ -388,8 +388,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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
From 2e1b50493f08cc2b0c40b02caff57a9b33c25687 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Wed, 29 Mar 2017 18:37:10 +0800
 | 
					 | 
				
			||||||
Subject: [PATCH 09/10] 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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,177 +0,0 @@
 | 
				
			|||||||
From 93a84f69a13df0a695747daccd5c8d95b4880736 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Dexuan Cui <decui@microsoft.com>
 | 
					 | 
				
			||||||
Date: Fri, 24 Mar 2017 20:53:18 +0800
 | 
					 | 
				
			||||||
Subject: [PATCH 10/10] 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 2fe024e86209..b2bdcfb49144 100644
 | 
					 | 
				
			||||||
--- a/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
+++ b/drivers/hv/channel_mgmt.c
 | 
					 | 
				
			||||||
@@ -375,6 +375,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;
 | 
					 | 
				
			||||||
@@ -409,17 +433,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);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -512,18 +525,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
 | 
					 | 
				
			||||||
@@ -572,17 +573,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 956acfc93487..9ee292b28e41 100644
 | 
					 | 
				
			||||||
--- a/include/linux/hyperv.h
 | 
					 | 
				
			||||||
+++ b/include/linux/hyperv.h
 | 
					 | 
				
			||||||
@@ -1461,6 +1461,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.12.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,184 +0,0 @@
 | 
				
			|||||||
<#
 | 
					 | 
				
			||||||
    .SYNOPSIS
 | 
					 | 
				
			||||||
        Manages a LinuxKit VM on Hyper-V
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .DESCRIPTION
 | 
					 | 
				
			||||||
        Creates/Destroys/Starts/Stops a LinuxKit VM.
 | 
					 | 
				
			||||||
        It creates a Gen2 VM which boots EFI ISOs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER VmName
 | 
					 | 
				
			||||||
        If passed, use this name for the LinuxKit VM, otherwise 'LinuxKitVM'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER IsoFile
 | 
					 | 
				
			||||||
        Path to the ISO image to boot from, must be set for Create/ReCreate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER SwitchName
 | 
					 | 
				
			||||||
        Use this switch to connect the VM to
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER Create
 | 
					 | 
				
			||||||
        Create a LinuxKit VM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER Memory
 | 
					 | 
				
			||||||
        Memory allocated for the VM in MB (optional on Create, default: 1024 MB)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER CPUs
 | 
					 | 
				
			||||||
        Number of CPUs to use (optional on Create, default: 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER DiskSize
 | 
					 | 
				
			||||||
        Disk size in MB (optional on Create, default: 0, no disk)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER Destroy
 | 
					 | 
				
			||||||
        Remove a LinuxKit VM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER Start
 | 
					 | 
				
			||||||
        Start an existing LinuxKit VM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .PARAMETER Stop
 | 
					 | 
				
			||||||
        Stop a running LinuxKit VM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .EXAMPLE
 | 
					 | 
				
			||||||
        .\LinuxKit.ps1 -IsoFile .\linuxkit-efi.iso -Create
 | 
					 | 
				
			||||||
        .\LinuxKit.ps1 -Start
 | 
					 | 
				
			||||||
#>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Param(
 | 
					 | 
				
			||||||
    [string] $VmName = "LinuxKitVM",
 | 
					 | 
				
			||||||
    [string] $IsoFile = ".\linuxkit-efi.iso",
 | 
					 | 
				
			||||||
    [string] $SwicthName = ".\linuxkit-efi.iso",
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Create',Mandatory=$false)][switch] $Create,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Create',Mandatory=$false)][int] $CPUs = 1,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Create',Mandatory=$false)][long] $Memory = 1024,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Create',Mandatory=$false)][long] $DiskSize = 0,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Create',Mandatory=$false)][string] $SwitchName = "",
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Remove',Mandatory=$false)][switch] $Remove,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Start',Mandatory=$false)][switch] $Start,
 | 
					 | 
				
			||||||
    [Parameter(ParameterSetName='Stop',Mandatory=$false)][switch] $Stop
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Make sure we stop at Errors unless otherwise explicitly specified
 | 
					 | 
				
			||||||
$ErrorActionPreference = "Stop"
 | 
					 | 
				
			||||||
$ProgressPreference = "SilentlyContinue"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Explicitly disable Module autoloading and explicitly import the
 | 
					 | 
				
			||||||
# Modules this script relies on. This is not strictly necessary but
 | 
					 | 
				
			||||||
# good practise as it prevents arbitrary errors
 | 
					 | 
				
			||||||
$PSModuleAutoloadingPreference = 'None'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Import-Module Microsoft.PowerShell.Utility
 | 
					 | 
				
			||||||
Import-Module Microsoft.PowerShell.Management
 | 
					 | 
				
			||||||
Import-Module Hyper-V
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Get-Vhd-Root {
 | 
					 | 
				
			||||||
    if($VhdPathOverride){
 | 
					 | 
				
			||||||
        return $VhdPathOverride
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    # Default location for VHDs
 | 
					 | 
				
			||||||
    $VhdRoot = "$((Get-VMHost).VirtualHardDiskPath)".TrimEnd("\")
 | 
					 | 
				
			||||||
    return "$VhdRoot\$VmName.vhdx"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Posh thinks that Create is an unapproved verb
 | 
					 | 
				
			||||||
function New-LinuxKitVM {
 | 
					 | 
				
			||||||
    if (!(Test-Path $IsoFile)) {
 | 
					 | 
				
			||||||
        Fatal "ISO file at $IsoFile does not exist"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $CPUs = [Math]::min((Get-VMHost).LogicalProcessorCount, $CPUs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $vm = Get-VM $VmName -ea SilentlyContinue
 | 
					 | 
				
			||||||
    if ($vm) {
 | 
					 | 
				
			||||||
        if ($vm.Length -ne 1) {
 | 
					 | 
				
			||||||
            Fatal "Multiple VMs exist with the name $VmName. Delete invalid ones."
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        Write-Output "Creating VM $VmName..."
 | 
					 | 
				
			||||||
        $vm = New-VM -Name $VmName -Generation 2 -NoVHD
 | 
					 | 
				
			||||||
        $vm | Set-VM -AutomaticStartAction Nothing -AutomaticStopAction ShutDown -CheckpointType Disabled
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($vm.Generation -ne 2) {
 | 
					 | 
				
			||||||
        Fatal "VM $VmName is a Generation $($vm.Generation) VM. It should be a Generation 2."
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($vm.State -ne "Off") {
 | 
					 | 
				
			||||||
        Write-Output "VM $VmName is $($vm.State). Cannot change its settings."
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Write-Output "Setting CPUs to $CPUs and Memory to $Memory MB"
 | 
					 | 
				
			||||||
    $Memory = ([Math]::min($Memory, ($vm | Get-VMMemory).MaximumPerNumaNode))
 | 
					 | 
				
			||||||
    $vm | Set-VM -MemoryStartupBytes ($Memory*1024*1024) -ProcessorCount $CPUs -StaticMemory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($DiskSize -ne 0) {
 | 
					 | 
				
			||||||
        $VmVhdFile = Get-Vhd-Root
 | 
					 | 
				
			||||||
        $vhd = Get-VHD -Path $VmVhdFile -ea SilentlyContinue
 | 
					 | 
				
			||||||
        if (!$vhd) {
 | 
					 | 
				
			||||||
            Write-Output "Creating dynamic VHD: $VmVhdFile"
 | 
					 | 
				
			||||||
            $vhd = New-VHD -Path $VmVhdFile -Dynamic -SizeBytes ($DiskSize*1024*1024)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Write-Output "Attach VHD $VmVhdFile"
 | 
					 | 
				
			||||||
        $vm | Add-VMHardDiskDrive -Path $VmVhdFile
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($SwitchName -ne "") {
 | 
					 | 
				
			||||||
        $vmNetAdapter = $vm | Get-VMNetworkAdapter
 | 
					 | 
				
			||||||
        if (!$vmNetAdapter) {
 | 
					 | 
				
			||||||
            Write-Output "Attach Net Adapter"
 | 
					 | 
				
			||||||
            $vmNetAdapter = $vm | Add-VMNetworkAdapter -Passthru
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Write-Output "Connect to switch $SwicthName"
 | 
					 | 
				
			||||||
        $vmNetAdapter | Connect-VMNetworkAdapter -VMSwitch $(Get-VMSwitch $SwitchName)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Write-Output "Attach DVD $IsoFile"
 | 
					 | 
				
			||||||
    $vm | Add-VMDvdDrive -Path $IsoFile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $iso = $vm | Get-VMFirmware | select -ExpandProperty BootOrder | ? { $_.FirmwarePath.EndsWith("Scsi(0,1)") }
 | 
					 | 
				
			||||||
    $vm | Set-VMFirmware -EnableSecureBoot Off -FirstBootDevice $iso
 | 
					 | 
				
			||||||
    $vm | Set-VMComPort -number 1 -Path "\\.\pipe\$VmName-com1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Write-Output "VM created."
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Remove-LinuxKitVM {
 | 
					 | 
				
			||||||
    Write-Output "Removing VM $VmName..."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Remove-VM $VmName -Force -ea SilentlyContinue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Start-LinuxKitVM {
 | 
					 | 
				
			||||||
    Write-Output "Starting VM $VmName..."
 | 
					 | 
				
			||||||
    Start-VM -VMName $VmName
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Stop-LinuxKitVM {
 | 
					 | 
				
			||||||
    $vm = Get-VM $VmName -ea SilentlyContinue
 | 
					 | 
				
			||||||
    if (!$vm) {
 | 
					 | 
				
			||||||
        Write-Output "VM $VmName does not exist"
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # This is a bit harsh, we poweroff
 | 
					 | 
				
			||||||
    $vm | Stop-VM -Confirm:$false -TurnOff -Force -ea SilentlyContinue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Fatal {
 | 
					 | 
				
			||||||
    throw "$args"
 | 
					 | 
				
			||||||
    Exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Main entry point
 | 
					 | 
				
			||||||
Try {
 | 
					 | 
				
			||||||
    Switch ($PSBoundParameters.GetEnumerator().Where({$_.Value -eq $true}).Key) {
 | 
					 | 
				
			||||||
        'Create'   { New-LinuxKitVM }
 | 
					 | 
				
			||||||
        'Start'    { Start-LinuxKitVM }
 | 
					 | 
				
			||||||
        'Stop'     { Stop-LinuxKitVM }
 | 
					 | 
				
			||||||
        'Remove'   { Stop-LinuxKitVM; Remove-LinuxKitVM }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
} Catch {
 | 
					 | 
				
			||||||
    throw
 | 
					 | 
				
			||||||
    Exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user