summary refs log tree commit diff
path: root/pkgs/os-specific/linux/chromium-os
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/os-specific/linux/chromium-os')
-rw-r--r--pkgs/os-specific/linux/chromium-os/common-mk/0001-common-mk-don-t-leak-source-absolute-paths.patch115
-rw-r--r--pkgs/os-specific/linux/chromium-os/common-mk/0002-common-mk-.gn-don-t-hardcode-env-path.patch8
-rw-r--r--pkgs/os-specific/linux/chromium-os/common-mk/default.nix6
-rw-r--r--pkgs/os-specific/linux/chromium-os/crosvm/Regenerate-Cargo.lock.patch681
-rw-r--r--pkgs/os-specific/linux/chromium-os/crosvm/VIRTIO_NET_F_MAC.patch (renamed from pkgs/os-specific/linux/chromium-os/crosvm/0001-crosvm-support-setting-guest-MAC-from-tap-fd.patch)204
-rw-r--r--pkgs/os-specific/linux/chromium-os/crosvm/default.nix20
-rw-r--r--pkgs/os-specific/linux/chromium-os/sommelier/0003-sommelier-don-t-leak-source-absolute-paths.patch (renamed from pkgs/os-specific/linux/chromium-os/sommelier/0004-sommelier-don-t-leak-source-absolute-paths.patch)10
-rw-r--r--pkgs/os-specific/linux/chromium-os/sommelier/0004-Revert-Revert-vm_tools-sommelier-Switch-to-the-stabl.patch (renamed from pkgs/os-specific/linux/chromium-os/sommelier/0005-sommelier-use-stable-xdg-shell-protocol.patch)981
-rw-r--r--pkgs/os-specific/linux/chromium-os/sommelier/0006-sommelier-make-building-demos-optional.patch100
-rw-r--r--pkgs/os-specific/linux/chromium-os/sommelier/default.nix5
-rw-r--r--pkgs/os-specific/linux/chromium-os/upstream-info.json44
-rw-r--r--pkgs/os-specific/linux/chromium-os/vm_protos/0003-vm_tools-proto-fix-parallel-build.patch39
-rw-r--r--pkgs/os-specific/linux/chromium-os/vm_protos/default.nix2
13 files changed, 1441 insertions, 774 deletions
diff --git a/pkgs/os-specific/linux/chromium-os/common-mk/0001-common-mk-don-t-leak-source-absolute-paths.patch b/pkgs/os-specific/linux/chromium-os/common-mk/0001-common-mk-don-t-leak-source-absolute-paths.patch
index 4b7a2f34779..479cb96eddf 100644
--- a/pkgs/os-specific/linux/chromium-os/common-mk/0001-common-mk-don-t-leak-source-absolute-paths.patch
+++ b/pkgs/os-specific/linux/chromium-os/common-mk/0001-common-mk-don-t-leak-source-absolute-paths.patch
@@ -1,23 +1,25 @@
-From 22f33cfdfacc8c4536a8bf883b4c8b54e30599a3 Mon Sep 17 00:00:00 2001
+From 8b87e0d6ee0e645d1ac2b27c2fba0c97f2929e31 Mon Sep 17 00:00:00 2001
 From: Alyssa Ross <hi@alyssa.is>
 Date: Sun, 24 Nov 2019 16:56:11 +0000
-Subject: [PATCH 1/6] common-mk: don't leak source-absolute paths
+Subject: [PATCH 1/4] common-mk: don't leak source-absolute paths
 
 Source-absolute paths like //vm_tools/whatever were being leaked to
 subprocesses, which of course didn't know how to understand them.
 With this patch, source-absolute paths are only used to tell GN the
 outputs, and normal Unix paths are passed to subprocesses.
 ---
- common-mk/external_dependencies/BUILD.gn |  3 ++-
- common-mk/pkg_config.gni                 |  7 +++----
- common-mk/proto_library.gni              | 21 +++++++++++----------
- 3 files changed, 16 insertions(+), 15 deletions(-)
+ common-mk/external_dependencies/BUILD.gn    |  3 ++-
+ common-mk/mojom_bindings_generator.gni      | 12 ++++++------
+ common-mk/mojom_type_mappings_generator.gni |  2 +-
+ common-mk/pkg_config.gni                    |  5 +++--
+ common-mk/proto_library.gni                 | 21 +++++++++++----------
+ 5 files changed, 23 insertions(+), 20 deletions(-)
 
 diff --git a/common-mk/external_dependencies/BUILD.gn b/common-mk/external_dependencies/BUILD.gn
-index 61f571b38..4cb7b93cf 100644
+index dbf45368ff..94aae4e2e2 100644
 --- a/common-mk/external_dependencies/BUILD.gn
 +++ b/common-mk/external_dependencies/BUILD.gn
-@@ -47,6 +47,7 @@ genxml2cpp("dbus-proxies") {
+@@ -45,6 +45,7 @@ genxml2cpp("dbus-proxies") {
  action("cloud_policy_proto_generator") {
    policy_resources_dir = "${sysroot}/usr/share/policy_resources"
    proto_out_dir = "${target_gen_dir}/proto"
@@ -25,26 +27,91 @@ index 61f571b38..4cb7b93cf 100644
    policy_tools_dir = "${sysroot}/usr/share/policy_tools"
  
    script = "${policy_tools_dir}/generate_policy_source.py"
-@@ -58,7 +59,7 @@ action("cloud_policy_proto_generator") {
-     "${proto_out_dir}/cloud_policy.proto",
+@@ -54,7 +55,7 @@ action("cloud_policy_proto_generator") {
    ]
+   outputs = [ "${proto_out_dir}/cloud_policy.proto" ]
    args = [
 -    "--cloud-policy-protobuf=${proto_out_dir}/cloud_policy.proto",
 +    "--cloud-policy-protobuf=${cloud_policy_protobuf_dir}/cloud_policy.proto",
      "--chrome-version-file=${policy_resources_dir}/VERSION",
      "--target-platform=chromeos",
      "--policy-templates-file=${policy_resources_dir}/policy_templates.json",
+diff --git a/common-mk/mojom_bindings_generator.gni b/common-mk/mojom_bindings_generator.gni
+index 038c20ed36..205d7d3037 100644
+--- a/common-mk/mojom_bindings_generator.gni
++++ b/common-mk/mojom_bindings_generator.gni
+@@ -100,7 +100,7 @@ template("generate_mojom_bindings_gen") {
+     args = [
+       "mkdir",
+       "-p",
+-      mojo_templates_dir,
++      rebase_path(mojo_templates_dir),
+     ]
+   }
+ 
+@@ -116,7 +116,7 @@ template("generate_mojom_bindings_gen") {
+     args = [
+       "--use_bundled_pylibs",
+       "-o",
+-      mojo_templates_dir,
++      rebase_path(mojo_templates_dir),
+       "precompile",
+     ]
+     deps = [ ":${mojo_templates_dir_action_name}" ]
+@@ -143,7 +143,7 @@ template("generate_mojom_bindings_gen") {
+     args = [
+       "--mojom-file-list={{response_file_name}}",
+       "--output-root",
+-      _mojo_output_base,
++      rebase_path(_mojo_output_base),
+       "--input-root",
+       mojo_root,  # Mojo depth.
+       "--input-root",
+@@ -188,11 +188,11 @@ template("generate_mojom_bindings_gen") {
+              mojom_bindings_generator,
+              "--use_bundled_pylibs",
+              "--output_dir",
+-             _mojo_output_base,
++             rebase_path(_mojo_output_base),
+              "generate",
+              "--filelist={{response_file_name}}",
+              "--bytecode_path",
+-             mojo_templates_dir,
++             rebase_path(mojo_templates_dir),
+              "-I",
+              mojo_root,  # Mojo include path.
+              "-d",
+@@ -216,7 +216,7 @@ template("generate_mojom_bindings_gen") {
+       foreach(typemap, invoker.typemaps) {
+         args += [
+           "--typemap",
+-          typemap,
++          rebase_path(typemap),
+         ]
+       }
+     }
+diff --git a/common-mk/mojom_type_mappings_generator.gni b/common-mk/mojom_type_mappings_generator.gni
+index ff09397111..959a8b6ca9 100644
+--- a/common-mk/mojom_type_mappings_generator.gni
++++ b/common-mk/mojom_type_mappings_generator.gni
+@@ -21,7 +21,7 @@ template("generate_mojom_type_mappings") {
+     outputs = [ "$target_gen_dir/${target_name}_typemapping" ]
+     args = [
+              "--output",
+-             "$target_gen_dir/${target_name}_typemapping",
++             rebase_path("$target_gen_dir/${target_name}_typemapping"),
+            ] + rebase_path(sources, root_build_dir)
+   }
+ }
 diff --git a/common-mk/pkg_config.gni b/common-mk/pkg_config.gni
-index af3c3fb4c..151c49e56 100644
+index 24e2cf1401..151c49e560 100644
 --- a/common-mk/pkg_config.gni
 +++ b/common-mk/pkg_config.gni
-@@ -81,12 +81,11 @@ template("generate_pkg_config") {
+@@ -81,10 +81,11 @@ template("generate_pkg_config") {
      if (!defined(output_name)) {
        output_name = name
      }
--    outputs = [
--      "${target_out_dir}/${output_name}.pc",
--    ]
+-    outputs = [ "${target_out_dir}/${output_name}.pc" ]
 +    lib_path = "${target_out_dir}/${output_name}.pc"
 +    outputs = [ lib_path ]
  
@@ -55,7 +122,7 @@ index af3c3fb4c..151c49e56 100644
        args += [ "--description=" + description ]
      }
 diff --git a/common-mk/proto_library.gni b/common-mk/proto_library.gni
-index 7fcb08341..692704288 100644
+index 68b7904acc..2bef5f44ef 100644
 --- a/common-mk/proto_library.gni
 +++ b/common-mk/proto_library.gni
 @@ -56,7 +56,7 @@ template("proto_library") {
@@ -106,7 +173,7 @@ index 7fcb08341..692704288 100644
        outputs += [
          "${cc_dir}/{{source_name_part}}.pb.cc",
          "${cc_dir}/{{source_name_part}}.pb.h",
-@@ -208,7 +207,9 @@ template("goproto_library") {
+@@ -218,7 +217,9 @@ template("goproto_library") {
      # otherwise file descriptor var name will conflict.
      # cf) https://github.com/golang/protobuf/issues/109
  
@@ -116,16 +183,16 @@ index 7fcb08341..692704288 100644
  
      # Build protoc command line to run.
      script = "//common-mk/file_generator_wrapper.py"
-@@ -224,7 +225,7 @@ template("goproto_library") {
-       "--proto_path",
-       "${sysroot}/usr/share/proto",
+@@ -258,7 +259,7 @@ template("goproto_library") {
        "--go_out",
--      "${go_out_prefix}${root_gen_dir}/${proto_out_dir}",
-+      "${go_out_prefix}${proto_out_dir}",
+ 
+       # go_out_prefix can be empty, so we can always add a colon here.
+-      "${go_out_prefix}:${root_gen_dir}/${proto_out_dir}",
++      "${go_out_prefix}:${proto_out_dir}",
      ]
      foreach(source, sources) {
        args += [ rebase_path(source) ]
-@@ -234,7 +235,7 @@ template("goproto_library") {
+@@ -268,7 +269,7 @@ template("goproto_library") {
      outputs = []
      foreach(source, invoker.sources) {
        name = get_path_info(source, "name")
@@ -135,5 +202,5 @@ index 7fcb08341..692704288 100644
    }
  }
 -- 
-2.26.2
+2.30.0
 
diff --git a/pkgs/os-specific/linux/chromium-os/common-mk/0002-common-mk-.gn-don-t-hardcode-env-path.patch b/pkgs/os-specific/linux/chromium-os/common-mk/0002-common-mk-.gn-don-t-hardcode-env-path.patch
index 592002c406f..feac017d253 100644
--- a/pkgs/os-specific/linux/chromium-os/common-mk/0002-common-mk-.gn-don-t-hardcode-env-path.patch
+++ b/pkgs/os-specific/linux/chromium-os/common-mk/0002-common-mk-.gn-don-t-hardcode-env-path.patch
@@ -1,7 +1,7 @@
-From 51ed7b957069bd3765222a466473c696755caa5e Mon Sep 17 00:00:00 2001
+From 1589ff7aa30d61be9ebe4b53a1b8d504b72ff4de Mon Sep 17 00:00:00 2001
 From: Alyssa Ross <hi@alyssa.is>
 Date: Sun, 24 Nov 2019 17:20:46 +0000
-Subject: [PATCH 2/6] common-mk: .gn: don't hardcode env path
+Subject: [PATCH 2/4] common-mk: .gn: don't hardcode env path
 
 This is needlessly non-portable.
 ---
@@ -9,7 +9,7 @@ This is needlessly non-portable.
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/.gn b/.gn
-index e7dba8c91..e29fcd61e 100644
+index e7dba8c91c..e29fcd61ee 100644
 --- a/.gn
 +++ b/.gn
 @@ -7,4 +7,4 @@ root = "//common-mk/gn_root/:"
@@ -19,5 +19,5 @@ index e7dba8c91..e29fcd61e 100644
 -script_executable = "/usr/bin/env"
 +script_executable = "env"
 -- 
-2.26.2
+2.30.0
 
diff --git a/pkgs/os-specific/linux/chromium-os/common-mk/default.nix b/pkgs/os-specific/linux/chromium-os/common-mk/default.nix
index cc72aab5d15..d617401138f 100644
--- a/pkgs/os-specific/linux/chromium-os/common-mk/default.nix
+++ b/pkgs/os-specific/linux/chromium-os/common-mk/default.nix
@@ -64,7 +64,11 @@ stdenv.mkDerivation ({
     patchShebangs common-mk
   '' + (lib.optionalString (!stdenv.cc.isClang) ''
     substituteInPlace common-mk/BUILD.gn \
-        --replace '"-Wno-c99-designator",' ""
+        --replace '"-Wno-c99-designator",' "" \
+        --replace '"-Wstring-compare",' "" \
+        --replace '"-Wstring-plus-int",' "" \
+        --replace '"-Wxor-used-as-pow",' "" \
+        --replace '"-Wunreachable-code-return",' ""
   '') + postPatch;
 
   nativeBuildInputs = [ gn pkgconfig python3 ninja ] ++ nativeBuildInputs;
diff --git a/pkgs/os-specific/linux/chromium-os/crosvm/Regenerate-Cargo.lock.patch b/pkgs/os-specific/linux/chromium-os/crosvm/Regenerate-Cargo.lock.patch
new file mode 100644
index 00000000000..07dbd5469e7
--- /dev/null
+++ b/pkgs/os-specific/linux/chromium-os/crosvm/Regenerate-Cargo.lock.patch
@@ -0,0 +1,681 @@
+From 972ee713ae8e48c3a99fbddca68018e20bb148c7 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Fri, 2 Apr 2021 16:38:28 +0000
+Subject: [PATCH crosvm] Regenerate Cargo.lock
+
+---
+ Cargo.lock | 327 +++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 240 insertions(+), 87 deletions(-)
+
+diff --git a/Cargo.lock b/Cargo.lock
+index 3179b43f5..c82916b06 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -26,7 +26,7 @@ name = "acpi_tables"
+ version = "0.1.0"
+ dependencies = [
+  "data_model",
+- "tempfile",
++ "tempfile 3.0.7",
+ ]
+ 
+ [[package]]
+@@ -61,9 +61,9 @@ version = "0.1.0"
+ 
+ [[package]]
+ name = "async-trait"
+-version = "0.1.36"
++version = "0.1.48"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92"
++checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf"
+ dependencies = [
+  "proc-macro2",
+  "quote",
+@@ -113,9 +113,9 @@ dependencies = [
+ 
+ [[package]]
+ name = "bitflags"
+-version = "1.1.0"
++version = "1.2.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
++checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+ 
+ [[package]]
+ name = "cc"
+@@ -129,6 +129,12 @@ version = "0.1.10"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+ 
++[[package]]
++name = "cfg-if"
++version = "1.0.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
++
+ [[package]]
+ name = "cras-sys"
+ version = "0.1.0"
+@@ -189,7 +195,7 @@ dependencies = [
+  "resources",
+  "rutabaga_gfx",
+  "sync",
+- "tempfile",
++ "tempfile 3.2.0",
+  "thiserror",
+  "vhost",
+  "vm_control",
+@@ -262,7 +268,7 @@ dependencies = [
+  "rutabaga_gfx",
+  "sync",
+  "syscall_defines",
+- "tempfile",
++ "tempfile 3.0.7",
+  "tpm2",
+  "usb_util",
+  "vfio_sys",
+@@ -285,7 +291,7 @@ dependencies = [
+  "protobuf",
+  "protos",
+  "remain",
+- "tempfile",
++ "tempfile 3.2.0",
+  "vm_memory",
+ ]
+ 
+@@ -295,6 +301,12 @@ version = "1.2.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
+ 
++[[package]]
++name = "either"
++version = "1.6.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
++
+ [[package]]
+ name = "enumn"
+ version = "0.1.0"
+@@ -318,9 +330,9 @@ dependencies = [
+ 
+ [[package]]
+ name = "futures"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987"
++checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
+ dependencies = [
+  "futures-channel",
+  "futures-core",
+@@ -333,9 +345,9 @@ dependencies = [
+ 
+ [[package]]
+ name = "futures-channel"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86"
++checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
+ dependencies = [
+  "futures-core",
+  "futures-sink",
+@@ -343,15 +355,15 @@ dependencies = [
+ 
+ [[package]]
+ name = "futures-core"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866"
++checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
+ 
+ [[package]]
+ name = "futures-executor"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231"
++checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
+ dependencies = [
+  "futures-core",
+  "futures-task",
+@@ -360,15 +372,15 @@ dependencies = [
+ 
+ [[package]]
+ name = "futures-io"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff"
++checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
+ 
+ [[package]]
+ name = "futures-macro"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764"
++checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
+ dependencies = [
+  "proc-macro-hack",
+  "proc-macro2",
+@@ -378,21 +390,21 @@ dependencies = [
+ 
+ [[package]]
+ name = "futures-sink"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16"
++checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
+ 
+ [[package]]
+ name = "futures-task"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9"
++checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
+ 
+ [[package]]
+ name = "futures-util"
+-version = "0.3.1"
++version = "0.3.13"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
++checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
+ dependencies = [
+  "futures-channel",
+  "futures-core",
+@@ -401,6 +413,7 @@ dependencies = [
+  "futures-sink",
+  "futures-task",
+  "memchr",
++ "pin-project-lite",
+  "pin-utils",
+  "proc-macro-hack",
+  "proc-macro-nested",
+@@ -409,11 +422,11 @@ dependencies = [
+ 
+ [[package]]
+ name = "gdbstub"
+-version = "0.4.0"
++version = "0.4.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "347c27d24b8ac4a2bcad3ff3d0695271a0510c020bd8134b53d189e973ed58bf"
++checksum = "d79a8fc10e9c4a4009deacc1d1e632cc2860c63c5169abc737f838e07534ab1a"
+ dependencies = [
+- "cfg-if",
++ "cfg-if 0.1.10",
+  "log",
+  "managed",
+  "num-traits",
+@@ -422,13 +435,24 @@ dependencies = [
+ 
+ [[package]]
+ name = "getopts"
+-version = "0.2.18"
++version = "0.2.21"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
++checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
+ dependencies = [
+  "unicode-width",
+ ]
+ 
++[[package]]
++name = "getrandom"
++version = "0.2.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
++dependencies = [
++ "cfg-if 1.0.0",
++ "libc",
++ "wasi",
++]
++
+ [[package]]
+ name = "gpu_buffer"
+ version = "0.1.0"
+@@ -448,6 +472,15 @@ dependencies = [
+  "linux_input_sys",
+ ]
+ 
++[[package]]
++name = "hermit-abi"
++version = "0.1.18"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
++dependencies = [
++ "libc",
++]
++
+ [[package]]
+ name = "hypervisor"
+ version = "0.1.0"
+@@ -496,7 +529,7 @@ version = "0.1.0"
+ dependencies = [
+  "base",
+  "libc",
+- "tempfile",
++ "tempfile 3.2.0",
+  "vm_memory",
+ ]
+ 
+@@ -524,9 +557,9 @@ dependencies = [
+ 
+ [[package]]
+ name = "libc"
+-version = "0.2.65"
++version = "0.2.92"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
++checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714"
+ 
+ [[package]]
+ name = "libchromeos"
+@@ -538,6 +571,7 @@ dependencies = [
+  "libc",
+  "log",
+  "protobuf",
++ "thiserror",
+ ]
+ 
+ [[package]]
+@@ -580,11 +614,11 @@ dependencies = [
+ 
+ [[package]]
+ name = "log"
+-version = "0.4.5"
++version = "0.4.14"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
++checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+ dependencies = [
+- "cfg-if",
++ "cfg-if 1.0.0",
+ ]
+ 
+ [[package]]
+@@ -595,9 +629,9 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
+ 
+ [[package]]
+ name = "memchr"
+-version = "2.3.0"
++version = "2.3.4"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
++checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+ 
+ [[package]]
+ name = "memoffset"
+@@ -666,19 +700,20 @@ dependencies = [
+ 
+ [[package]]
+ name = "num-traits"
+-version = "0.2.12"
++version = "0.2.14"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
++checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+ dependencies = [
+  "autocfg",
+ ]
+ 
+ [[package]]
+ name = "num_cpus"
+-version = "1.9.0"
++version = "1.13.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
++checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+ dependencies = [
++ "hermit-abi",
+  "libc",
+ ]
+ 
+@@ -693,21 +728,27 @@ dependencies = [
+ 
+ [[package]]
+ name = "paste"
+-version = "1.0.2"
++version = "1.0.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "ba7ae1a2180ed02ddfdb5ab70c70d596a26dd642e097bb6fe78b1bde8588ed97"
++checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
++
++[[package]]
++name = "pin-project-lite"
++version = "0.2.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
+ 
+ [[package]]
+ name = "pin-utils"
+-version = "0.1.0-alpha.4"
++version = "0.1.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
++checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+ 
+ [[package]]
+ name = "pkg-config"
+-version = "0.3.11"
++version = "0.3.19"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
++checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+ 
+ [[package]]
+ name = "poll_token_derive"
+@@ -729,65 +770,67 @@ dependencies = [
+ ]
+ 
+ [[package]]
+-name = "proc-macro-hack"
+-version = "0.5.11"
++name = "ppv-lite86"
++version = "0.2.10"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
+-dependencies = [
+- "proc-macro2",
+- "quote",
+- "syn",
+-]
++checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
++
++[[package]]
++name = "proc-macro-hack"
++version = "0.5.19"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+ 
+ [[package]]
+ name = "proc-macro-nested"
+-version = "0.1.3"
++version = "0.1.7"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
++checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
+ 
+ [[package]]
+ name = "proc-macro2"
+-version = "1.0.8"
++version = "1.0.26"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
++checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
+ dependencies = [
+  "unicode-xid",
+ ]
+ 
+ [[package]]
+ name = "protobuf"
+-version = "2.8.1"
++version = "2.22.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20"
++checksum = "1b7f4a129bb3754c25a4e04032a90173c68f85168f77118ac4cb4936e7f06f92"
+ 
+ [[package]]
+ name = "protobuf-codegen"
+-version = "2.8.1"
++version = "2.22.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "12c6abd78435445fc86898ebbd0521a68438063d4a73e23527b7134e6bf58b4a"
++checksum = "e5d2fa3a461857508103b914da60dd7b489c1a834967c2e214ecc1496f0c486a"
+ dependencies = [
+  "protobuf",
+ ]
+ 
+ [[package]]
+ name = "protoc"
+-version = "2.8.1"
++version = "2.22.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3998c4bc0af8ccbd3cc68245ee9f72663c5ae2fb78bc48ff7719aef11562edea"
++checksum = "e6653d384a260fedff0a466e894e05c5b8d75e261a14e9f93e81e43ef86cad23"
+ dependencies = [
+  "log",
++ "which",
+ ]
+ 
+ [[package]]
+ name = "protoc-rust"
+-version = "2.8.1"
++version = "2.22.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "234c97039c32bb58a883d0deafa57db37e59428ce536f3bdfe1c46cffec04113"
++checksum = "e5198afa8fca3f419b36db9a70ede51ff845938ef0386b49f4b02a5a322015a6"
+ dependencies = [
+  "protobuf",
+  "protobuf-codegen",
+  "protoc",
+- "tempfile",
++ "tempfile 3.2.0",
+ ]
+ 
+ [[package]]
+@@ -811,28 +854,86 @@ dependencies = [
+ 
+ [[package]]
+ name = "quote"
+-version = "1.0.2"
++version = "1.0.9"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
++checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+ dependencies = [
+  "proc-macro2",
+ ]
+ 
++[[package]]
++name = "rand"
++version = "0.8.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
++dependencies = [
++ "libc",
++ "rand_chacha",
++ "rand_core",
++ "rand_hc",
++]
++
++[[package]]
++name = "rand_chacha"
++version = "0.3.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
++dependencies = [
++ "ppv-lite86",
++ "rand_core",
++]
++
++[[package]]
++name = "rand_core"
++version = "0.6.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
++dependencies = [
++ "getrandom",
++]
++
++[[package]]
++name = "rand_hc"
++version = "0.3.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
++dependencies = [
++ "rand_core",
++]
++
+ [[package]]
+ name = "rand_ish"
+ version = "0.1.0"
+ 
+ [[package]]
+-name = "remain"
+-version = "0.2.1"
++name = "redox_syscall"
++version = "0.2.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "99c861227fc40c8da6fdaa3d58144ac84c0537080a43eb1d7d45c28f88dcb888"
++checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
++dependencies = [
++ "bitflags",
++]
++
++[[package]]
++name = "remain"
++version = "0.2.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
+ dependencies = [
+  "proc-macro2",
+  "quote",
+  "syn",
+ ]
+ 
++[[package]]
++name = "remove_dir_all"
++version = "0.5.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
++dependencies = [
++ "winapi",
++]
++
+ [[package]]
+ name = "resources"
+ version = "0.1.0"
+@@ -860,9 +961,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+ 
+ [[package]]
+ name = "syn"
+-version = "1.0.14"
++version = "1.0.68"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
++checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87"
+ dependencies = [
+  "proc-macro2",
+  "quote",
+@@ -883,7 +984,7 @@ dependencies = [
+  "poll_token_derive",
+  "sync",
+  "syscall_defines",
+- "tempfile",
++ "tempfile 3.0.7",
+ ]
+ 
+ [[package]]
+@@ -898,19 +999,33 @@ dependencies = [
+ ]
+ 
+ [[package]]
+-name = "thiserror"
+-version = "1.0.20"
++name = "tempfile"
++version = "3.2.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
++checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
++dependencies = [
++ "cfg-if 1.0.0",
++ "libc",
++ "rand",
++ "redox_syscall",
++ "remove_dir_all",
++ "winapi",
++]
++
++[[package]]
++name = "thiserror"
++version = "1.0.24"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
+ dependencies = [
+  "thiserror-impl",
+ ]
+ 
+ [[package]]
+ name = "thiserror-impl"
+-version = "1.0.20"
++version = "1.0.24"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
++checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
+ dependencies = [
+  "proc-macro2",
+  "quote",
+@@ -934,15 +1049,15 @@ dependencies = [
+ 
+ [[package]]
+ name = "unicode-width"
+-version = "0.1.5"
++version = "0.1.8"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
++checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+ 
+ [[package]]
+ name = "unicode-xid"
+-version = "0.2.0"
++version = "0.2.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
++checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+ 
+ [[package]]
+ name = "usb_sys"
+@@ -1015,6 +1130,44 @@ dependencies = [
+  "syscall_defines",
+ ]
+ 
++[[package]]
++name = "wasi"
++version = "0.10.2+wasi-snapshot-preview1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
++
++[[package]]
++name = "which"
++version = "4.1.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
++dependencies = [
++ "either",
++ "libc",
++]
++
++[[package]]
++name = "winapi"
++version = "0.3.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
++dependencies = [
++ "winapi-i686-pc-windows-gnu",
++ "winapi-x86_64-pc-windows-gnu",
++]
++
++[[package]]
++name = "winapi-i686-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
++
++[[package]]
++name = "winapi-x86_64-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
++
+ [[package]]
+ name = "wire_format_derive"
+ version = "0.1.0"
+-- 
+2.30.0
+
diff --git a/pkgs/os-specific/linux/chromium-os/crosvm/0001-crosvm-support-setting-guest-MAC-from-tap-fd.patch b/pkgs/os-specific/linux/chromium-os/crosvm/VIRTIO_NET_F_MAC.patch
index f257796f52a..7f79cb90c18 100644
--- a/pkgs/os-specific/linux/chromium-os/crosvm/0001-crosvm-support-setting-guest-MAC-from-tap-fd.patch
+++ b/pkgs/os-specific/linux/chromium-os/crosvm/VIRTIO_NET_F_MAC.patch
@@ -1,7 +1,7 @@
-From 2db1db4e42e87f05e414384a0c09be340e81d94d Mon Sep 17 00:00:00 2001
+From 655988f0b66ccf22ce197024d6eb2682f3bbada8 Mon Sep 17 00:00:00 2001
 From: Alyssa Ross <hi@alyssa.is>
 Date: Sun, 27 Sep 2020 15:34:02 +0000
-Subject: [PATCH] crosvm: support setting guest MAC from tap-fd
+Subject: [PATCH crosvm v2] crosvm: support setting guest MAC from tap-fd
 
 This adds a mac= option to crosvm's --tap-fd option.  The virtio-net
 driver in the guest will read the desired MAC from virtio
@@ -12,110 +12,76 @@ See the documentation for VIRTIO_NET_F_MAC in the Virtio spec[1].
 [1]: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.html
 
 Thanks-to: Puck Meerburg <puck@puckipedia.com>
-Message-Id: <20210409222026.13886-1-hi@alyssa.is>
 Reviewed-by: Cole Helbling <cole.e.helbling@outlook.com>
-
+Message-Id: <20210517185700.3591932-1-hi@alyssa.is>
 ---
- devices/src/virtio/net.rs | 31 ++++++++++++++++---
+ devices/src/virtio/net.rs | 12 ++++++--
  src/crosvm.rs             |  8 +++--
- src/linux.rs              | 20 +++++++-----
- src/main.rs               | 64 ++++++++++++++++++++++++++++++---------
- 4 files changed, 96 insertions(+), 27 deletions(-)
+ src/linux.rs              | 12 ++++----
+ src/main.rs               | 63 ++++++++++++++++++++++++++++++---------
+ 4 files changed, 71 insertions(+), 24 deletions(-)
 
 diff --git a/devices/src/virtio/net.rs b/devices/src/virtio/net.rs
-index 44a39abd..fe71371f 100644
+index 92368c440..4d0ea1560 100644
 --- a/devices/src/virtio/net.rs
 +++ b/devices/src/virtio/net.rs
-@@ -22,7 +22,9 @@ use virtio_sys::virtio_net::{
- };
- use virtio_sys::{vhost, virtio_net};
- 
--use super::{DescriptorError, Interrupt, Queue, Reader, VirtioDevice, Writer, TYPE_NET};
-+use super::{
-+    copy_config, DescriptorError, Interrupt, Queue, Reader, VirtioDevice, Writer, TYPE_NET,
-+};
- 
- const QUEUE_SIZE: u16 = 256;
- const NUM_QUEUES: usize = 3;
-@@ -373,7 +375,13 @@ where
-     }
+@@ -419,6 +419,7 @@ where
  }
  
-+#[derive(Default)]
-+pub struct NetOptions {
-+    pub guest_mac: Option<net_util::MacAddress>,
-+}
-+
  pub struct Net<T: TapT> {
-+    config: Vec<u8>,
-     workers_kill_evt: Option<EventFd>,
-     kill_evt: EventFd,
-     worker_thread: Option<thread::JoinHandle<Worker<T>>>,
-@@ -392,6 +400,7 @@ where
++    mac_address: Option<MacAddress>,
+     queue_sizes: Box<[u16]>,
+     workers_kill_evt: Vec<Event>,
+     kill_evts: Vec<Event>,
+@@ -439,6 +440,7 @@ where
          ip_addr: Ipv4Addr,
          netmask: Ipv4Addr,
          mac_addr: MacAddress,
-+        options: NetOptions,
++        guest_mac_addr: Option<MacAddress>,
+         vq_pairs: u16,
      ) -> Result<Net<T>, NetError> {
-         let tap: T = T::new(true).map_err(NetError::TapOpen)?;
-         tap.set_ip_addr(ip_addr).map_err(NetError::TapSetIp)?;
-@@ -401,18 +410,18 @@ where
+         let multi_queue = if vq_pairs > 1 { true } else { false };
+@@ -450,12 +452,12 @@ where
  
          tap.enable().map_err(NetError::TapEnable)?;
  
--        Net::from(tap)
-+        Net::with_tap(tap, options)
+-        Net::from(base_features, tap, vq_pairs)
++        Net::with_tap(base_features, tap, vq_pairs, guest_mac_addr)
      }
  
      /// Creates a new virtio network device from a tap device that has already been
      /// configured.
--    pub fn from(tap: T) -> Result<Net<T>, NetError> {
-+    pub fn with_tap(tap: T, options: NetOptions) -> Result<Net<T>, NetError> {
-         // This would also validate a tap created by Self::new(), but that's a good thing as it
-         // would ensure that any changes in the creation procedure are matched in the validation.
-         // Plus we still need to set the offload and vnet_hdr_size values.
-         validate_and_configure_tap(&tap)?;
+-    pub fn from(base_features: u64, tap: T, vq_pairs: u16) -> Result<Net<T>, NetError> {
++    pub fn with_tap(base_features: u64, tap: T, vq_pairs: u16, mac_address: Option<MacAddress>) -> Result<Net<T>, NetError> {
+         let taps = tap.into_mq_taps(vq_pairs).map_err(NetError::TapOpen)?;
  
--        let avail_features = 1 << virtio_net::VIRTIO_NET_F_GUEST_CSUM
-+        let mut avail_features = 1 << virtio_net::VIRTIO_NET_F_GUEST_CSUM
-             | 1 << virtio_net::VIRTIO_NET_F_CSUM
-             | 1 << virtio_net::VIRTIO_NET_F_CTRL_VQ
-             | 1 << virtio_net::VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
-@@ -422,8 +431,18 @@ where
-             | 1 << virtio_net::VIRTIO_NET_F_HOST_UFO
-             | 1 << vhost::VIRTIO_F_VERSION_1;
+         // This would also validate a tap created by Self::new(), but that's a good thing as it
+@@ -488,7 +490,12 @@ where
+             workers_kill_evt.push(worker_kill_evt);
+         }
  
-+        if options.guest_mac.is_some() {
++        if mac_address.is_some() {
 +            avail_features |= 1 << virtio_net::VIRTIO_NET_F_MAC;
 +        }
 +
-+        let config = options
-+            .guest_mac
-+            .map(|mac| mac.octets().to_vec())
-+            .unwrap_or_default();
-+
-         let kill_evt = EventFd::new().map_err(NetError::CreateKillEventFd)?;
          Ok(Net {
-+            config,
-             workers_kill_evt: Some(kill_evt.try_clone().map_err(NetError::CloneKillEventFd)?),
-             kill_evt,
-             worker_thread: None,
-@@ -545,6 +564,10 @@ where
-         }
-     }
- 
-+    fn read_config(&self, offset: u64, data: &mut [u8]) {
-+        copy_config(data, 0, self.config.as_slice(), offset);
-+    }
-+
-     fn activate(
-         &mut self,
-         mem: GuestMemory,
++            mac_address,
+             queue_sizes: vec![QUEUE_SIZE; (vq_pairs * 2 + 1) as usize].into_boxed_slice(),
+             workers_kill_evt,
+             kill_evts,
+@@ -503,6 +510,7 @@ where
+         let vq_pairs = self.queue_sizes.len() as u16 / 2;
+ 
+         VirtioNetConfig {
++            mac: self.mac_address.map(|m| m.octets()).unwrap_or_else(Default::default),
+             max_vq_pairs: Le16::from(vq_pairs),
+             // Other field has meaningful value when the corresponding feature
+             // is enabled, but all these features aren't supported now.
 diff --git a/src/crosvm.rs b/src/crosvm.rs
-index 81344c32..e69f2dfc 100644
+index 04e267d6c..1dde7d769 100644
 --- a/src/crosvm.rs
 +++ b/src/crosvm.rs
-@@ -157,6 +157,10 @@ impl Default for SharedDir {
+@@ -171,6 +171,10 @@ impl Default for SharedDir {
      }
  }
  
@@ -125,19 +91,19 @@ index 81344c32..e69f2dfc 100644
 +
  /// Aggregate of all configurable options for a running VM.
  pub struct Config {
-     pub vcpu_count: Option<u32>,
-@@ -177,7 +181,7 @@ pub struct Config {
-     pub netmask: Option<net::Ipv4Addr>,
+     pub vcpu_count: Option<usize>,
+@@ -194,7 +198,7 @@ pub struct Config {
      pub mac_address: Option<net_util::MacAddress>,
+     pub net_vq_pairs: Option<u16>,
      pub vhost_net: bool,
 -    pub tap_fd: Vec<RawFd>,
 +    pub tap_fd: BTreeMap<RawFd, TapFdOptions>,
      pub cid: Option<u64>,
      pub wayland_socket_paths: BTreeMap<String, PathBuf>,
      pub wayland_dmabuf: bool,
-@@ -224,7 +228,7 @@ impl Default for Config {
-             netmask: None,
+@@ -253,7 +257,7 @@ impl Default for Config {
              mac_address: None,
+             net_vq_pairs: None,
              vhost_net: false,
 -            tap_fd: Vec::new(),
 +            tap_fd: BTreeMap::new(),
@@ -145,53 +111,46 @@ index 81344c32..e69f2dfc 100644
              #[cfg(feature = "gpu")]
              gpu_parameters: None,
 diff --git a/src/linux.rs b/src/linux.rs
-index 3370c1e1..f7f78ad2 100644
+index f452fef3f..42c07df4f 100644
 --- a/src/linux.rs
 +++ b/src/linux.rs
-@@ -60,7 +60,9 @@ use vm_control::{
-     VmMemoryRequest, VmMemoryResponse, VmRunMode,
- };
+@@ -75,7 +75,7 @@ use vm_memory::{GuestAddress, GuestMemory};
  
+ #[cfg(all(target_arch = "x86_64", feature = "gdb"))]
+ use crate::gdb::{gdb_thread, GdbStub};
 -use crate::{Config, DiskOption, Executable, SharedDir, SharedDirKind, TouchDeviceOption};
-+use crate::{
-+    Config, DiskOption, Executable, SharedDir, SharedDirKind, TapFdOptions, TouchDeviceOption,
-+};
- use arch::{self, LinuxArch, RunnableLinuxVm, VirtioDeviceStub, VmComponents, VmImage};
- 
- #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
-@@ -586,14 +588,18 @@ fn create_balloon_device(cfg: &Config, socket: BalloonControlResponseSocket) ->
++use crate::{Config, DiskOption, Executable, SharedDir, SharedDirKind, TapFdOptions, TouchDeviceOption};
+ use arch::{
+     self, LinuxArch, RunnableLinuxVm, SerialHardware, SerialParameters, VcpuAffinity,
+     VirtioDeviceStub, VmComponents, VmImage,
+@@ -675,7 +675,7 @@ fn create_balloon_device(cfg: &Config, socket: BalloonControlResponseSocket) ->
      })
  }
  
--fn create_tap_net_device(cfg: &Config, tap_fd: RawFd) -> DeviceResult {
-+fn create_tap_net_device(cfg: &Config, tap_fd: RawFd, options: &TapFdOptions) -> DeviceResult {
+-fn create_tap_net_device(cfg: &Config, tap_fd: RawDescriptor) -> DeviceResult {
++fn create_tap_net_device(cfg: &Config, tap_fd: RawDescriptor, options: &TapFdOptions) -> DeviceResult {
      // Safe because we ensure that we get a unique handle to the fd.
      let tap = unsafe {
-         Tap::from_raw_fd(validate_raw_fd(tap_fd).map_err(Error::ValidateRawFd)?)
-             .map_err(Error::CreateTapDevice)?
-     };
- 
--    let dev = virtio::Net::from(tap).map_err(Error::NetDeviceNew)?;
-+    let net_opts = virtio::NetOptions {
-+        guest_mac: options.mac,
-+    };
-+
-+    let dev = virtio::Net::with_tap(tap, net_opts).map_err(Error::NetDeviceNew)?;
+         Tap::from_raw_descriptor(
+@@ -691,7 +691,7 @@ fn create_tap_net_device(cfg: &Config, tap_fd: RawDescriptor) -> DeviceResult {
+         vq_pairs = 1;
+     }
+     let features = virtio::base_features(cfg.protected_vm);
+-    let dev = virtio::Net::from(features, tap, vq_pairs).map_err(Error::NetDeviceNew)?;
++    let dev = virtio::Net::with_tap(features, tap, vq_pairs, options.mac).map_err(Error::NetDeviceNew)?;
  
      Ok(VirtioDeviceStub {
          dev: Box::new(dev),
-@@ -614,8 +620,8 @@ fn create_net_device(
-                 .map_err(Error::VhostNetDeviceNew)?;
+@@ -725,7 +725,7 @@ fn create_net_device(
+         .map_err(Error::VhostNetDeviceNew)?;
          Box::new(dev) as Box<dyn VirtioDevice>
      } else {
--        let dev =
--            virtio::Net::<Tap>::new(host_ip, netmask, mac_address).map_err(Error::NetDeviceNew)?;
-+        let dev = virtio::Net::<Tap>::new(host_ip, netmask, mac_address, Default::default())
-+            .map_err(Error::NetDeviceNew)?;
+-        let dev = virtio::Net::<Tap>::new(features, host_ip, netmask, mac_address, vq_pairs)
++        let dev = virtio::Net::<Tap>::new(features, host_ip, netmask, mac_address, None, vq_pairs)
+             .map_err(Error::NetDeviceNew)?;
          Box::new(dev) as Box<dyn VirtioDevice>
      };
- 
-@@ -1006,8 +1012,8 @@ fn create_virtio_devices(
+@@ -1311,8 +1311,8 @@ fn create_virtio_devices(
      devs.push(create_balloon_device(cfg, balloon_device_socket)?);
  
      // We checked above that if the IP is defined, then the netmask is, too.
@@ -203,20 +162,19 @@ index 3370c1e1..f7f78ad2 100644
  
      if let (Some(host_ip), Some(netmask), Some(mac_address)) =
 diff --git a/src/main.rs b/src/main.rs
-index 3afca8e0..053af465 100644
+index 5d02af02f..f8bc0d14e 100644
 --- a/src/main.rs
 +++ b/src/main.rs
-@@ -21,7 +21,8 @@ use arch::Pstore;
- use audio_streams::StreamEffect;
+@@ -28,7 +28,7 @@ use base::{
+ };
  use crosvm::{
      argument::{self, print_help, set_arguments, Argument},
--    linux, BindMount, Config, DiskOption, Executable, GidMap, SharedDir, TouchDeviceOption,
-+    linux, BindMount, Config, DiskOption, Executable, GidMap, SharedDir, TapFdOptions,
-+    TouchDeviceOption,
+-    platform, BindMount, Config, DiskOption, Executable, GidMap, SharedDir, TouchDeviceOption,
++    platform, BindMount, Config, DiskOption, Executable, GidMap, SharedDir, TapFdOptions, TouchDeviceOption,
+     DISK_ID_LEN,
  };
  #[cfg(feature = "gpu")]
- use devices::virtio::gpu::{GpuMode, GpuParameters};
-@@ -1041,17 +1042,52 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
+@@ -1319,17 +1319,52 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
          }
          "vhost-net" => cfg.vhost_net = true,
          "tap-fd" => {
@@ -233,7 +191,7 @@ index 3afca8e0..053af465 100644
 -            );
 +            let mut components = value.unwrap().split(',');
 +
-+            let fd: RawFd = components
++            let fd: RawDescriptor = components
 +                .next()
 +                .and_then(|x| x.parse().ok())
 +                .ok_or_else(|| argument::Error::InvalidValue {
@@ -280,7 +238,7 @@ index 3afca8e0..053af465 100644
          }
          #[cfg(feature = "gpu")]
          "gpu" => {
-@@ -1295,8 +1331,8 @@ writeback=BOOL - Indicates whether the VM can use writeback caching (default: fa
+@@ -1644,8 +1679,8 @@ writeback=BOOL - Indicates whether the VM can use writeback caching (default: fa
            Argument::value("plugin-gid-map-file", "PATH", "Path to the file listing supplemental GIDs that should be mapped in plugin jail.  Can be given more than once."),
            Argument::flag("vhost-net", "Use vhost for networking."),
            Argument::value("tap-fd",
@@ -292,5 +250,5 @@ index 3afca8e0..053af465 100644
            Argument::flag_or_value("gpu",
                                    "[width=INT,height=INT]",
 -- 
-2.27.0
+2.31.1
 
diff --git a/pkgs/os-specific/linux/chromium-os/crosvm/default.nix b/pkgs/os-specific/linux/chromium-os/crosvm/default.nix
index d54c050d308..681526356ea 100644
--- a/pkgs/os-specific/linux/chromium-os/crosvm/default.nix
+++ b/pkgs/os-specific/linux/chromium-os/crosvm/default.nix
@@ -1,5 +1,6 @@
 { stdenv, lib, rustPlatform, fetchFromGitiles, upstreamInfo
-, pkgconfig, minijail, dtc, libusb1, libcap, linux
+, pkgconfig, minigbm, minijail, wayland, wayland-protocols, dtc, libusb1, libcap
+, linux
 }:
 
 let
@@ -13,6 +14,7 @@ let
     "src/platform/crosvm"
     "src/third_party/adhd"
     "src/aosp/external/minijail"
+    "src/platform2"
   ] getSrc;
 in
 
@@ -37,20 +39,25 @@ in
 
     sourceRoot = "src/platform/crosvm";
 
+    cargoPatches = [ ./Regenerate-Cargo.lock.patch ];
+
     patches = [
       ./default-seccomp-policy-dir.diff
-      ./0001-crosvm-support-setting-guest-MAC-from-tap-fd.patch
+      ./VIRTIO_NET_F_MAC.patch
     ];
 
-    cargoSha256 = "0wzqn2n4vyv3bk39079yg1zbnriagi5xns928bzdqmq9djdcj21i";
+    cargoSha256 = "0rrhgchrf6ac5393rxlkff0kd3xs7xixxshcdpag3lxjgg0j62af";
 
-    nativeBuildInputs = [ pkgconfig ];
+    nativeBuildInputs = [ pkgconfig wayland ];
 
-    buildInputs = [ dtc libcap libusb1 minijail ];
+    buildInputs = [ dtc libcap libusb1 minigbm minijail wayland wayland-protocols ];
 
     postPatch = ''
       sed -i "s|/usr/share/policy/crosvm/|$out/share/policy/|g" \
              seccomp/*/*.policy
+
+      # No /dev/log in the sandbox.
+      sed -i '/^[[:space:]]*syslog::init().unwrap();$/d' tests/boot.rs
     '';
 
     preBuild = ''
@@ -62,6 +69,9 @@ in
       cp seccomp/${arch}/* $out/share/policy/
     '';
 
+    # Boot test often hangs on AMD.
+    doCheck = !stdenv.buildPlatform.isx86_64;
+
     CROSVM_CARGO_TEST_KERNEL_BINARY =
       lib.optionalString (stdenv.buildPlatform == stdenv.hostPlatform)
         "${linux}/${stdenv.hostPlatform.platform.kernelTarget}";
diff --git a/pkgs/os-specific/linux/chromium-os/sommelier/0004-sommelier-don-t-leak-source-absolute-paths.patch b/pkgs/os-specific/linux/chromium-os/sommelier/0003-sommelier-don-t-leak-source-absolute-paths.patch
index 309165c8a05..515daf80073 100644
--- a/pkgs/os-specific/linux/chromium-os/sommelier/0004-sommelier-don-t-leak-source-absolute-paths.patch
+++ b/pkgs/os-specific/linux/chromium-os/sommelier/0003-sommelier-don-t-leak-source-absolute-paths.patch
@@ -1,17 +1,17 @@
-From 7fd2b67e7b265f7c2014ce7183c483f34e1a8ec9 Mon Sep 17 00:00:00 2001
+From 98cff9d9c6cd0642ecb54f0fbb799a6a9c666035 Mon Sep 17 00:00:00 2001
 From: Alyssa Ross <hi@alyssa.is>
 Date: Sun, 1 Dec 2019 17:04:04 +0000
-Subject: [PATCH 4/6] sommelier: don't leak source-absolute paths
+Subject: [PATCH 3/4] sommelier: don't leak source-absolute paths
 
 ---
  vm_tools/sommelier/wayland_protocol.gni | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/vm_tools/sommelier/wayland_protocol.gni b/vm_tools/sommelier/wayland_protocol.gni
-index 4f18a0c10..b1bd5d659 100644
+index f894adf81d..28bb5a006b 100644
 --- a/vm_tools/sommelier/wayland_protocol.gni
 +++ b/vm_tools/sommelier/wayland_protocol.gni
-@@ -44,7 +44,7 @@ template("wayland_protocol_library") {
+@@ -42,7 +42,7 @@ template("wayland_protocol_library") {
          "wayland-scanner",
          g.subcommand,
          "{{source}}",
@@ -21,5 +21,5 @@ index 4f18a0c10..b1bd5d659 100644
      }
    }
 -- 
-2.26.2
+2.30.0
 
diff --git a/pkgs/os-specific/linux/chromium-os/sommelier/0005-sommelier-use-stable-xdg-shell-protocol.patch b/pkgs/os-specific/linux/chromium-os/sommelier/0004-Revert-Revert-vm_tools-sommelier-Switch-to-the-stabl.patch
index 41a42df74fd..fcc8a5d8ad7 100644
--- a/pkgs/os-specific/linux/chromium-os/sommelier/0005-sommelier-use-stable-xdg-shell-protocol.patch
+++ b/pkgs/os-specific/linux/chromium-os/sommelier/0004-Revert-Revert-vm_tools-sommelier-Switch-to-the-stabl.patch
@@ -1,28 +1,25 @@
-From d3a8f6b49e35744e71271cab1eb9ea9a5c87854d Mon Sep 17 00:00:00 2001
-From: Puck Meerburg <puck@puckipedia.com>
-Date: Tue, 3 Dec 2019 18:06:14 +0000
-Subject: [PATCH 5/6] sommelier: use stable xdg-shell protocol
+From 1ff39f1a4e5ac194a1e3ca52632342794eedc130 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Fri, 2 Apr 2021 17:55:55 +0000
+Subject: [PATCH 4/4] Revert "Revert "vm_tools: sommelier: Switch to the stable
+ version of xdg-shell""
 
-From https://github.com/wayland-project/weston/commit/d8d9f5e6e16c8f6a3c06763d5f56c27dc9a6e52e:
-
-> Some clients like the mpv video player now request the xdg_shell
-> protocol so these will fail if the compositor only provides the
-> xdg_shell_unstable_v6 protocol. Compositors like mir and gnome provide
-> both protocols.
+This reverts commit 32050c0ea6c00c16999915856b40a6a6b8b41bb9.
 ---
  vm_tools/sommelier/BUILD.gn                   |   2 +-
- ...dg-shell-unstable-v6.xml => xdg-shell.xml} | 319 ++++++++++++------
- vm_tools/sommelier/sommelier-xdg-shell.c      | 233 ++++++-------
- vm_tools/sommelier/sommelier.c                | 211 ++++++------
- vm_tools/sommelier/sommelier.h                |  17 +-
- 5 files changed, 447 insertions(+), 335 deletions(-)
- rename vm_tools/sommelier/protocol/{xdg-shell-unstable-v6.xml => xdg-shell.xml} (79%)
+ vm_tools/sommelier/meson.build                |   2 +-
+ ...dg-shell-unstable-v6.xml => xdg-shell.xml} | 435 +++++++++++++-----
+ vm_tools/sommelier/sommelier-xdg-shell.cc     | 217 +++++----
+ vm_tools/sommelier/sommelier.cc               | 210 +++++----
+ vm_tools/sommelier/sommelier.h                |   8 +-
+ 6 files changed, 535 insertions(+), 339 deletions(-)
+ rename vm_tools/sommelier/protocol/{xdg-shell-unstable-v6.xml => xdg-shell.xml} (71%)
 
 diff --git a/vm_tools/sommelier/BUILD.gn b/vm_tools/sommelier/BUILD.gn
-index 5027628d2..4330560a1 100644
+index fe8481bee1..7fdebbb201 100644
 --- a/vm_tools/sommelier/BUILD.gn
 +++ b/vm_tools/sommelier/BUILD.gn
-@@ -68,7 +68,7 @@ wayland_protocol_library("sommelier-protocol") {
+@@ -64,7 +64,7 @@ wayland_protocol_library("sommelier-protocol") {
      "protocol/relative-pointer-unstable-v1.xml",
      "protocol/text-input-unstable-v1.xml",
      "protocol/viewporter.xml",
@@ -31,11 +28,24 @@ index 5027628d2..4330560a1 100644
    ]
  }
  
+diff --git a/vm_tools/sommelier/meson.build b/vm_tools/sommelier/meson.build
+index cd33ec8fec..9eb8a2fb30 100644
+--- a/vm_tools/sommelier/meson.build
++++ b/vm_tools/sommelier/meson.build
+@@ -58,7 +58,7 @@ wl_protocols = [
+     'protocol/relative-pointer-unstable-v1.xml',
+     'protocol/text-input-unstable-v1.xml',
+     'protocol/viewporter.xml',
+-    'protocol/xdg-shell-unstable-v6.xml',
++    'protocol/xdg-shell.xml',
+ ]
+ 
+ wl_outs = []
 diff --git a/vm_tools/sommelier/protocol/xdg-shell-unstable-v6.xml b/vm_tools/sommelier/protocol/xdg-shell.xml
-similarity index 79%
+similarity index 71%
 rename from vm_tools/sommelier/protocol/xdg-shell-unstable-v6.xml
 rename to vm_tools/sommelier/protocol/xdg-shell.xml
-index 1c0f92452..3a87a9ed6 100644
+index 1c0f92452b..f7377a713c 100644
 --- a/vm_tools/sommelier/protocol/xdg-shell-unstable-v6.xml
 +++ b/vm_tools/sommelier/protocol/xdg-shell.xml
 @@ -1,11 +1,13 @@
@@ -58,7 +68,7 @@ index 1c0f92452..3a87a9ed6 100644
    </copyright>
  
 -  <interface name="zxdg_shell_v6" version="1">
-+  <interface name="xdg_wm_base" version="2">
++  <interface name="xdg_wm_base" version="3">
      <description summary="create desktop-style surfaces">
 -      xdg_shell allows clients to turn a wl_surface into a "real window"
 -      which can be dragged, resized, stacked, and moved around by the
@@ -142,7 +152,7 @@ index 1c0f92452..3a87a9ed6 100644
    </interface>
  
 -  <interface name="zxdg_positioner_v6" version="1">
-+  <interface name="xdg_positioner" version="2">
++  <interface name="xdg_positioner" version="3">
      <description summary="child surface positioner">
        The xdg_positioner provides a collection of rules for the placement of a
        child surface relative to a parent surface. Rules can be defined to ensure
@@ -280,16 +290,58 @@ index 1c0f92452..3a87a9ed6 100644
  	  If the adjusted position also ends up being constrained, the resulting
  	  position of the flip_y adjustment will be the one before the
  	  adjustment.
-@@ -361,7 +359,7 @@
+@@ -359,9 +357,49 @@
+       <arg name="x" type="int" summary="surface position x offset"/>
+       <arg name="y" type="int" summary="surface position y offset"/>
      </request>
++
++    <!-- Version 3 additions -->
++
++    <request name="set_reactive" since="3">
++      <description summary="continuously reconstrain the surface">
++	When set reactive, the surface is reconstrained if the conditions used
++	for constraining changed, e.g. the parent window moved.
++
++	If the conditions changed and the popup was reconstrained, an
++	xdg_popup.configure event is sent with updated geometry, followed by an
++	xdg_surface.configure event.
++      </description>
++    </request>
++
++    <request name="set_parent_size" since="3">
++      <description summary="">
++	Set the parent window geometry the compositor should use when
++	positioning the popup. The compositor may use this information to
++	determine the future state the popup should be constrained using. If
++	this doesn't match the dimension of the parent the popup is eventually
++	positioned against, the behavior is undefined.
++
++	The arguments are given in the surface-local coordinate space.
++      </description>
++      <arg name="parent_width" type="int"
++	   summary="future window geometry width of parent"/>
++      <arg name="parent_height" type="int"
++	   summary="future window geometry height of parent"/>
++    </request>
++
++    <request name="set_parent_configure" since="3">
++      <description summary="set parent configure this is a response to">
++	Set the serial of a xdg_surface.configure event this positioner will be
++	used in response to. The compositor may use this information together
++	with set_parent_size to determine what future state the popup should be
++	constrained using.
++      </description>
++      <arg name="serial" type="uint"
++	   summary="serial of parent configure event"/>
++    </request>
    </interface>
  
 -  <interface name="zxdg_surface_v6" version="1">
-+  <interface name="xdg_surface" version="2">
++  <interface name="xdg_surface" version="3">
      <description summary="desktop user interface surface base interface">
        An interface that may be implemented by a wl_surface, for
        implementations that provide a desktop-style user interface.
-@@ -388,11 +386,20 @@
+@@ -388,11 +426,25 @@
        manipulate a buffer prior to the first xdg_surface.configure call must
        also be treated as errors.
  
@@ -298,6 +350,11 @@ index 1c0f92452..3a87a9ed6 100644
 -      surface, (2) the client has set and committed the xdg_surface state and
 -      the role dependent state to the surface and (3) the client has committed a
 -      buffer to the surface.
++      After creating a role-specific object and setting it up, the client must
++      perform an initial commit without any buffer attached. The compositor
++      will reply with an xdg_surface.configure event. The client must
++      acknowledge it and is then allowed to attach a buffer to map the surface.
++
 +      Mapping an xdg_surface-based role surface is defined as making it
 +      possible for the surface to be shown by the compositor. Note that
 +      a mapped surface is not guaranteed to be visible once it is mapped.
@@ -315,7 +372,7 @@ index 1c0f92452..3a87a9ed6 100644
      </description>
  
      <enum name="error">
-@@ -416,20 +423,23 @@
+@@ -416,20 +468,23 @@
  	See the documentation of xdg_toplevel for more details about what an
  	xdg_toplevel is and how it is used.
        </description>
@@ -345,7 +402,7 @@ index 1c0f92452..3a87a9ed6 100644
      </request>
  
      <request name="set_window_geometry">
-@@ -442,6 +452,11 @@
+@@ -442,6 +497,11 @@
  	The window geometry is double buffered, and will be applied at the
  	time wl_surface.commit of the corresponding wl_surface is called.
  
@@ -357,12 +414,15 @@ index 1c0f92452..3a87a9ed6 100644
  	Once the window geometry of the surface is set, it is not possible to
  	unset it, and it will remain the same until set_window_geometry is
  	called again, even if a new subsurface or buffer is attached.
-@@ -513,34 +528,50 @@
+@@ -511,36 +571,57 @@
+       </description>
+       <arg name="serial" type="uint" summary="serial of the configure event"/>
      </event>
++
    </interface>
  
 -  <interface name="zxdg_toplevel_v6" version="1">
-+  <interface name="xdg_toplevel" version="2">
++  <interface name="xdg_toplevel" version="3">
      <description summary="toplevel surface">
        This interface defines an xdg_surface role which allows a surface to,
        among other things, set window-like properties such as maximize,
@@ -374,7 +434,11 @@ index 1c0f92452..3a87a9ed6 100644
 +      by the compositor until it is explicitly mapped again.
 +      All active operations (e.g., move, resize) are canceled and all
 +      attributes (e.g. title, state, stacking, ...) are discarded for
-+      an xdg_toplevel surface when it is unmapped.
++      an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
++      the state it had right after xdg_surface.get_toplevel. The client
++      can re-map the toplevel by perfoming a commit without any buffer
++      attached, waiting for a configure event and handling it as usual (see
++      xdg_surface description).
 +
 +      Attaching a null buffer to a toplevel unmaps the surface.
      </description>
@@ -416,7 +480,7 @@ index 1c0f92452..3a87a9ed6 100644
      </request>
  
      <request name="set_title">
-@@ -573,6 +604,9 @@
+@@ -573,6 +654,9 @@
  	For example, "org.freedesktop.FooViewer" where the .desktop file is
  	"org.freedesktop.FooViewer.desktop".
  
@@ -426,7 +490,16 @@ index 1c0f92452..3a87a9ed6 100644
  	See the desktop-entry specification [0] for more details on
  	application identifiers and how they relate to well-known D-Bus
  	names and .desktop files.
-@@ -693,12 +727,18 @@
+@@ -676,7 +760,7 @@
+       </description>
+       <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
+       <arg name="serial" type="uint" summary="the serial of the user event"/>
+-      <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
++      <arg name="edges" type="uint" enum="resize_edge" summary="which edge or corner is being dragged"/>
+     </request>
+ 
+     <enum name="state">
+@@ -693,12 +777,18 @@
  	<description summary="the surface is maximized">
  	  The surface is maximized. The window geometry specified in the configure
  	  event must be obeyed by the client.
@@ -447,7 +520,7 @@ index 1c0f92452..3a87a9ed6 100644
  	</description>
        </entry>
        <entry name="resizing" value="3" summary="the surface is being resized">
-@@ -716,6 +756,30 @@
+@@ -716,6 +806,30 @@
  	  keyboard or pointer focus.
  	</description>
        </entry>
@@ -478,7 +551,7 @@ index 1c0f92452..3a87a9ed6 100644
      </enum>
  
      <request name="set_max_size">
-@@ -805,12 +869,11 @@
+@@ -805,12 +919,11 @@
  	Maximize the surface.
  
  	After requesting that the surface should be maximized, the compositor
@@ -496,7 +569,7 @@ index 1c0f92452..3a87a9ed6 100644
  
  	It is up to the compositor to decide how and where to maximize the
  	surface, for example which output and what region of the screen should
-@@ -818,6 +881,10 @@
+@@ -818,6 +931,10 @@
  
  	If the surface was already maximized, the compositor will still emit
  	a configure event with the "maximized" state.
@@ -507,7 +580,7 @@ index 1c0f92452..3a87a9ed6 100644
        </description>
      </request>
  
-@@ -826,13 +893,13 @@
+@@ -826,13 +943,13 @@
  	Unmaximize the surface.
  
  	After requesting that the surface should be unmaximized, the compositor
@@ -528,7 +601,7 @@ index 1c0f92452..3a87a9ed6 100644
  
  	It is up to the compositor to position the surface after it was
  	unmaximized; usually the position the surface had before maximizing, if
-@@ -840,24 +907,63 @@
+@@ -840,24 +957,63 @@
  
  	If the surface was already not maximized, the compositor will still
  	emit a configure event without the "maximized" state.
@@ -598,16 +671,16 @@ index 1c0f92452..3a87a9ed6 100644
  
      <request name="set_minimized">
        <description summary="set the window as minimized">
-@@ -913,7 +1019,7 @@
+@@ -913,7 +1069,7 @@
      </event>
    </interface>
  
 -  <interface name="zxdg_popup_v6" version="1">
-+  <interface name="xdg_popup" version="2">
++  <interface name="xdg_popup" version="3">
      <description summary="short-lived, popup surfaces for menus">
        A popup surface is a short-lived, temporary surface. It can be used to
        implement for example menus, popovers, tooltips and other similar user
-@@ -931,9 +1037,6 @@
+@@ -931,21 +1087,12 @@
        surface of their own is clicked should dismiss the popup using the destroy
        request.
  
@@ -617,21 +690,103 @@ index 1c0f92452..3a87a9ed6 100644
        A newly created xdg_popup will be stacked on top of all previously created
        xdg_popup surfaces associated with the same xdg_toplevel.
  
-diff --git a/vm_tools/sommelier/sommelier-xdg-shell.c b/vm_tools/sommelier/sommelier-xdg-shell.c
-index ecd0fc647..a3ba0d6e1 100644
---- a/vm_tools/sommelier/sommelier-xdg-shell.c
-+++ b/vm_tools/sommelier/sommelier-xdg-shell.c
+       The parent of an xdg_popup must be mapped (see the xdg_surface
+       description) before the xdg_popup itself.
+ 
+-      The x and y arguments passed when creating the popup object specify
+-      where the top left of the popup should be placed, relative to the
+-      local surface coordinates of the parent surface. See
+-      xdg_surface.get_popup. An xdg_popup must intersect with or be at least
+-      partially adjacent to its parent surface.
+-
+       The client must call wl_surface.commit on the corresponding wl_surface
+       for the xdg_popup state to take effect.
+     </description>
+@@ -1023,6 +1170,11 @@
+ 	The x and y arguments represent the position the popup was placed at
+ 	given the xdg_positioner rule, relative to the upper left corner of the
+ 	window geometry of the parent surface.
++
++	For version 2 or older, the configure event for an xdg_popup is only
++	ever sent once for the initial configuration. Starting with version 3,
++	it may be sent again if the popup is setup with an xdg_positioner with
++	set_reactive requested, or in response to xdg_popup.reposition requests.
+       </description>
+       <arg name="x" type="int"
+ 	   summary="x position relative to parent surface window geometry"/>
+@@ -1040,5 +1192,58 @@
+       </description>
+     </event>
+ 
++    <!-- Version 3 additions -->
++
++    <request name="reposition" since="3">
++      <description summary="recalculate the popup's location">
++	Reposition an already-mapped popup. The popup will be placed given the
++	details in the passed xdg_positioner object, and a
++	xdg_popup.repositioned followed by xdg_popup.configure and
++	xdg_surface.configure will be emitted in response. Any parameters set
++	by the previous positioner will be discarded.
++
++	The passed token will be sent in the corresponding
++	xdg_popup.repositioned event. The new popup position will not take
++	effect until the corresponding configure event is acknowledged by the
++	client. See xdg_popup.repositioned for details. The token itself is
++	opaque, and has no other special meaning.
++
++	If multiple reposition requests are sent, the compositor may skip all
++	but the last one.
++
++	If the popup is repositioned in response to a configure event for its
++	parent, the client should send an xdg_positioner.set_parent_configure
++	and possibly a xdg_positioner.set_parent_size request to allow the
++	compositor to properly constrain the popup.
++
++	If the popup is repositioned together with a parent that is being
++	resized, but not in response to a configure event, the client should
++	send a xdg_positioner.set_parent_size request.
++      </description>
++      <arg name="positioner" type="object" interface="xdg_positioner"/>
++      <arg name="token" type="uint" summary="reposition request token"/>
++    </request>
++
++    <event name="repositioned" since="3">
++      <description summary="signal the completion of a repositioned request">
++	The repositioned event is sent as part of a popup configuration
++	sequence, together with xdg_popup.configure and lastly
++	xdg_surface.configure to notify the completion of a reposition request.
++
++	The repositioned event is to notify about the completion of a
++	xdg_popup.reposition request. The token argument is the token passed
++	in the xdg_popup.reposition request.
++
++	Immediately after this event is emitted, xdg_popup.configure and
++	xdg_surface.configure will be sent with the updated size and position,
++	as well as a new configure serial.
++
++	The client should optionally update the content of the popup, but must
++	acknowledge the new popup configuration for the new position to take
++	effect. See xdg_surface.ack_configure for details.
++      </description>
++      <arg name="token" type="uint" summary="reposition request token"/>
++    </event>
++
+   </interface>
+ </protocol>
+diff --git a/vm_tools/sommelier/sommelier-xdg-shell.cc b/vm_tools/sommelier/sommelier-xdg-shell.cc
+index 91744a67e3..45b8eeb93e 100644
+--- a/vm_tools/sommelier/sommelier-xdg-shell.cc
++++ b/vm_tools/sommelier/sommelier-xdg-shell.cc
 @@ -7,37 +7,37 @@
  #include <assert.h>
  #include <stdlib.h>
  
--#include "xdg-shell-unstable-v6-client-protocol.h"
--#include "xdg-shell-unstable-v6-server-protocol.h"
-+#include "xdg-shell-client-protocol.h"
-+#include "xdg-shell-server-protocol.h"
+-#include "xdg-shell-unstable-v6-client-protocol.h"  // NOLINT(build/include_directory)
+-#include "xdg-shell-unstable-v6-server-protocol.h"  // NOLINT(build/include_directory)
++#include "xdg-shell-client-protocol.h"  // NOLINT(build/include_directory)
++#include "xdg-shell-server-protocol.h"  // NOLINT(build/include_directory)
  
--struct sl_host_xdg_shell {
-+struct sl_host_xdg_wm_base {
+ struct sl_host_xdg_shell {
    struct sl_context* ctx;
    struct wl_resource* resource;
 -  struct zxdg_shell_v6* proxy;
@@ -667,8 +822,8 @@ index ecd0fc647..a3ba0d6e1 100644
  };
  
  static void sl_xdg_positioner_destroy(struct wl_client* client,
-@@ -52,7 +52,7 @@ static void sl_xdg_positioner_set_size(struct wl_client* client,
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+@@ -53,7 +53,7 @@ static void sl_xdg_positioner_set_size(struct wl_client* client,
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
    double scale = host->ctx->scale;
  
 -  zxdg_positioner_v6_set_size(host->proxy, width / scale, height / scale);
@@ -676,7 +831,7 @@ index ecd0fc647..a3ba0d6e1 100644
  }
  
  static void sl_xdg_positioner_set_anchor_rect(struct wl_client* client,
-@@ -70,7 +70,7 @@ static void sl_xdg_positioner_set_anchor_rect(struct wl_client* client,
+@@ -72,7 +72,7 @@ static void sl_xdg_positioner_set_anchor_rect(struct wl_client* client,
    x2 = (x + width) / scale;
    y2 = (y + height) / scale;
  
@@ -685,37 +840,36 @@ index ecd0fc647..a3ba0d6e1 100644
  }
  
  static void sl_xdg_positioner_set_anchor(struct wl_client* client,
-@@ -78,7 +78,7 @@ static void sl_xdg_positioner_set_anchor(struct wl_client* client,
-                                          uint32_t anchor) {
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+@@ -81,7 +81,7 @@ static void sl_xdg_positioner_set_anchor(struct wl_client* client,
+   struct sl_host_xdg_positioner* host =
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
  
 -  zxdg_positioner_v6_set_anchor(host->proxy, anchor);
 +  xdg_positioner_set_anchor(host->proxy, anchor);
  }
  
  static void sl_xdg_positioner_set_gravity(struct wl_client* client,
-@@ -86,7 +86,7 @@ static void sl_xdg_positioner_set_gravity(struct wl_client* client,
-                                           uint32_t gravity) {
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+@@ -90,7 +90,7 @@ static void sl_xdg_positioner_set_gravity(struct wl_client* client,
+   struct sl_host_xdg_positioner* host =
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
  
 -  zxdg_positioner_v6_set_gravity(host->proxy, gravity);
 +  xdg_positioner_set_gravity(host->proxy, gravity);
  }
  
  static void sl_xdg_positioner_set_constraint_adjustment(
-@@ -95,8 +95,8 @@ static void sl_xdg_positioner_set_constraint_adjustment(
-     uint32_t constraint_adjustment) {
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+@@ -100,8 +100,7 @@ static void sl_xdg_positioner_set_constraint_adjustment(
+   struct sl_host_xdg_positioner* host =
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
  
 -  zxdg_positioner_v6_set_constraint_adjustment(host->proxy,
 -                                               constraint_adjustment);
-+  xdg_positioner_set_constraint_adjustment(host->proxy,
-+                                           constraint_adjustment);
- }
++  xdg_positioner_set_constraint_adjustment(host->proxy, constraint_adjustment);
+ }  // NOLINT(whitespace/indent)
  
  static void sl_xdg_positioner_set_offset(struct wl_client* client,
-@@ -106,10 +106,10 @@ static void sl_xdg_positioner_set_offset(struct wl_client* client,
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+@@ -112,24 +111,23 @@ static void sl_xdg_positioner_set_offset(struct wl_client* client,
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
    double scale = host->ctx->scale;
  
 -  zxdg_positioner_v6_set_offset(host->proxy, x / scale, y / scale);
@@ -723,26 +877,39 @@ index ecd0fc647..a3ba0d6e1 100644
  }
  
 -static const struct zxdg_positioner_v6_interface
-+static const struct xdg_positioner_interface
-     sl_xdg_positioner_implementation = {
-         sl_xdg_positioner_destroy,
-         sl_xdg_positioner_set_size,
-@@ -122,7 +122,7 @@ static const struct zxdg_positioner_v6_interface
+-    sl_xdg_positioner_implementation = {
+-        sl_xdg_positioner_destroy,
+-        sl_xdg_positioner_set_size,
+-        sl_xdg_positioner_set_anchor_rect,
+-        sl_xdg_positioner_set_anchor,
+-        sl_xdg_positioner_set_gravity,
+-        sl_xdg_positioner_set_constraint_adjustment,
+-        sl_xdg_positioner_set_offset};
++static const struct xdg_positioner_interface sl_xdg_positioner_implementation =
++    {sl_xdg_positioner_destroy,
++     sl_xdg_positioner_set_size,
++     sl_xdg_positioner_set_anchor_rect,
++     sl_xdg_positioner_set_anchor,
++     sl_xdg_positioner_set_gravity,
++     sl_xdg_positioner_set_constraint_adjustment,
++     sl_xdg_positioner_set_offset};
+ 
  static void sl_destroy_host_xdg_positioner(struct wl_resource* resource) {
-   struct sl_host_xdg_positioner* host = wl_resource_get_user_data(resource);
+   struct sl_host_xdg_positioner* host =
+       static_cast<sl_host_xdg_positioner*>(wl_resource_get_user_data(resource));
  
 -  zxdg_positioner_v6_destroy(host->proxy);
 +  xdg_positioner_destroy(host->proxy);
    wl_resource_set_user_data(resource, NULL);
    free(host);
  }
-@@ -139,19 +139,19 @@ static void sl_xdg_popup_grab(struct wl_client* client,
-   struct sl_host_xdg_popup* host = wl_resource_get_user_data(resource);
-   struct sl_host_seat* host_seat = wl_resource_get_user_data(seat_resource);
+@@ -148,20 +146,20 @@ static void sl_xdg_popup_grab(struct wl_client* client,
+   struct sl_host_seat* host_seat =
+       static_cast<sl_host_seat*>(wl_resource_get_user_data(seat_resource));
  
 -  zxdg_popup_v6_grab(host->proxy, host_seat->proxy, serial);
 +  xdg_popup_grab(host->proxy, host_seat->proxy, serial);
- }
+ }  // NOLINT(whitespace/indent)
  
 -static const struct zxdg_popup_v6_interface sl_xdg_popup_implementation = {
 +static const struct xdg_popup_interface sl_xdg_popup_implementation = {
@@ -755,12 +922,13 @@ index ecd0fc647..a3ba0d6e1 100644
                                     int32_t y,
                                     int32_t width,
                                     int32_t height) {
--  struct sl_host_xdg_popup* host = zxdg_popup_v6_get_user_data(xdg_popup);
-+  struct sl_host_xdg_popup* host = xdg_popup_get_user_data(xdg_popup);
+   struct sl_host_xdg_popup* host =
+-      static_cast<sl_host_xdg_popup*>(zxdg_popup_v6_get_user_data(xdg_popup));
++      static_cast<sl_host_xdg_popup*>(xdg_popup_get_user_data(xdg_popup));
    double scale = host->ctx->scale;
    int32_t x1, y1, x2, y2;
  
-@@ -160,23 +160,23 @@ static void sl_xdg_popup_configure(void* data,
+@@ -170,25 +168,24 @@ static void sl_xdg_popup_configure(void* data,
    x2 = (x + width) * scale;
    y2 = (y + height) * scale;
  
@@ -768,11 +936,12 @@ index ecd0fc647..a3ba0d6e1 100644
 +  xdg_popup_send_configure(host->resource, x1, y1, x2 - x1, y2 - y1);
  }
  
- static void sl_xdg_popup_popup_done(void* data,
+-static void sl_xdg_popup_popup_done(void* data,
 -                                    struct zxdg_popup_v6* xdg_popup) {
--  struct sl_host_xdg_popup* host = zxdg_popup_v6_get_user_data(xdg_popup);
-+                                    struct xdg_popup* xdg_popup) {
-+  struct sl_host_xdg_popup* host = xdg_popup_get_user_data(xdg_popup);
++static void sl_xdg_popup_popup_done(void* data, struct xdg_popup* xdg_popup) {
+   struct sl_host_xdg_popup* host =
+-      static_cast<sl_host_xdg_popup*>(zxdg_popup_v6_get_user_data(xdg_popup));
++      static_cast<sl_host_xdg_popup*>(xdg_popup_get_user_data(xdg_popup));
  
 -  zxdg_popup_v6_send_popup_done(host->resource);
 +  xdg_popup_send_popup_done(host->resource);
@@ -783,140 +952,152 @@ index ecd0fc647..a3ba0d6e1 100644
      sl_xdg_popup_configure, sl_xdg_popup_popup_done};
  
  static void sl_destroy_host_xdg_popup(struct wl_resource* resource) {
-   struct sl_host_xdg_popup* host = wl_resource_get_user_data(resource);
+   struct sl_host_xdg_popup* host =
+       static_cast<sl_host_xdg_popup*>(wl_resource_get_user_data(resource));
  
 -  zxdg_popup_v6_destroy(host->proxy);
 +  xdg_popup_destroy(host->proxy);
    wl_resource_set_user_data(resource, NULL);
    free(host);
  }
-@@ -193,8 +193,8 @@ static void sl_xdg_toplevel_set_parent(struct wl_client* client,
-   struct sl_host_xdg_toplevel* host_parent =
-       parent_resource ? wl_resource_get_user_data(parent_resource) : NULL;
+@@ -208,8 +205,7 @@ static void sl_xdg_toplevel_set_parent(struct wl_client* client,
+                             wl_resource_get_user_data(parent_resource))
+                       : NULL;
  
 -  zxdg_toplevel_v6_set_parent(host->proxy,
 -                              host_parent ? host_parent->proxy : NULL);
-+  xdg_toplevel_set_parent(host->proxy,
-+                          host_parent ? host_parent->proxy : NULL);
++  xdg_toplevel_set_parent(host->proxy, host_parent ? host_parent->proxy : NULL);
  }
  
  static void sl_xdg_toplevel_set_title(struct wl_client* client,
-@@ -202,7 +202,7 @@ static void sl_xdg_toplevel_set_title(struct wl_client* client,
-                                       const char* title) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -218,7 +214,7 @@ static void sl_xdg_toplevel_set_title(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_title(host->proxy, title);
 +  xdg_toplevel_set_title(host->proxy, title);
  }
  
  static void sl_xdg_toplevel_set_app_id(struct wl_client* client,
-@@ -210,7 +210,7 @@ static void sl_xdg_toplevel_set_app_id(struct wl_client* client,
-                                        const char* app_id) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -227,7 +223,7 @@ static void sl_xdg_toplevel_set_app_id(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_app_id(host->proxy, app_id);
 +  xdg_toplevel_set_app_id(host->proxy, app_id);
  }
  
  static void sl_xdg_toplevel_show_window_menu(struct wl_client* client,
-@@ -223,7 +223,7 @@ static void sl_xdg_toplevel_show_window_menu(struct wl_client* client,
-   struct sl_host_seat* host_seat =
-       seat_resource ? wl_resource_get_user_data(seat_resource) : NULL;
+@@ -243,7 +239,7 @@ static void sl_xdg_toplevel_show_window_menu(struct wl_client* client,
+           ? static_cast<sl_host_seat*>(wl_resource_get_user_data(seat_resource))
+           : NULL;
  
 -  zxdg_toplevel_v6_show_window_menu(
 +  xdg_toplevel_show_window_menu(
        host->proxy, host_seat ? host_seat->proxy : NULL, serial, x, y);
- }
+ }  // NOLINT(whitespace/indent)
  
-@@ -235,8 +235,8 @@ static void sl_xdg_toplevel_move(struct wl_client* client,
-   struct sl_host_seat* host_seat =
-       seat_resource ? wl_resource_get_user_data(seat_resource) : NULL;
+@@ -258,8 +254,7 @@ static void sl_xdg_toplevel_move(struct wl_client* client,
+           ? static_cast<sl_host_seat*>(wl_resource_get_user_data(seat_resource))
+           : NULL;
  
 -  zxdg_toplevel_v6_move(host->proxy, host_seat ? host_seat->proxy : NULL,
 -                        serial);
-+  xdg_toplevel_move(host->proxy, host_seat ? host_seat->proxy : NULL,
-+                    serial);
- }
++  xdg_toplevel_move(host->proxy, host_seat ? host_seat->proxy : NULL, serial);
+ }  // NOLINT(whitespace/indent)
  
  static void sl_xdg_toplevel_resize(struct wl_client* client,
-@@ -248,8 +248,8 @@ static void sl_xdg_toplevel_resize(struct wl_client* client,
-   struct sl_host_seat* host_seat =
-       seat_resource ? wl_resource_get_user_data(seat_resource) : NULL;
+@@ -274,8 +269,8 @@ static void sl_xdg_toplevel_resize(struct wl_client* client,
+           ? static_cast<sl_host_seat*>(wl_resource_get_user_data(seat_resource))
+           : NULL;
  
 -  zxdg_toplevel_v6_resize(host->proxy, host_seat ? host_seat->proxy : NULL,
 -                          serial, edges);
-+  xdg_toplevel_resize(host->proxy, host_seat ? host_seat->proxy : NULL,
-+                      serial, edges);
- }
++  xdg_toplevel_resize(host->proxy, host_seat ? host_seat->proxy : NULL, serial,
++                      edges);
+ }  // NOLINT(whitespace/indent)
  
  static void sl_xdg_toplevel_set_max_size(struct wl_client* client,
-@@ -258,7 +258,7 @@ static void sl_xdg_toplevel_set_max_size(struct wl_client* client,
-                                          int32_t height) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -285,7 +280,7 @@ static void sl_xdg_toplevel_set_max_size(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_max_size(host->proxy, width, height);
 +  xdg_toplevel_set_max_size(host->proxy, width, height);
  }
  
  static void sl_xdg_toplevel_set_min_size(struct wl_client* client,
-@@ -267,21 +267,21 @@ static void sl_xdg_toplevel_set_min_size(struct wl_client* client,
-                                          int32_t height) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -295,7 +290,7 @@ static void sl_xdg_toplevel_set_min_size(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_min_size(host->proxy, width, height);
 +  xdg_toplevel_set_min_size(host->proxy, width, height);
  }
  
  static void sl_xdg_toplevel_set_maximized(struct wl_client* client,
-                                           struct wl_resource* resource) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -303,7 +298,7 @@ static void sl_xdg_toplevel_set_maximized(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_maximized(host->proxy);
 +  xdg_toplevel_set_maximized(host->proxy);
  }
  
  static void sl_xdg_toplevel_unset_maximized(struct wl_client* client,
-                                             struct wl_resource* resource) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -311,7 +306,7 @@ static void sl_xdg_toplevel_unset_maximized(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_unset_maximized(host->proxy);
 +  xdg_toplevel_unset_maximized(host->proxy);
  }
  
  static void sl_xdg_toplevel_set_fullscreen(
-@@ -292,25 +292,25 @@ static void sl_xdg_toplevel_set_fullscreen(
-   struct sl_host_output* host_output =
-       output_resource ? wl_resource_get_user_data(output_resource) : NULL;
+@@ -325,8 +320,8 @@ static void sl_xdg_toplevel_set_fullscreen(
+                             wl_resource_get_user_data(output_resource))
+                       : NULL;
  
 -  zxdg_toplevel_v6_set_fullscreen(host->proxy,
 -                                  host_output ? host_output->proxy : NULL);
 +  xdg_toplevel_set_fullscreen(host->proxy,
 +                              host_output ? host_output->proxy : NULL);
- }
+ }  // NOLINT(whitespace/indent)
  
  static void sl_xdg_toplevel_unset_fullscreen(struct wl_client* client,
-                                              struct wl_resource* resource) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -334,7 +329,7 @@ static void sl_xdg_toplevel_unset_fullscreen(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_unset_fullscreen(host->proxy);
 +  xdg_toplevel_unset_fullscreen(host->proxy);
  }
  
  static void sl_xdg_toplevel_set_minimized(struct wl_client* client,
-                                           struct wl_resource* resource) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+@@ -342,47 +337,47 @@ static void sl_xdg_toplevel_set_minimized(struct wl_client* client,
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_set_minimized(host->proxy);
 +  xdg_toplevel_set_minimized(host->proxy);
  }
  
 -static const struct zxdg_toplevel_v6_interface sl_xdg_toplevel_implementation =
-+static const struct xdg_toplevel_interface sl_xdg_toplevel_implementation =
-     {sl_xdg_toplevel_destroy,          sl_xdg_toplevel_set_parent,
-      sl_xdg_toplevel_set_title,        sl_xdg_toplevel_set_app_id,
-      sl_xdg_toplevel_show_window_menu, sl_xdg_toplevel_move,
-@@ -320,33 +320,33 @@ static const struct zxdg_toplevel_v6_interface sl_xdg_toplevel_implementation =
-      sl_xdg_toplevel_unset_fullscreen, sl_xdg_toplevel_set_minimized};
+-    {sl_xdg_toplevel_destroy,          sl_xdg_toplevel_set_parent,
+-     sl_xdg_toplevel_set_title,        sl_xdg_toplevel_set_app_id,
+-     sl_xdg_toplevel_show_window_menu, sl_xdg_toplevel_move,
+-     sl_xdg_toplevel_resize,           sl_xdg_toplevel_set_max_size,
+-     sl_xdg_toplevel_set_min_size,     sl_xdg_toplevel_set_maximized,
+-     sl_xdg_toplevel_unset_maximized,  sl_xdg_toplevel_set_fullscreen,
+-     sl_xdg_toplevel_unset_fullscreen, sl_xdg_toplevel_set_minimized};
++static const struct xdg_toplevel_interface sl_xdg_toplevel_implementation = {
++    sl_xdg_toplevel_destroy,          sl_xdg_toplevel_set_parent,
++    sl_xdg_toplevel_set_title,        sl_xdg_toplevel_set_app_id,
++    sl_xdg_toplevel_show_window_menu, sl_xdg_toplevel_move,
++    sl_xdg_toplevel_resize,           sl_xdg_toplevel_set_max_size,
++    sl_xdg_toplevel_set_min_size,     sl_xdg_toplevel_set_maximized,
++    sl_xdg_toplevel_unset_maximized,  sl_xdg_toplevel_set_fullscreen,
++    sl_xdg_toplevel_unset_fullscreen, sl_xdg_toplevel_set_minimized};
  
  static void sl_xdg_toplevel_configure(void* data,
 -                                      struct zxdg_toplevel_v6* xdg_toplevel,
@@ -924,22 +1105,23 @@ index ecd0fc647..a3ba0d6e1 100644
                                        int32_t width,
                                        int32_t height,
                                        struct wl_array* states) {
-   struct sl_host_xdg_toplevel* host =
--      zxdg_toplevel_v6_get_user_data(xdg_toplevel);
-+      xdg_toplevel_get_user_data(xdg_toplevel);
+   struct sl_host_xdg_toplevel* host = static_cast<sl_host_xdg_toplevel*>(
+-      zxdg_toplevel_v6_get_user_data(xdg_toplevel));
++      xdg_toplevel_get_user_data(xdg_toplevel));
    double scale = host->ctx->scale;
  
 -  zxdg_toplevel_v6_send_configure(host->resource, width * scale, height * scale,
+-                                  states);
 +  xdg_toplevel_send_configure(host->resource, width * scale, height * scale,
-                                   states);
++                              states);
  }
  
  static void sl_xdg_toplevel_close(void* data,
 -                                  struct zxdg_toplevel_v6* xdg_toplevel) {
 +                                  struct xdg_toplevel* xdg_toplevel) {
-   struct sl_host_xdg_toplevel* host =
--      zxdg_toplevel_v6_get_user_data(xdg_toplevel);
-+      xdg_toplevel_get_user_data(xdg_toplevel);
+   struct sl_host_xdg_toplevel* host = static_cast<sl_host_xdg_toplevel*>(
+-      zxdg_toplevel_v6_get_user_data(xdg_toplevel));
++      xdg_toplevel_get_user_data(xdg_toplevel));
  
 -  zxdg_toplevel_v6_send_close(host->resource);
 +  xdg_toplevel_send_close(host->resource);
@@ -950,20 +1132,20 @@ index ecd0fc647..a3ba0d6e1 100644
      sl_xdg_toplevel_configure, sl_xdg_toplevel_close};
  
  static void sl_destroy_host_xdg_toplevel(struct wl_resource* resource) {
-   struct sl_host_xdg_toplevel* host = wl_resource_get_user_data(resource);
+   struct sl_host_xdg_toplevel* host =
+       static_cast<sl_host_xdg_toplevel*>(wl_resource_get_user_data(resource));
  
 -  zxdg_toplevel_v6_destroy(host->proxy);
 +  xdg_toplevel_destroy(host->proxy);
    wl_resource_set_user_data(resource, NULL);
    free(host);
  }
-@@ -367,14 +367,15 @@ static void sl_xdg_surface_get_toplevel(struct wl_client* client,
+@@ -403,14 +398,14 @@ static void sl_xdg_surface_get_toplevel(struct wl_client* client,
  
    host_xdg_toplevel->ctx = host->ctx;
    host_xdg_toplevel->resource =
 -      wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id);
-+      wl_resource_create(client, &xdg_toplevel_interface,
-+                         wl_resource_get_version(resource), id);
++      wl_resource_create(client, &xdg_toplevel_interface, 1, id);
    wl_resource_set_implementation(
        host_xdg_toplevel->resource, &sl_xdg_toplevel_implementation,
        host_xdg_toplevel, sl_destroy_host_xdg_toplevel);
@@ -973,34 +1155,44 @@ index ecd0fc647..a3ba0d6e1 100644
 -                                &sl_xdg_toplevel_listener, host_xdg_toplevel);
 +  host_xdg_toplevel->proxy = xdg_surface_get_toplevel(host->proxy);
 +  xdg_toplevel_set_user_data(host_xdg_toplevel->proxy, host_xdg_toplevel);
-+  xdg_toplevel_add_listener(host_xdg_toplevel->proxy,
-+                            &sl_xdg_toplevel_listener, host_xdg_toplevel);
++  xdg_toplevel_add_listener(host_xdg_toplevel->proxy, &sl_xdg_toplevel_listener,
++                            host_xdg_toplevel);
  }
  
  static void sl_xdg_surface_get_popup(struct wl_client* client,
-@@ -394,15 +395,16 @@ static void sl_xdg_surface_get_popup(struct wl_client* client,
+@@ -421,7 +416,7 @@ static void sl_xdg_surface_get_popup(struct wl_client* client,
+   struct sl_host_xdg_surface* host =
+       static_cast<sl_host_xdg_surface*>(wl_resource_get_user_data(resource));
+   struct sl_host_xdg_surface* host_parent = static_cast<sl_host_xdg_surface*>(
+-      wl_resource_get_user_data(parent_resource));
++      parent_resource ? wl_resource_get_user_data(parent_resource) : NULL);
+   struct sl_host_xdg_positioner* host_positioner =
+       static_cast<sl_host_xdg_positioner*>(
+           wl_resource_get_user_data(positioner_resource));
+@@ -431,15 +426,16 @@ static void sl_xdg_surface_get_popup(struct wl_client* client,
  
    host_xdg_popup->ctx = host->ctx;
    host_xdg_popup->resource =
 -      wl_resource_create(client, &zxdg_popup_v6_interface, 1, id);
-+      wl_resource_create(client, &xdg_popup_interface,
-+                         wl_resource_get_version(resource), id);
++      wl_resource_create(client, &xdg_popup_interface, 1, id);
    wl_resource_set_implementation(host_xdg_popup->resource,
                                   &sl_xdg_popup_implementation, host_xdg_popup,
                                   sl_destroy_host_xdg_popup);
 -  host_xdg_popup->proxy = zxdg_surface_v6_get_popup(
-+  host_xdg_popup->proxy = xdg_surface_get_popup(
-       host->proxy, host_parent->proxy, host_positioner->proxy);
+-      host->proxy, host_parent->proxy, host_positioner->proxy);
 -  zxdg_popup_v6_set_user_data(host_xdg_popup->proxy, host_xdg_popup);
 -  zxdg_popup_v6_add_listener(host_xdg_popup->proxy, &sl_xdg_popup_listener,
 -                             host_xdg_popup);
++  host_xdg_popup->proxy = xdg_surface_get_popup(
++      host->proxy, host_parent ? host_parent->proxy : NULL,
++      host_positioner->proxy);
 +  xdg_popup_set_user_data(host_xdg_popup->proxy, host_xdg_popup);
 +  xdg_popup_add_listener(host_xdg_popup->proxy, &sl_xdg_popup_listener,
 +                         host_xdg_popup);
- }
+ }  // NOLINT(whitespace/indent)
  
  static void sl_xdg_surface_set_window_geometry(struct wl_client* client,
-@@ -420,7 +422,7 @@ static void sl_xdg_surface_set_window_geometry(struct wl_client* client,
+@@ -458,7 +454,7 @@ static void sl_xdg_surface_set_window_geometry(struct wl_client* client,
    x2 = (x + width) / scale;
    y2 = (y + height) / scale;
  
@@ -1009,9 +1201,9 @@ index ecd0fc647..a3ba0d6e1 100644
  }
  
  static void sl_xdg_surface_ack_configure(struct wl_client* client,
-@@ -428,63 +430,64 @@ static void sl_xdg_surface_ack_configure(struct wl_client* client,
-                                          uint32_t serial) {
-   struct sl_host_xdg_surface* host = wl_resource_get_user_data(resource);
+@@ -467,31 +463,31 @@ static void sl_xdg_surface_ack_configure(struct wl_client* client,
+   struct sl_host_xdg_surface* host =
+       static_cast<sl_host_xdg_surface*>(wl_resource_get_user_data(resource));
  
 -  zxdg_surface_v6_ack_configure(host->proxy, serial);
 +  xdg_surface_ack_configure(host->proxy, serial);
@@ -1027,8 +1219,9 @@ index ecd0fc647..a3ba0d6e1 100644
 -                                     struct zxdg_surface_v6* xdg_surface,
 +                                     struct xdg_surface* xdg_surface,
                                       uint32_t serial) {
--  struct sl_host_xdg_surface* host = zxdg_surface_v6_get_user_data(xdg_surface);
-+  struct sl_host_xdg_surface* host = xdg_surface_get_user_data(xdg_surface);
+   struct sl_host_xdg_surface* host = static_cast<sl_host_xdg_surface*>(
+-      zxdg_surface_v6_get_user_data(xdg_surface));
++      xdg_surface_get_user_data(xdg_surface));
  
 -  zxdg_surface_v6_send_configure(host->resource, serial);
 +  xdg_surface_send_configure(host->resource, serial);
@@ -1039,37 +1232,20 @@ index ecd0fc647..a3ba0d6e1 100644
      sl_xdg_surface_configure};
  
  static void sl_destroy_host_xdg_surface(struct wl_resource* resource) {
-   struct sl_host_xdg_surface* host = wl_resource_get_user_data(resource);
+   struct sl_host_xdg_surface* host =
+       static_cast<sl_host_xdg_surface*>(wl_resource_get_user_data(resource));
  
 -  zxdg_surface_v6_destroy(host->proxy);
 +  xdg_surface_destroy(host->proxy);
    wl_resource_set_user_data(resource, NULL);
    free(host);
  }
- 
--static void sl_xdg_shell_destroy(struct wl_client* client,
-+static void sl_xdg_wm_base_destroy(struct wl_client* client,
-                                  struct wl_resource* resource) {
-   wl_resource_destroy(resource);
- }
- 
--static void sl_xdg_shell_create_positioner(struct wl_client* client,
-+static void sl_xdg_wm_base_create_positioner(struct wl_client* client,
-                                            struct wl_resource* resource,
-                                            uint32_t id) {
--  struct sl_host_xdg_shell* host = wl_resource_get_user_data(resource);
-+  struct sl_host_xdg_wm_base* host = wl_resource_get_user_data(resource);
-   struct sl_host_xdg_positioner* host_xdg_positioner;
- 
-   host_xdg_positioner = malloc(sizeof(*host_xdg_positioner));
-   assert(host_xdg_positioner);
+@@ -513,13 +509,12 @@ static void sl_xdg_shell_create_positioner(struct wl_client* client,
  
    host_xdg_positioner->ctx = host->ctx;
--  host_xdg_positioner->resource =
+   host_xdg_positioner->resource =
 -      wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id);
-+  host_xdg_positioner->resource = wl_resource_create(
-+      client, &xdg_positioner_interface,
-+      wl_resource_get_version(resource), id);
++      wl_resource_create(client, &xdg_positioner_interface, 1, id);
    wl_resource_set_implementation(
        host_xdg_positioner->resource, &sl_xdg_positioner_implementation,
        host_xdg_positioner, sl_destroy_host_xdg_positioner);
@@ -1077,29 +1253,16 @@ index ecd0fc647..a3ba0d6e1 100644
 -  zxdg_positioner_v6_set_user_data(host_xdg_positioner->proxy,
 -                                   host_xdg_positioner);
 +  host_xdg_positioner->proxy = xdg_wm_base_create_positioner(host->proxy);
-+  xdg_positioner_set_user_data(host_xdg_positioner->proxy,
-+                               host_xdg_positioner);
++  xdg_positioner_set_user_data(host_xdg_positioner->proxy, host_xdg_positioner);
  }
  
--static void sl_xdg_shell_get_xdg_surface(struct wl_client* client,
-+static void sl_xdg_wm_base_get_xdg_surface(struct wl_client* client,
-                                          struct wl_resource* resource,
-                                          uint32_t id,
-                                          struct wl_resource* surface_resource) {
--  struct sl_host_xdg_shell* host = wl_resource_get_user_data(resource);
-+  struct sl_host_xdg_wm_base* host = wl_resource_get_user_data(resource);
-   struct sl_host_surface* host_surface =
-       wl_resource_get_user_data(surface_resource);
-   struct sl_host_xdg_surface* host_xdg_surface;
-@@ -493,71 +496,75 @@ static void sl_xdg_shell_get_xdg_surface(struct wl_client* client,
-   assert(host_xdg_surface);
+ static void sl_xdg_shell_get_xdg_surface(struct wl_client* client,
+@@ -536,15 +531,15 @@ static void sl_xdg_shell_get_xdg_surface(struct wl_client* client,
  
    host_xdg_surface->ctx = host->ctx;
--  host_xdg_surface->resource =
+   host_xdg_surface->resource =
 -      wl_resource_create(client, &zxdg_surface_v6_interface, 1, id);
-+  host_xdg_surface->resource = wl_resource_create(
-+      client, &xdg_surface_interface,
-+      wl_resource_get_version(resource), id);
++      wl_resource_create(client, &xdg_surface_interface, 1, id);
    wl_resource_set_implementation(host_xdg_surface->resource,
                                   &sl_xdg_surface_implementation,
                                   host_xdg_surface, sl_destroy_host_xdg_surface);
@@ -1110,129 +1273,104 @@ index ecd0fc647..a3ba0d6e1 100644
 -                               &sl_xdg_surface_listener, host_xdg_surface);
 +      xdg_wm_base_get_xdg_surface(host->proxy, host_surface->proxy);
 +  xdg_surface_set_user_data(host_xdg_surface->proxy, host_xdg_surface);
-+  xdg_surface_add_listener(host_xdg_surface->proxy,
-+                           &sl_xdg_surface_listener, host_xdg_surface);
++  xdg_surface_add_listener(host_xdg_surface->proxy, &sl_xdg_surface_listener,
++                           host_xdg_surface);
    host_surface->has_role = 1;
  }
  
--static void sl_xdg_shell_pong(struct wl_client* client,
-+static void sl_xdg_wm_base_pong(struct wl_client* client,
-                               struct wl_resource* resource,
-                               uint32_t serial) {
--  struct sl_host_xdg_shell* host = wl_resource_get_user_data(resource);
-+  struct sl_host_xdg_wm_base* host = wl_resource_get_user_data(resource);
+@@ -554,30 +549,30 @@ static void sl_xdg_shell_pong(struct wl_client* client,
+   struct sl_host_xdg_shell* host =
+       static_cast<sl_host_xdg_shell*>(wl_resource_get_user_data(resource));
  
 -  zxdg_shell_v6_pong(host->proxy, serial);
 +  xdg_wm_base_pong(host->proxy, serial);
  }
  
 -static const struct zxdg_shell_v6_interface sl_xdg_shell_implementation = {
--    sl_xdg_shell_destroy, sl_xdg_shell_create_positioner,
--    sl_xdg_shell_get_xdg_surface, sl_xdg_shell_pong};
-+static const struct xdg_wm_base_interface sl_xdg_wm_base_implementation = {
-+    sl_xdg_wm_base_destroy, sl_xdg_wm_base_create_positioner,
-+    sl_xdg_wm_base_get_xdg_surface, sl_xdg_wm_base_pong};
++static const struct xdg_wm_base_interface sl_xdg_shell_implementation = {
+     sl_xdg_shell_destroy, sl_xdg_shell_create_positioner,
+     sl_xdg_shell_get_xdg_surface, sl_xdg_shell_pong};
  
--static void sl_xdg_shell_ping(void* data,
+ static void sl_xdg_shell_ping(void* data,
 -                              struct zxdg_shell_v6* xdg_shell,
-+static void sl_xdg_wm_base_ping(void* data,
-+                              struct xdg_wm_base* xdg_wm_base,
++                              struct xdg_wm_base* xdg_shell,
                                uint32_t serial) {
--  struct sl_host_xdg_shell* host = zxdg_shell_v6_get_user_data(xdg_shell);
-+  struct sl_host_xdg_wm_base* host = xdg_wm_base_get_user_data(xdg_wm_base);
+   struct sl_host_xdg_shell* host =
+-      static_cast<sl_host_xdg_shell*>(zxdg_shell_v6_get_user_data(xdg_shell));
++      static_cast<sl_host_xdg_shell*>(xdg_wm_base_get_user_data(xdg_shell));
  
 -  zxdg_shell_v6_send_ping(host->resource, serial);
 +  xdg_wm_base_send_ping(host->resource, serial);
  }
  
 -static const struct zxdg_shell_v6_listener sl_xdg_shell_listener = {
--    sl_xdg_shell_ping};
-+static const struct xdg_wm_base_listener sl_xdg_wm_base_listener = {
-+    sl_xdg_wm_base_ping};
++static const struct xdg_wm_base_listener sl_xdg_shell_listener = {
+     sl_xdg_shell_ping};
  
--static void sl_destroy_host_xdg_shell(struct wl_resource* resource) {
--  struct sl_host_xdg_shell* host = wl_resource_get_user_data(resource);
-+static void sl_destroy_host_xdg_wm_base(struct wl_resource* resource) {
-+  struct sl_host_xdg_wm_base* host = wl_resource_get_user_data(resource);
+ static void sl_destroy_host_xdg_shell(struct wl_resource* resource) {
+   struct sl_host_xdg_shell* host =
+       static_cast<sl_host_xdg_shell*>(wl_resource_get_user_data(resource));
  
 -  zxdg_shell_v6_destroy(host->proxy);
 +  xdg_wm_base_destroy(host->proxy);
    wl_resource_set_user_data(resource, NULL);
    free(host);
  }
- 
--static void sl_bind_host_xdg_shell(struct wl_client* client,
-+static void sl_bind_host_xdg_wm_base(struct wl_client* client,
-                                    void* data,
-                                    uint32_t version,
-                                    uint32_t id) {
-   struct sl_context* ctx = (struct sl_context*)data;
--  struct sl_host_xdg_shell* host;
-+  struct sl_host_xdg_wm_base* host;
- 
-   host = malloc(sizeof(*host));
+@@ -591,17 +586,17 @@ static void sl_bind_host_xdg_shell(struct wl_client* client,
+       static_cast<sl_host_xdg_shell*>(malloc(sizeof(*host)));
    assert(host);
    host->ctx = ctx;
 -  host->resource = wl_resource_create(client, &zxdg_shell_v6_interface, 1, id);
--  wl_resource_set_implementation(host->resource, &sl_xdg_shell_implementation,
--                                 host, sl_destroy_host_xdg_shell);
-+  host->resource = wl_resource_create(client, &xdg_wm_base_interface,
-+				      ctx->xdg_wm_base->id, id);
-+  wl_resource_set_implementation(host->resource, &sl_xdg_wm_base_implementation,
-+                                 host, sl_destroy_host_xdg_wm_base);
-   host->proxy =
++  host->resource = wl_resource_create(client, &xdg_wm_base_interface, 1, id);
+   wl_resource_set_implementation(host->resource, &sl_xdg_shell_implementation,
+                                  host, sl_destroy_host_xdg_shell);
+-  host->proxy = static_cast<zxdg_shell_v6*>(
++  host->proxy = static_cast<xdg_wm_base*>(
        wl_registry_bind(wl_display_get_registry(ctx->display),
--                       ctx->xdg_shell->id, &zxdg_shell_v6_interface, 1);
+-                       ctx->xdg_shell->id, &zxdg_shell_v6_interface, 1));
 -  zxdg_shell_v6_set_user_data(host->proxy, host);
 -  zxdg_shell_v6_add_listener(host->proxy, &sl_xdg_shell_listener, host);
-+                       ctx->xdg_wm_base->id, &xdg_wm_base_interface,
-+                       ctx->xdg_wm_base->version);
++                       ctx->xdg_shell->id, &xdg_wm_base_interface, 1));
 +  xdg_wm_base_set_user_data(host->proxy, host);
-+  xdg_wm_base_add_listener(host->proxy, &sl_xdg_wm_base_listener, host);
++  xdg_wm_base_add_listener(host->proxy, &sl_xdg_shell_listener, host);
  }
  
--struct sl_global* sl_xdg_shell_global_create(struct sl_context* ctx) {
+ struct sl_global* sl_xdg_shell_global_create(struct sl_context* ctx) {
 -  return sl_global_create(ctx, &zxdg_shell_v6_interface, 1, ctx,
--                          sl_bind_host_xdg_shell);
-+struct sl_global* sl_xdg_wm_base_global_create(struct sl_context* ctx) {
-+  return sl_global_create(ctx, &xdg_wm_base_interface,
-+                          ctx->xdg_wm_base->version, ctx,
-+                          sl_bind_host_xdg_wm_base);
++  return sl_global_create(ctx, &xdg_wm_base_interface, 1, ctx,
+                           sl_bind_host_xdg_shell);
  }
-diff --git a/vm_tools/sommelier/sommelier.c b/vm_tools/sommelier/sommelier.c
-index 98e101135..9a56f350d 100644
---- a/vm_tools/sommelier/sommelier.c
-+++ b/vm_tools/sommelier/sommelier.c
-@@ -35,7 +35,7 @@
- #include "relative-pointer-unstable-v1-client-protocol.h"
- #include "text-input-unstable-v1-client-protocol.h"
- #include "viewporter-client-protocol.h"
--#include "xdg-shell-unstable-v6-client-protocol.h"
-+#include "xdg-shell-client-protocol.h"
+diff --git a/vm_tools/sommelier/sommelier.cc b/vm_tools/sommelier/sommelier.cc
+index 0560672d46..8435dbe082 100644
+--- a/vm_tools/sommelier/sommelier.cc
++++ b/vm_tools/sommelier/sommelier.cc
+@@ -39,7 +39,7 @@
+ #include "relative-pointer-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
+ #include "text-input-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
+ #include "viewporter-client-protocol.h"  // NOLINT(build/include_directory)
+-#include "xdg-shell-unstable-v6-client-protocol.h"  // NOLINT(build/include_directory)
++#include "xdg-shell-client-protocol.h"  // NOLINT(build/include_directory)
  
  #define errno_assert(rv)                                          \
    {                                                               \
-@@ -281,14 +281,14 @@ void sl_sync_point_destroy(struct sl_sync_point* sync_point) {
-   free(sync_point);
+@@ -376,13 +376,13 @@ void sl_sync_point_destroy(struct sl_sync_point* sync_point) {
  }
  
--static void sl_internal_xdg_shell_ping(void* data,
+ static void sl_internal_xdg_shell_ping(void* data,
 -                                       struct zxdg_shell_v6* xdg_shell,
-+static void sl_internal_xdg_wm_base_ping(void* data,
-+                                       struct xdg_wm_base* xdg_wm_base,
++                                       struct xdg_wm_base* xdg_shell,
                                         uint32_t serial) {
+   TRACE_EVENT("shell", "sl_internal_xdg_shell_ping");
 -  zxdg_shell_v6_pong(xdg_shell, serial);
-+  xdg_wm_base_pong(xdg_wm_base, serial);
++  xdg_wm_base_pong(xdg_shell, serial);
  }
  
 -static const struct zxdg_shell_v6_listener sl_internal_xdg_shell_listener = {
--    sl_internal_xdg_shell_ping};
-+static const struct xdg_wm_base_listener sl_internal_xdg_wm_base_listener = {
-+    sl_internal_xdg_wm_base_ping};
++static const struct xdg_wm_base_listener sl_internal_xdg_shell_listener = {
+     sl_internal_xdg_shell_ping};
  
  static void sl_send_configure_notify(struct sl_window* window) {
-   xcb_configure_notify_event_t event = {
-@@ -451,8 +451,8 @@ int sl_process_pending_configure_acks(struct sl_window* window,
+@@ -549,8 +549,8 @@ int sl_process_pending_configure_acks(struct sl_window* window,
    }
  
    if (window->xdg_surface) {
@@ -1243,24 +1381,30 @@ index 98e101135..9a56f350d 100644
    }
    window->pending_config.serial = 0;
  
-@@ -463,8 +463,8 @@ int sl_process_pending_configure_acks(struct sl_window* window,
+@@ -560,11 +560,12 @@ int sl_process_pending_configure_acks(struct sl_window* window,
+   return 1;
  }
  
- static void sl_internal_xdg_surface_configure(
+-static void sl_internal_xdg_surface_configure(
 -    void* data, struct zxdg_surface_v6* xdg_surface, uint32_t serial) {
--  struct sl_window* window = zxdg_surface_v6_get_user_data(xdg_surface);
-+    void* data, struct xdg_surface* xdg_surface, uint32_t serial) {
-+  struct sl_window* window = xdg_surface_get_user_data(xdg_surface);
++static void sl_internal_xdg_surface_configure(void* data,
++                                              struct xdg_surface* xdg_surface,
++                                              uint32_t serial) {
+   TRACE_EVENT("surface", "sl_internal_xdg_surface_configure");
+   struct sl_window* window =
+-      static_cast<sl_window*>(zxdg_surface_v6_get_user_data(xdg_surface));
++      static_cast<sl_window*>(xdg_surface_get_user_data(xdg_surface));
  
    window->next_config.serial = serial;
    if (!window->pending_config.serial) {
-@@ -485,16 +485,16 @@ static void sl_internal_xdg_surface_configure(
+@@ -586,18 +587,18 @@ static void sl_internal_xdg_surface_configure(
    }
  }
  
 -static const struct zxdg_surface_v6_listener sl_internal_xdg_surface_listener =
-+static const struct xdg_surface_listener sl_internal_xdg_surface_listener =
-     {sl_internal_xdg_surface_configure};
+-    {sl_internal_xdg_surface_configure};
++static const struct xdg_surface_listener sl_internal_xdg_surface_listener = {
++    sl_internal_xdg_surface_configure};
  
  static void sl_internal_xdg_toplevel_configure(
      void* data,
@@ -1269,15 +1413,17 @@ index 98e101135..9a56f350d 100644
      int32_t width,
      int32_t height,
      struct wl_array* states) {
--  struct sl_window* window = zxdg_toplevel_v6_get_user_data(xdg_toplevel);
-+  struct sl_window* window = xdg_toplevel_get_user_data(xdg_toplevel);
+   TRACE_EVENT("other", "sl_internal_xdg_toplevel_configure");
+   struct sl_window* window =
+-      static_cast<sl_window*>(zxdg_toplevel_v6_get_user_data(xdg_toplevel));
++      static_cast<sl_window*>(xdg_toplevel_get_user_data(xdg_toplevel));
    int activated = 0;
    uint32_t* state;
    int i = 0;
-@@ -524,21 +524,21 @@ static void sl_internal_xdg_toplevel_configure(
+@@ -627,21 +628,21 @@ static void sl_internal_xdg_toplevel_configure(
  
    window->allow_resize = 1;
-   wl_array_for_each(state, states) {
+   sl_array_for_each(state, states) {
 -    if (*state == ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN) {
 +    if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
        window->allow_resize = 0;
@@ -1300,25 +1446,30 @@ index 98e101135..9a56f350d 100644
        window->allow_resize = 0;
    }
  
-@@ -554,8 +554,8 @@ static void sl_internal_xdg_toplevel_configure(
+@@ -656,11 +657,11 @@ static void sl_internal_xdg_toplevel_configure(
+   window->next_config.states_length = i;
  }
  
- static void sl_internal_xdg_toplevel_close(
+-static void sl_internal_xdg_toplevel_close(
 -    void* data, struct zxdg_toplevel_v6* xdg_toplevel) {
--  struct sl_window* window = zxdg_toplevel_v6_get_user_data(xdg_toplevel);
-+    void* data, struct xdg_toplevel* xdg_toplevel) {
-+  struct sl_window* window = xdg_toplevel_get_user_data(xdg_toplevel);
-   xcb_client_message_event_t event = {
-       .response_type = XCB_CLIENT_MESSAGE,
-       .format = 32,
-@@ -572,21 +572,21 @@ static void sl_internal_xdg_toplevel_close(
++static void sl_internal_xdg_toplevel_close(void* data,
++                                           struct xdg_toplevel* xdg_toplevel) {
+   TRACE_EVENT("other", "sl_internal_xdg_toplevel_close");
+   struct sl_window* window =
+-      static_cast<sl_window*>(zxdg_toplevel_v6_get_user_data(xdg_toplevel));
++      static_cast<sl_window*>(xdg_toplevel_get_user_data(xdg_toplevel));
+   xcb_client_message_event_t event = {};
+   event.response_type = XCB_CLIENT_MESSAGE;
+   event.format = 32;
+@@ -673,21 +674,20 @@ static void sl_internal_xdg_toplevel_close(
                   XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
  }
  
 -static const struct zxdg_toplevel_v6_listener
-+static const struct xdg_toplevel_listener
-     sl_internal_xdg_toplevel_listener = {sl_internal_xdg_toplevel_configure,
-                                          sl_internal_xdg_toplevel_close};
+-    sl_internal_xdg_toplevel_listener = {sl_internal_xdg_toplevel_configure,
+-                                         sl_internal_xdg_toplevel_close};
++static const struct xdg_toplevel_listener sl_internal_xdg_toplevel_listener = {
++    sl_internal_xdg_toplevel_configure, sl_internal_xdg_toplevel_close};
  
  static void sl_internal_xdg_popup_configure(void* data,
 -                                            struct zxdg_popup_v6* xdg_popup,
@@ -1337,7 +1488,7 @@ index 98e101135..9a56f350d 100644
      sl_internal_xdg_popup_configure, sl_internal_xdg_popup_done};
  
  static void sl_window_set_wm_state(struct sl_window* window, int state) {
-@@ -654,15 +654,15 @@ void sl_window_update(struct sl_window* window) {
+@@ -759,15 +759,15 @@ void sl_window_update(struct sl_window* window) {
        window->aura_surface = NULL;
      }
      if (window->xdg_toplevel) {
@@ -1356,18 +1507,7 @@ index 98e101135..9a56f350d 100644
        window->xdg_surface = NULL;
      }
      window->realized = 0;
-@@ -673,8 +673,8 @@ void sl_window_update(struct sl_window* window) {
-   assert(host_surface);
-   assert(!host_surface->has_role);
- 
--  assert(ctx->xdg_shell);
--  assert(ctx->xdg_shell->internal);
-+  assert(ctx->xdg_wm_base);
-+  assert(ctx->xdg_wm_base->internal);
- 
-   if (window->managed) {
-     if (window->transient_for != XCB_WINDOW_NONE) {
-@@ -736,11 +736,11 @@ void sl_window_update(struct sl_window* window) {
+@@ -843,11 +843,11 @@ void sl_window_update(struct sl_window* window) {
    }
  
    if (!window->xdg_surface) {
@@ -1376,25 +1516,26 @@ index 98e101135..9a56f350d 100644
 -    zxdg_surface_v6_set_user_data(window->xdg_surface, window);
 -    zxdg_surface_v6_add_listener(window->xdg_surface,
 -                                 &sl_internal_xdg_surface_listener, window);
-+    window->xdg_surface = xdg_wm_base_get_xdg_surface(
-+        ctx->xdg_wm_base->internal, host_surface->proxy);
++    window->xdg_surface = xdg_wm_base_get_xdg_surface(ctx->xdg_shell->internal,
++                                                      host_surface->proxy);
 +    xdg_surface_set_user_data(window->xdg_surface, window);
 +    xdg_surface_add_listener(window->xdg_surface,
 +                             &sl_internal_xdg_surface_listener, window);
    }
  
    if (ctx->aura_shell) {
-@@ -770,50 +770,50 @@ void sl_window_update(struct sl_window* window) {
+@@ -882,50 +882,46 @@ void sl_window_update(struct sl_window* window) {
    // window is closed.
    if (ctx->xwayland || !parent) {
      if (!window->xdg_toplevel) {
 -      window->xdg_toplevel = zxdg_surface_v6_get_toplevel(window->xdg_surface);
 -      zxdg_toplevel_v6_set_user_data(window->xdg_toplevel, window);
 -      zxdg_toplevel_v6_add_listener(window->xdg_toplevel,
+-                                    &sl_internal_xdg_toplevel_listener, window);
 +      window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
 +      xdg_toplevel_set_user_data(window->xdg_toplevel, window);
 +      xdg_toplevel_add_listener(window->xdg_toplevel,
-                                     &sl_internal_xdg_toplevel_listener, window);
++                                &sl_internal_xdg_toplevel_listener, window);
      }
      if (parent)
 -      zxdg_toplevel_v6_set_parent(window->xdg_toplevel, parent->xdg_toplevel);
@@ -1404,15 +1545,19 @@ index 98e101135..9a56f350d 100644
 +      xdg_toplevel_set_title(window->xdg_toplevel, window->name);
      if (window->size_flags & P_MIN_SIZE) {
 -      zxdg_toplevel_v6_set_min_size(window->xdg_toplevel,
+-                                    window->min_width / ctx->scale,
+-                                    window->min_height / ctx->scale);
 +      xdg_toplevel_set_min_size(window->xdg_toplevel,
-                                     window->min_width / ctx->scale,
-                                     window->min_height / ctx->scale);
++                                window->min_width / ctx->scale,
++                                window->min_height / ctx->scale);
      }
      if (window->size_flags & P_MAX_SIZE) {
 -      zxdg_toplevel_v6_set_max_size(window->xdg_toplevel,
+-                                    window->max_width / ctx->scale,
+-                                    window->max_height / ctx->scale);
 +      xdg_toplevel_set_max_size(window->xdg_toplevel,
-                                     window->max_width / ctx->scale,
-                                     window->max_height / ctx->scale);
++                                window->max_width / ctx->scale,
++                                window->max_height / ctx->scale);
      }
      if (window->maximized) {
 -      zxdg_toplevel_v6_set_maximized(window->xdg_toplevel);
@@ -1423,97 +1568,73 @@ index 98e101135..9a56f350d 100644
 +    struct xdg_positioner* positioner;
  
 -    positioner = zxdg_shell_v6_create_positioner(ctx->xdg_shell->internal);
-+    positioner = xdg_wm_base_create_positioner(ctx->xdg_wm_base->internal);
++    positioner = xdg_wm_base_create_positioner(ctx->xdg_shell->internal);
      assert(positioner);
 -    zxdg_positioner_v6_set_anchor(
-+    xdg_positioner_set_anchor(
-         positioner,
+-        positioner,
 -        ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_LEFT);
 -    zxdg_positioner_v6_set_gravity(
-+        XDG_POSITIONER_ANCHOR_TOP | XDG_POSITIONER_ANCHOR_LEFT);
-+    xdg_positioner_set_gravity(
-         positioner,
+-        positioner,
 -        ZXDG_POSITIONER_V6_GRAVITY_BOTTOM | ZXDG_POSITIONER_V6_GRAVITY_RIGHT);
 -    zxdg_positioner_v6_set_anchor_rect(
-+        XDG_POSITIONER_GRAVITY_BOTTOM | XDG_POSITIONER_GRAVITY_RIGHT);
-+    xdg_positioner_set_anchor_rect(
-         positioner, (window->x - parent->x) / ctx->scale,
-         (window->y - parent->y) / ctx->scale, 1, 1);
+-        positioner, (window->x - parent->x) / ctx->scale,
+-        (window->y - parent->y) / ctx->scale, 1, 1);
++    xdg_positioner_set_anchor(positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
++    xdg_positioner_set_gravity(positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
++    xdg_positioner_set_anchor_rect(positioner,
++                                   (window->x - parent->x) / ctx->scale,
++                                   (window->y - parent->y) / ctx->scale, 1, 1);
  
 -    window->xdg_popup = zxdg_surface_v6_get_popup(
-+    window->xdg_popup = xdg_surface_get_popup(
-         window->xdg_surface, parent->xdg_surface, positioner);
+-        window->xdg_surface, parent->xdg_surface, positioner);
 -    zxdg_popup_v6_set_user_data(window->xdg_popup, window);
 -    zxdg_popup_v6_add_listener(window->xdg_popup,
+-                               &sl_internal_xdg_popup_listener, window);
++    window->xdg_popup = xdg_surface_get_popup(window->xdg_surface,
++                                              parent->xdg_surface, positioner);
 +    xdg_popup_set_user_data(window->xdg_popup, window);
-+    xdg_popup_add_listener(window->xdg_popup,
-                                &sl_internal_xdg_popup_listener, window);
++    xdg_popup_add_listener(window->xdg_popup, &sl_internal_xdg_popup_listener,
++                           window);
  
 -    zxdg_positioner_v6_destroy(positioner);
 +    xdg_positioner_destroy(positioner);
    }
  
    if ((window->size_flags & (US_POSITION | P_POSITION)) && parent &&
-@@ -1177,22 +1177,23 @@ static void sl_registry_handler(void* data,
+@@ -1326,7 +1322,7 @@ static void sl_registry_handler(void* data,
        data_device_manager->host_global =
            sl_data_device_manager_global_create(ctx);
      }
 -  } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
--    struct sl_xdg_shell* xdg_shell = malloc(sizeof(struct sl_xdg_shell));
--    assert(xdg_shell);
--    xdg_shell->ctx = ctx;
--    xdg_shell->id = id;
--    xdg_shell->internal = NULL;
--    xdg_shell->host_global = NULL;
--    assert(!ctx->xdg_shell);
--    ctx->xdg_shell = xdg_shell;
 +  } else if (strcmp(interface, "xdg_wm_base") == 0) {
-+    struct sl_xdg_wm_base* xdg_wm_base = malloc(sizeof(struct sl_xdg_wm_base));
-+    assert(xdg_wm_base);
-+    xdg_wm_base->ctx = ctx;
-+    xdg_wm_base->id = id;
-+    xdg_wm_base->version = MIN(2, version);
-+    xdg_wm_base->internal = NULL;
-+    xdg_wm_base->host_global = NULL;
-+    assert(!ctx->xdg_wm_base);
-+    ctx->xdg_wm_base = xdg_wm_base;
+     struct sl_xdg_shell* xdg_shell =
+         static_cast<sl_xdg_shell*>(malloc(sizeof(struct sl_xdg_shell)));
+     assert(xdg_shell);
+@@ -1337,10 +1333,10 @@ static void sl_registry_handler(void* data,
+     assert(!ctx->xdg_shell);
+     ctx->xdg_shell = xdg_shell;
      if (ctx->xwayland) {
--      xdg_shell->internal =
--          wl_registry_bind(registry, id, &zxdg_shell_v6_interface, 1);
+-      xdg_shell->internal = static_cast<zxdg_shell_v6*>(
+-          wl_registry_bind(registry, id, &zxdg_shell_v6_interface, 1));
 -      zxdg_shell_v6_add_listener(xdg_shell->internal,
 -                                 &sl_internal_xdg_shell_listener, NULL);
-+      xdg_wm_base->internal =
-+          wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
-+      xdg_wm_base_add_listener(xdg_wm_base->internal,
-+                                 &sl_internal_xdg_wm_base_listener, NULL);
++      xdg_shell->internal = static_cast<xdg_wm_base*>(
++          wl_registry_bind(registry, id, &xdg_wm_base_interface, 1));
++      xdg_wm_base_add_listener(xdg_shell->internal,
++                               &sl_internal_xdg_shell_listener, NULL);
      } else {
--      xdg_shell->host_global = sl_xdg_shell_global_create(ctx);
-+      xdg_wm_base->host_global = sl_xdg_wm_base_global_create(ctx);
+       xdg_shell->host_global = sl_xdg_shell_global_create(ctx);
      }
-   } else if (strcmp(interface, "zaura_shell") == 0) {
-     if (version >= MIN_AURA_SHELL_VERSION) {
-@@ -1299,13 +1300,13 @@ static void sl_registry_remover(void* data,
-     ctx->data_device_manager = NULL;
-     return;
-   }
--  if (ctx->xdg_shell && ctx->xdg_shell->id == id) {
--    if (ctx->xdg_shell->host_global)
--      sl_global_destroy(ctx->xdg_shell->host_global);
--    if (ctx->xdg_shell->internal)
+@@ -1473,7 +1469,7 @@ static void sl_registry_remover(void* data,
+     if (ctx->xdg_shell->host_global)
+       sl_global_destroy(ctx->xdg_shell->host_global);
+     if (ctx->xdg_shell->internal)
 -      zxdg_shell_v6_destroy(ctx->xdg_shell->internal);
--    free(ctx->xdg_shell);
--    ctx->xdg_shell = NULL;
-+  if (ctx->xdg_wm_base && ctx->xdg_wm_base->id == id) {
-+    if (ctx->xdg_wm_base->host_global)
-+      sl_global_destroy(ctx->xdg_wm_base->host_global);
-+    if (ctx->xdg_wm_base->internal)
-+      xdg_wm_base_destroy(ctx->xdg_wm_base->internal);
-+    free(ctx->xdg_wm_base);
-+    ctx->xdg_wm_base = NULL;
++      xdg_wm_base_destroy(ctx->xdg_shell->internal);
+     free(ctx->xdg_shell);
+     ctx->xdg_shell = NULL;
      return;
-   }
-   if (ctx->aura_shell && ctx->aura_shell->id == id) {
-@@ -1467,11 +1468,11 @@ static void sl_destroy_window(struct sl_window* window) {
+@@ -1650,11 +1646,11 @@ static void sl_destroy_window(struct sl_window* window) {
    }
  
    if (window->xdg_popup)
@@ -1528,7 +1649,7 @@ index 98e101135..9a56f350d 100644
    if (window->aura_surface)
      zaura_surface_destroy(window->aura_surface);
  
-@@ -1915,15 +1916,15 @@ static void sl_handle_configure_request(struct sl_context* ctx,
+@@ -2118,15 +2114,15 @@ static void sl_handle_configure_request(struct sl_context* ctx,
    // that matching contents will arrive.
    if (window->xdg_toplevel) {
      if (window->pending_config.serial) {
@@ -1548,7 +1669,7 @@ index 98e101135..9a56f350d 100644
        window->next_config.serial = 0;
        window->next_config.mask = 0;
        window->next_config.states_length = 0;
-@@ -2044,23 +2045,23 @@ static void sl_handle_configure_notify(struct sl_context* ctx,
+@@ -2247,23 +2243,23 @@ static void sl_handle_configure_notify(struct sl_context* ctx,
  static uint32_t sl_resize_edge(int net_wm_moveresize_size) {
    switch (net_wm_moveresize_size) {
      case NET_WM_MOVERESIZE_SIZE_TOPLEFT:
@@ -1581,13 +1702,14 @@ index 98e101135..9a56f350d 100644
    }
  }
  
-@@ -2107,15 +2108,15 @@ static void sl_handle_client_message(struct sl_context* ctx,
+@@ -2362,16 +2358,16 @@ static void sl_handle_client_message(struct sl_context* ctx,
          return;
  
        if (event->data.data32[2] == NET_WM_MOVERESIZE_MOVE) {
 -        zxdg_toplevel_v6_move(window->xdg_toplevel, seat->proxy,
+-                              seat->seat->last_serial);
 +        xdg_toplevel_move(window->xdg_toplevel, seat->proxy,
-                               seat->seat->last_serial);
++                          seat->seat->last_serial);
        } else {
          uint32_t edge = sl_resize_edge(event->data.data32[2]);
  
@@ -1596,13 +1718,15 @@ index 98e101135..9a56f350d 100644
            return;
  
 -        zxdg_toplevel_v6_resize(window->xdg_toplevel, seat->proxy,
+-                                seat->seat->last_serial, edge);
 +        xdg_toplevel_resize(window->xdg_toplevel, seat->proxy,
-                                 seat->seat->last_serial, edge);
++                            seat->seat->last_serial, edge);
        }
      }
-@@ -2134,24 +2135,24 @@ static void sl_handle_client_message(struct sl_context* ctx,
- 
-       if (changed[ATOM_NET_WM_STATE_FULLSCREEN]) {
+   } else if (event->type == ctx->atoms[ATOM_NET_WM_STATE].value) {
+@@ -2392,9 +2388,9 @@ static void sl_handle_client_message(struct sl_context* ctx,
+                     "action", net_wm_state_to_string(action), "window->name",
+                     window->name);
          if (action == NET_WM_STATE_ADD)
 -          zxdg_toplevel_v6_set_fullscreen(window->xdg_toplevel, NULL);
 +          xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
@@ -1612,7 +1736,9 @@ index 98e101135..9a56f350d 100644
        }
  
        if (changed[ATOM_NET_WM_STATE_MAXIMIZED_VERT] &&
-           changed[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
+@@ -2405,9 +2401,9 @@ static void sl_handle_client_message(struct sl_context* ctx,
+             "action", net_wm_state_to_string(action), "window->name",
+             window->name);
          if (action == NET_WM_STATE_ADD)
 -          zxdg_toplevel_v6_set_maximized(window->xdg_toplevel);
 +          xdg_toplevel_set_maximized(window->xdg_toplevel);
@@ -1622,15 +1748,16 @@ index 98e101135..9a56f350d 100644
        }
      }
    } else if (event->type == ctx->atoms[ATOM_WM_CHANGE_STATE].value &&
-              event->data.data32[0] == WM_STATE_ICONIC) {
-     struct sl_window* window = sl_lookup_window(ctx, event->window);
+@@ -2416,7 +2412,7 @@ static void sl_handle_client_message(struct sl_context* ctx,
+     TRACE_EVENT("x11wm", "XCB_CLIENT_MESSAGE: WM_STATE_ICONIC (minimize)",
+                 "window->name", window ? window->name : "<unknown>");
      if (window && window->xdg_toplevel) {
 -      zxdg_toplevel_v6_set_minimized(window->xdg_toplevel);
 +      xdg_toplevel_set_minimized(window->xdg_toplevel);
      }
    }
  }
-@@ -2164,7 +2165,7 @@ static void sl_handle_focus_in(struct sl_context* ctx,
+@@ -2429,7 +2425,7 @@ static void sl_handle_focus_in(struct sl_context* ctx,
      // window was realized.
      struct sl_window* parent = sl_lookup_window(ctx, window->transient_for);
      if (parent && parent->xdg_toplevel && window->xdg_toplevel)
@@ -1639,7 +1766,7 @@ index 98e101135..9a56f350d 100644
    }
  }
  
-@@ -2381,9 +2382,9 @@ static void sl_handle_property_notify(struct sl_context* ctx,
+@@ -2738,9 +2734,9 @@ static void sl_handle_property_notify(struct sl_context* ctx,
        return;
  
      if (window->name) {
@@ -1651,14 +1778,16 @@ index 98e101135..9a56f350d 100644
      }
    } else if (event->atom == XCB_ATOM_WM_CLASS) {
      struct sl_window* window = sl_lookup_window(ctx, event->window);
-@@ -2435,19 +2436,19 @@ static void sl_handle_property_notify(struct sl_context* ctx,
+@@ -2796,19 +2792,19 @@ static void sl_handle_property_notify(struct sl_context* ctx,
        return;
  
      if (window->size_flags & P_MIN_SIZE) {
 -      zxdg_toplevel_v6_set_min_size(window->xdg_toplevel,
+-                                    window->min_width / ctx->scale,
+-                                    window->min_height / ctx->scale);
 +      xdg_toplevel_set_min_size(window->xdg_toplevel,
-                                     window->min_width / ctx->scale,
-                                     window->min_height / ctx->scale);
++                                window->min_width / ctx->scale,
++                                window->min_height / ctx->scale);
      } else {
 -      zxdg_toplevel_v6_set_min_size(window->xdg_toplevel, 0, 0);
 +      xdg_toplevel_set_min_size(window->xdg_toplevel, 0, 0);
@@ -1666,62 +1795,31 @@ index 98e101135..9a56f350d 100644
  
      if (window->size_flags & P_MAX_SIZE) {
 -      zxdg_toplevel_v6_set_max_size(window->xdg_toplevel,
+-                                    window->max_width / ctx->scale,
+-                                    window->max_height / ctx->scale);
 +      xdg_toplevel_set_max_size(window->xdg_toplevel,
-                                     window->max_width / ctx->scale,
-                                     window->max_height / ctx->scale);
++                                window->max_width / ctx->scale,
++                                window->max_height / ctx->scale);
      } else {
 -      zxdg_toplevel_v6_set_max_size(window->xdg_toplevel, 0, 0);
 +      xdg_toplevel_set_max_size(window->xdg_toplevel, 0, 0);
      }
    } else if (event->atom == XCB_ATOM_WM_HINTS) {
      struct sl_window* window = sl_lookup_window(ctx, event->window);
-@@ -3535,7 +3536,7 @@ int main(int argc, char** argv) {
-       .shm = NULL,
-       .shell = NULL,
-       .data_device_manager = NULL,
--      .xdg_shell = NULL,
-+      .xdg_wm_base = NULL,
-       .aura_shell = NULL,
-       .viewporter = NULL,
-       .linux_dmabuf = NULL,
 diff --git a/vm_tools/sommelier/sommelier.h b/vm_tools/sommelier/sommelier.h
-index b851b5c8d..7e6daf773 100644
+index 1e00a0b981..f07a826c99 100644
 --- a/vm_tools/sommelier/sommelier.h
 +++ b/vm_tools/sommelier/sommelier.h
-@@ -31,7 +31,7 @@ struct sl_shell;
- struct sl_data_device_manager;
- struct sl_data_offer;
- struct sl_data_source;
--struct sl_xdg_shell;
-+struct sl_xdg_wm_base;
- struct sl_subcompositor;
- struct sl_aura_shell;
- struct sl_viewporter;
-@@ -99,7 +99,7 @@ struct sl_context {
-   struct sl_shm* shm;
-   struct sl_shell* shell;
-   struct sl_data_device_manager* data_device_manager;
--  struct sl_xdg_shell* xdg_shell;
-+  struct sl_xdg_wm_base* xdg_wm_base;
-   struct sl_aura_shell* aura_shell;
-   struct sl_viewporter* viewporter;
-   struct sl_linux_dmabuf* linux_dmabuf;
-@@ -373,11 +373,12 @@ struct sl_viewporter {
-   struct wp_viewporter* internal;
- };
- 
--struct sl_xdg_shell {
-+struct sl_xdg_wm_base {
+@@ -411,7 +411,7 @@ struct sl_xdg_shell {
    struct sl_context* ctx;
    uint32_t id;
-+  uint32_t version;
    struct sl_global* host_global;
 -  struct zxdg_shell_v6* internal;
 +  struct xdg_wm_base* internal;
  };
  
  struct sl_aura_shell {
-@@ -476,9 +477,9 @@ struct sl_window {
+@@ -511,9 +511,9 @@ struct sl_window {
    int max_height;
    struct sl_config next_config;
    struct sl_config pending_config;
@@ -1734,15 +1832,6 @@ index b851b5c8d..7e6daf773 100644
    struct zaura_surface* aura_surface;
    struct wl_list link;
  };
-@@ -522,7 +523,7 @@ struct sl_global* sl_data_device_manager_global_create(struct sl_context* ctx);
- 
- struct sl_global* sl_viewporter_global_create(struct sl_context* ctx);
- 
--struct sl_global* sl_xdg_shell_global_create(struct sl_context* ctx);
-+struct sl_global* sl_xdg_wm_base_global_create(struct sl_context* ctx);
- 
- struct sl_global* sl_gtk_shell_global_create(struct sl_context* ctx);
- 
 -- 
-2.26.2
+2.30.0
 
diff --git a/pkgs/os-specific/linux/chromium-os/sommelier/0006-sommelier-make-building-demos-optional.patch b/pkgs/os-specific/linux/chromium-os/sommelier/0006-sommelier-make-building-demos-optional.patch
deleted file mode 100644
index ecc876e4bfb..00000000000
--- a/pkgs/os-specific/linux/chromium-os/sommelier/0006-sommelier-make-building-demos-optional.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 6a4ccbcded19df9ec42b865218ac744e6b35d505 Mon Sep 17 00:00:00 2001
-From: Alyssa Ross <hi@alyssa.is>
-Date: Wed, 15 Jan 2020 21:36:43 +0000
-Subject: [PATCH 6/6] sommelier: make building demos optional
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-pkg-config was checked at GN evaluation time for libbrillo and
-libchrome, meaning that there was no way to build sommelier without
-them, even though they were only required for the demos, not for
-sommelier itself.
-
-Making the demo optional saves having to libbrillo and libchrome for
-the common case of building just sommelier, which themselves have lots
-of unusual dependencies.
-
-Thanks-to: Tomasz Ĺšniatowski <tsniatowski@vewd.com>
----
- vm_tools/sommelier/BUILD.gn | 54 ++++++++++++++++++++++---------------
- 1 file changed, 32 insertions(+), 22 deletions(-)
-
-diff --git a/vm_tools/sommelier/BUILD.gn b/vm_tools/sommelier/BUILD.gn
-index 4330560a1..cbb752745 100644
---- a/vm_tools/sommelier/BUILD.gn
-+++ b/vm_tools/sommelier/BUILD.gn
-@@ -4,12 +4,20 @@
- 
- import("wayland_protocol.gni")
- 
-+declare_args() {
-+  use_demos = true
-+}
-+
- group("all") {
-   deps = [
-     ":sommelier",
--    ":wayland_demo",
--    ":x11_demo",
-   ]
-+  if (use_demos) {
-+    deps += [
-+      ":wayland_demo",
-+      ":x11_demo",
-+    ]
-+  }
- }
- 
- if (!defined(peer_cmd_prefix)) {
-@@ -123,25 +131,27 @@ executable("sommelier") {
-   ]
- }
- 
--executable("wayland_demo") {
--  pkg_deps = [
--    "libbrillo",
--    "libchrome-${libbase_ver}",
--    "wayland-client",
--  ]
--  libs = [ "wayland-client" ]
--  sources = [
--    "demos/wayland_demo.cc",
--  ]
--}
-+if (use_demos) {
-+  executable("wayland_demo") {
-+    pkg_deps = [
-+      "libbrillo",
-+      "libchrome-${libbase_ver}",
-+      "wayland-client",
-+    ]
-+    libs = [ "wayland-client" ]
-+    sources = [
-+      "demos/wayland_demo.cc",
-+    ]
-+  }
- 
--executable("x11_demo") {
--  pkg_deps = [
--    "libbrillo",
--    "libchrome-${libbase_ver}",
--  ]
--  libs = [ "X11" ]
--  sources = [
--    "demos/x11_demo.cc",
--  ]
-+  executable("x11_demo") {
-+    pkg_deps = [
-+      "libbrillo",
-+      "libchrome-${libbase_ver}",
-+    ]
-+    libs = [ "X11" ]
-+    sources = [
-+      "demos/x11_demo.cc",
-+    ]
-+  }
- }
--- 
-2.26.2
-
diff --git a/pkgs/os-specific/linux/chromium-os/sommelier/default.nix b/pkgs/os-specific/linux/chromium-os/sommelier/default.nix
index 9bf2777bfd7..c995689c4f5 100644
--- a/pkgs/os-specific/linux/chromium-os/sommelier/default.nix
+++ b/pkgs/os-specific/linux/chromium-os/sommelier/default.nix
@@ -7,9 +7,8 @@ common-mk {
   platformSubdir = "vm_tools/sommelier";
 
   platform2Patches = [
-    ./0004-sommelier-don-t-leak-source-absolute-paths.patch
-    ./0005-sommelier-use-stable-xdg-shell-protocol.patch
-    ./0006-sommelier-make-building-demos-optional.patch
+    ./0003-sommelier-don-t-leak-source-absolute-paths.patch
+    ./0004-Revert-Revert-vm_tools-sommelier-Switch-to-the-stabl.patch
   ];
 
   buildInputs = [
diff --git a/pkgs/os-specific/linux/chromium-os/upstream-info.json b/pkgs/os-specific/linux/chromium-os/upstream-info.json
index 7755c48239c..cec5a21b1e4 100644
--- a/pkgs/os-specific/linux/chromium-os/upstream-info.json
+++ b/pkgs/os-specific/linux/chromium-os/upstream-info.json
@@ -1,66 +1,66 @@
 {
-  "version": "83.13020.0.0-rc1",
+  "version": "89.13729.0.0-rc1",
   "components": {
     "src/aosp/external/minijail": {
       "name": "minijail",
       "url": "https://android.googlesource.com/platform/external/minijail",
-      "rev": "84ffabcf488bf0935f00930a9a23bbce1f34d79f",
-      "sha256": "0yhbklwmgqws4cb098hpaky4w8if5snpkdabridcc5hk5d7vgild"
+      "rev": "b49291144e126662b8c7d1551fd1dc572e1d55da",
+      "sha256": "19z0qrfyh7p2kmsgvm4k053vrzz2w6zysqh3bm2rx0irsdv0pnqm"
     },
     "src/platform/crosvm": {
       "name": "crosvm",
       "url": "https://chromium.googlesource.com/chromiumos/platform/crosvm",
-      "rev": "664cc3ca49cb58d5bf7d936686fd211d6dd728bf",
-      "sha256": "0rms1hkb3r4w6j3l71gavky6ylc7gi9sfr2rq4dr82v6vc8zxbjx"
+      "rev": "f35d2c43ff19520855cffee761dc8899c5a439a1",
+      "sha256": "0fahrcw7x33d21i6azgr787afrhp002f8mvz81ich5w7vk2xjzxr"
     },
     "src/platform/minigbm": {
       "name": "minigbm",
       "url": "https://chromium.googlesource.com/chromiumos/platform/minigbm",
-      "rev": "bc4f023bfcc51cf9dcfcfec5bf4177b2e607dd68",
-      "sha256": "08ag207199xj5cw686386rmvr7sx2mzihdckm2pnvw743w03gipr"
+      "rev": "9fe8c20f05116869f86d91fc542a17b9badf9ec3",
+      "sha256": "0gr81qngfa1g58cz3v9dlms997ry3h5dh7vcv2ak1j53dzfdzckn"
     },
     "src/platform2": {
       "name": "platform2",
       "url": "https://chromium.googlesource.com/chromiumos/platform2",
-      "rev": "e45d54bedee94e0121e12cc86fded46be8b3fa4e",
-      "sha256": "0ag01p8ch0wn7ds9ywasrdxkbibg19qzf5rldf8nr8irk1n851n7"
+      "rev": "e6e2faf2abb10fcbca3b6eccdcf7cf2506bcc212",
+      "sha256": "1g6kxmiffizqlxwakma1rp26p9mwpjbl3cv5hn7k5zd6cn8wixj7"
     },
     "src/third_party/adhd": {
       "name": "adhd",
       "url": "https://chromium.googlesource.com/chromiumos/third_party/adhd",
-      "rev": "d3af897db5540cadc439463a0ffdde07f2b8898a",
-      "sha256": "1h0xxf338d7fwmfwjlpsjiml8d3v426a95x3ka7qfikdapgmav3d"
+      "rev": "0458a459ad51cc0b386835f5b909d0d04003ab16",
+      "sha256": "1y1g0h2dcmgpz9nk2hc6fcb0c53ip3mf27yyf7gg6syx764pr2gb"
     },
     "src/third_party/chromiumos-overlay": {
       "name": "chromiumos-overlay",
       "url": "https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay",
-      "rev": "270f5c2cfb7eadc374638076c8fdee72360a6d66",
-      "sha256": "1d88xvnf0qc3v5hp9b2pafxhi83rph84y2sbk1nc46rhj63m8bwi"
+      "rev": "dd29be74a5c6fa492411ec7feed734004c6a1ea5",
+      "sha256": "0pbrbbr39j9zsc10dhhhmwx1c69a40nsv4cprh7biz1b8f840l1b"
     },
     "src/third_party/kernel/v5.4": {
       "name": "v5.4",
       "url": "https://chromium.googlesource.com/chromiumos/third_party/kernel",
-      "rev": "36270ae817fb576debb80bce752addb3a4cc9886",
-      "sha256": "0h7fj3w9vwmq8a6cx96vjcyw29v7wfamxykh1nx3lmhxxkn120f4",
-      "version": "5.4.28"
+      "rev": "eb179ec7ef3e053acb48366e72299055b2b66ca8",
+      "sha256": "13i7f3742cnw7lm0b2zal4lxbqrkmniajqp5c1gllvrfvxcw4a45",
+      "version": "5.4.88"
     },
     "src/third_party/libqmi": {
       "name": "libqmi",
       "url": "https://chromium.googlesource.com/chromiumos/third_party/libqmi",
-      "rev": "20726755e60d48c70f0189a1cfe9665a87a5e6c6",
-      "sha256": "0w04lyd459jgcag70kx6nq1i952fbhy32nmkh6r255xjf2wrliwr"
+      "rev": "072abd58da99c00b79dbf7e4642fa19fb791aed9",
+      "sha256": "1a6x5hwghkrvi82szhabxf2by4x7x9pfk6bvpgz0ipz8yqg8fwih"
     },
     "src/third_party/modemmanager-next": {
       "name": "modemmanager-next",
       "url": "https://chromium.googlesource.com/chromiumos/third_party/modemmanager-next",
-      "rev": "988f572cc882a74209fba0f5c49cf0b01b9163a6",
-      "sha256": "1hiqz7wn1w461sd94v179q81yahisffnw033yix3dwfwagm9ndf8"
+      "rev": "3eba6678dfe0d7b35f128bb58b63e71d1a3a64d4",
+      "sha256": "0lviwkkqsv5zmajqdlc0s83yq12ikk0gf7wq9za58p92g0970i4l"
     },
     "src/third_party/modp_b64": {
       "name": "modp_b64",
       "url": "https://chromium.googlesource.com/aosp/platform/external/modp_b64",
-      "rev": "ae26ad8516036774fd3b6e84a98a89955dcf5f61",
-      "sha256": "03ja5fkq3wk0qcnfnqcj09lciky6n6zdj544xs1jfssjhz9yj8hi"
+      "rev": "467734f4870d3ab23968f5ebdd461f6112e4103b",
+      "sha256": "1hlk9vzivy0n3xf9hm9bhj7i09yifirc1af6pli471m00v3s0zvg"
     }
   }
 }
diff --git a/pkgs/os-specific/linux/chromium-os/vm_protos/0003-vm_tools-proto-fix-parallel-build.patch b/pkgs/os-specific/linux/chromium-os/vm_protos/0003-vm_tools-proto-fix-parallel-build.patch
deleted file mode 100644
index 93fa535ac7e..00000000000
--- a/pkgs/os-specific/linux/chromium-os/vm_protos/0003-vm_tools-proto-fix-parallel-build.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From dfed9458bf7abc1dc8f33a3e16ee179cde88e4e2 Mon Sep 17 00:00:00 2001
-From: Alyssa Ross <hi@alyssa.is>
-Date: Tue, 2 Jun 2020 00:21:08 +0000
-Subject: [PATCH 3/6] vm_tools: proto: fix parallel build
-
-fuzzer-protos depends on vm-crash-rpcs, but this dependency wasn't
-declared, causing build failures like the following:
-
-[26/52] CXX obj/out/Release/gen/include/vm_protos/proto_bindings/libfuzzer-protos.fuzzer.grpc.pb.o
-FAILED: obj/out/Release/gen/include/vm_protos/proto_bindings/libfuzzer-protos.fuzzer.grpc.pb.o
-c++ -MMD -MF obj/out/Release/gen/include/vm_protos/proto_bindings/libfuzzer-protos.fuzzer.grpc.pb.o.d -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Igen/include -I../../common-mk -I/usr/include -Igen -Igen -Igen -Igen -Wall -Wunused -Wno-unused-parameter -Wunreachable-code -ggdb3 -fstack-protector-strong -Wformat=2 -fvisibility=internal -Wa,--noexecstack -Wimplicit-fallthrough -Werror --sysroot= -fPIE -fvisibility=default -pthread -I/nix/store/pjl2q3lny3c18ypqjcv0q3akyq89hg2i-grpc-1.28.1/include -I/nix/store/hya0y6slws66h99njc2yiz02irfv4n62-openssl-1.1.1g-dev/include -I/nix/store/mfpg3sk5vk9rm99hbpmd3dgvxqybd391-protobuf-3.8.0/include -pthread -I/nix/store/pjl2q3lny3c18ypqjcv0q3akyq89hg2i-grpc-1.28.1/include -I/nix/store/hya0y6slws66h99njc2yiz02irfv4n62-openssl-1.1.1g-dev/include -I/nix/store/mfpg3sk5vk9rm99hbpmd3dgvxqybd391-protobuf-3.8.0/include -Wno-unreachable-code -std=gnu++14 -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -Wno-psabi -c gen/include/vm_protos/proto_bindings/fuzzer.grpc.pb.cc -o obj/out/Release/gen/include/vm_protos/proto_bindings/libfuzzer-protos.fuzzer.grpc.pb.o
-In file included from gen/include/vm_protos/proto_bindings/fuzzer.grpc.pb.cc:5:
-gen/include/vm_protos/proto_bindings/fuzzer.pb.h:38:10: fatal error: vm_crash.pb.h: No such file or directory
-   38 | #include "vm_crash.pb.h"
-      |          ^~~~~~~~~~~~~~~
-compilation terminated.
-ninja: build stopped: subcommand failed.
-
-Reported-by: Cole Helbling <cole.e.helbling@outlook.com>
-Reviewed-by: Cole Helbling <cole.e.helbling@outlook.com>
----
- vm_tools/proto/BUILD.gn | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/vm_tools/proto/BUILD.gn b/vm_tools/proto/BUILD.gn
-index 713b81853..a25265cab 100644
---- a/vm_tools/proto/BUILD.gn
-+++ b/vm_tools/proto/BUILD.gn
-@@ -70,6 +70,7 @@ proto_library("fuzzer-protos") {
-   deps = [
-     ":container-rpcs",
-     ":tremplin-rpcs",
-+    ":vm-crash-rpcs",
-   ]
-   sources = [
-     "${proto_in_dir}/fuzzer.proto",
--- 
-2.26.2
-
diff --git a/pkgs/os-specific/linux/chromium-os/vm_protos/default.nix b/pkgs/os-specific/linux/chromium-os/vm_protos/default.nix
index 4f0aae3be38..e87d0c57e78 100644
--- a/pkgs/os-specific/linux/chromium-os/vm_protos/default.nix
+++ b/pkgs/os-specific/linux/chromium-os/vm_protos/default.nix
@@ -12,8 +12,6 @@ common-mk {
     "-Wno-error=deprecated-declarations"
   ];
 
-  platform2Patches = [ ./0003-vm_tools-proto-fix-parallel-build.patch ];
-
   postPatch = ''
     substituteInPlace common-mk/proto_library.gni \
         --replace /usr/bin/grpc_cpp_plugin ${grpc}/bin/grpc_cpp_plugin