xref: /cloud-hypervisor/docs/windows.md (revision f7f2f25a574b1b2dba22c094fc8226d404157d15)
1# Windows Support
2
3Starting with the release version [0.10.0](https://github.com/cloud-hypervisor/cloud-hypervisor/releases/tag/v0.10.0), Cloud Hypervisor supports Windows guests.
4
5__Requirements__
6
7- Host with KVM enabled
8- [UEFI](uefi.md) capable Windows guest image with Virtio drivers integrated
9
10Any modern Windows Server version is compatible. Cloud Hypervisor has been successfully tested with Windows Server 2019 and Windows Server Core 2004.
11
12At the current stage, only UEFI capable Windows images are supported. This implies the presence of the OVMF firmware during the Windows installation and in any subsequent usage. BIOS boot is not supported.
13
14The subsequent sections will tell, in detail, how to prepare an appropriate Windows image.
15
16## Image Preparation
17
18### Installation using the stock Windows ISO
19
20__Prerequisites__
21
22- QEMU, version >=5.0.0 is recommended.
23- Windows installation ISO. Obtained through MSDN, Visual Studio subscription, evaluation center, etc.
24- [VirtIO driver ISO](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/)
25- Suitable [OVMF](uefi.md) firmware
26- With the suggested image size of 30G, there should be enough free disk space to hold the installation ISO and any other necessary files
27
28This step currently requires QEMU to install Windows onto the guest. QEMU is only used at the preparation stage, the resulting image is then fully functional with Cloud Hypervisor.
29
30Preparing several command parts as these will be used in the follow up sections as well.
31
32```shell
33IMG_FILE=windows-disk.raw
34WIN_ISO_FILE=en_windows_server_version_2004_updated_may_2020_x64_dvd_1e7f1cfa.iso
35VIRTIO_ISO_FILE=virtio-win-0.1.185.iso
36OVMF_DIR=./FV
37```
38
39Create an empty image file, `raw` is supported.
40```shell
41qemu-img create -f raw $IMG_FILE 30G
42```
43
44Begin the Windows installation process under QEMU
45```shell
46qemu-system-x86_64 \
47	-machine q35,accel=kvm \
48	-cpu host \
49	-m 4G \
50	-bios ./$OVMF_DIR/OVMF_CODE.fd \
51	-cdrom ./$WIN_ISO_FILE \
52	-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
53	-drive if=none,id=root,file=./$IMG_FILE \
54	-device virtio-blk-pci,drive=root,disable-legacy=on \
55	-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
56	-netdev user,id=mynet0 \
57	-vga std
58```
59
60Before the installation can proceed, point the Windows installation program to the VirtIO disk and install the necessary storage controller drivers. After that, the attached hard drive will become visible and the actual installation can commence.
61
62After the installation has completed, proceed further to the configuration section. QEMU will be needed at least once more to enable the Windows Special Administration Console (SAC) and to possibly install extra device drivers.
63
64## Image Usage
65
66The basic command to boot a Windows image. The configuration section should be checked before executing it for the first time.
67
68```shell
69cloud-hypervisor \
70	--kernel ./$OVMF_DIR/OVMF.fd \
71	--disk path=./$IMG_FILE \
72	--cpus boot=1,kvm_hyperv=on \
73	--memory size=4G \
74	--serial tty \
75	--console off \
76	--net tap=
77```
78
79It is necessary to always:
80
81- Carry the OVMF firmware in the `--kernel` option
82- Add `kvm_hyperv=on` to the `--cpus` option
83
84In cases where the host processor supports address space > 39 bits, it might be necessary to limit the address space. It can be done by appending the option `max_phys_bits=X` to the `--cpus` parameter, where `X` is the number of bits to be supported. Windows was tested to support at least 39-bit address space.
85
86To daemonize the Cloud Hypervisor process, `nohup` can be used. Some STDIO redirections might need to be done. In a simple case it is sufficient to just redirect all the output to `/dev/null`.
87
88## Image Configuration
89
90### Device Drivers
91
92After the Windows installation has finished under QEMU, there might be still devices with no drivers installed. This might happen for example, when a device was not used during the installation. In particular it is important to ensure that the VirtIO network device is setup correctly because further steps for the configuration and the usage require network in most case.
93
94Boot once more under QEMU and use the [Device Manager](https://support.microsoft.com/en-in/help/4028443/windows-10-update-drivers), to ensure all the device drivers, and especially the network card, are installed correctly. Also, as Cloud Hypervisor can introduce new devices, it is advisable to repeat the procedure while booted under Cloud Hypervisor, when the RDP access to the image is functional.
95
96### Windows Special Administration Console (SAC) enablement
97
98SAC provides a text based console access to the Windows guest. As Cloud Hypervisor doesn't implement a VGA adaptor, SAC is an important instrument for the Windows guest management.
99
100Boot the Windows image under QEMU and execute the below commands to permanently enable SAC
101
102```cmd
103bcdedit /emssettings emsport:1 emsbaudrate:115200
104bcdedit /ems on
105bcdedit /bootems on
106```
107
108Once SAC is enabled, the image can be booted under Cloud Hypervisor. The SAC prompt will show up
109
110<pre>
111Computer is booting, SAC started and initialized.
112
113Use the "ch -?" command for information about using channels.
114Use the "?" command for general help.
115
116
117SAC>
118</pre>
119
120To open a console on the guest, the command sequence below can be used
121<pre>
122SAC>cmd
123The Command Prompt session was successfully launched.
124SAC>
125EVENT:   A new channel has been created.  Use "ch -?" for channel help.
126Channel: Cmd0001
127SAC>ch -si 1
128</pre>
129
130See also the [links](#Links) section for a more extended SAC documentation.
131
132## Network
133
134This section illustrates the Windows specific corner points for the VM network configuration. For the extended networking guide, including bridging for multiple VMs, follow [networking.md](networking.md).
135
136### Basic Networking
137
138As the simplest option, using `--net tap=` in the Cloud Hypervisor command line will create a `vmtapX` device on the host with the default IPv4 adress `192.168.249.1`. After SAC becomes available, the guest configuration can be set with
139
140<pre>
141SAC>i 10 192.168.249.2 255.255.255.0 192.168.249.1
142</pre>
143
144Where `10` is the device index as shown by the `i` command.
145
146### Guest Internet Connectivity
147
148Additional steps are necessary to provide the guest with internet access.
149
150- On the guest, add the DNS server either by using `netsh` or by opening `Network and Connectivity Center` and editing the adapter properties.
151- On the host, configure the traffic forwarding. Replace the `NET_DEV` with the name of your network device.
152```shell
153NET_DEV=wlp3s0
154sysctl -w net.ipv4.ip_forward=1
155iptables -t nat -A POSTROUTING -o $NET_DEV -j MASQUERADE
156```
157
158### Remote Desktop Protocol (RDP) enablement
159
160#### Using QEMU
161  - Execute `SystemPropertiesRemote`
162  - In the properties window, choose "Allow remote connections to this computer"
163  - Click "Select Users" and add some user to the allow list
164#### Using powershell
165```powershell
166Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\" -Name "fDenyTSConnections" -Value 0
167Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
168Add-LocalGroupMember -Group "Remote Desktop Users" -Member someuser
169```
170
171Administrators can always RDP, non administrator users have to be explicitly enabled.
172
173Once the configuration is set, RDP clients can connect to `192.168.249.2`.
174
175### SSH
176
177#### Enable using powershell
178
179```powershell
180Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
181Start-Service sshd
182Set-Service -Name sshd -StartupType ‘Automatic’
183```
184
185This allows for SSH login from a remote machine, for example through the `administrator` user: `ssh administrator@192.168.249.2`. For a more detailed OpenSSH guide, please follow the MSDN article from the [links](#links) section.
186
187## Hotplug capability
188
189CPU hotplug is supported. The VM operating system needs to support hotplug and be appropriately licensed. SKU limitations like constraints on the number of cores are to be taken into consideration. Note, that Windows doesn't support CPU hot-remove. When `ch-remote` is invoked to reduce the number of CPUs, the result will be visible after the OS reboot within the same hypervisor instance.
190
191RAM hotplug is supported. Note, that while the `pnpmem.sys` driver in use supports RAM hot-remove, the RAM being unplugged has to be not in use and have no reserved pages. In most cases it means, hot-remove won't work. Same as with the CPU hot-remove, when `ch-remote` is invoked to reduce the RAM size, the result will be visible after the OS reboot.
192
193Network device hotplug and hot-remove are supported.
194
195Disk hotplug and hot-remove are supported. After the device has been hotplugged, it will need to be onlined from within the guest. Among other tools, powershell applets `Get-Disk` and `Set-Disk` can be used for the disk configuration and activation.
196
197## Debugging
198
199The Windows guest debugging process relies heavily on QEMU and [socat](http://www.dest-unreach.org/socat/). The procedure requires two Windows VMs:
200
201- A debugger VM running under QEMU.
202- A debuggee, a Windows VM that has been created in the previous steps, running under Cloud Hypervisor or QEMU.
203
204The connection between both guests happens over TCP, whereby on the guest side it is automatically translated to a COM port. Because the VMs are connected through TCP, the debugging infrastructure can be distributed over the network. The serial port, while slowly transferring data, is common enough to support a wide range of cases and tools.
205
206In this excercise, [WinDbg](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) is used. Any other debugger of choice with the ability to use serial connection can be used instead.
207
208### Debugger and Debuggee
209
210#### WinDbg VM
211
212For simplicity, the debugger VM is supposed to be only running under QEMU. It will require VGA and doesn't neccessarily depend on UEFI. As an OS, it can carry any supported Windows OS where the debugger of choice can be installed. The simplest way is to follow the image preparation instructions from the previous chapter, but avoid using the OVMF firmware. It is also not required to use VirtIO drivers, whereby it might be useful in some case. Though, while creating the image file for the debugger VM, be sure to choose a sufficient disk size that counts in the need to save the corresponding debug symbols and sources.
213
214To create the debugger Windows VM, the following command can be used:
215
216```shell
217qemu-system-x86_64 \
218	-machine q35,accel=kvm \
219	-cpu host \
220	-smp 1 \
221	-m 4G \
222	-cdrom ./$WIN_ISO_FILE \
223	-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
224	-drive if=none,id=root,file=./windbg-disk.raw \
225	-device virtio-blk-pci,drive=root,disable-legacy=on \
226	-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
227	-netdev user,id=mynet0,net=192.168.178.0/24,host=192.168.178.1,dhcpstart=192.168.178.64,hostname=windbg-host \
228	-vga std
229```
230
231A non server Windows OS like Windows 10 can be used to carry the debugging tools in the debugger VM.
232
233#### Debuggee VM
234
235The debuggee VM is the one that we've learned to configure and run in the first section. There might be various reasons to debug. For example, there could be an issue in the Windows guest with an emulated device or an included driver. Or, we might want to develop a custom feature like a kernel driver to be available in the guest.
236
237Note, that there are several ways to debug Windows, not all of them need to be enabled at the same time. For example, if developing a kernel module, the only useful options would be to configure for the serial debugging and enable the kernel debug. In that case, any crash or misbehavior in the boot loader or kernel would be ignored. The commands below must be run as administrator on the debuggee guest VM.
238
239##### Turn On Serial Debugging
240
241This will configure the debugging to be enabled and instruct to use the serial port for it.
242
243```cmd
244bcdedit /dbgsettings serial debugport:1 baudrate:115200
245```
246
247##### Turn On Kernel Debuging
248
249```cmd
250bcdedit /debug on
251```
252
253##### Turn On Boot Loader Debug
254
255```cmd
256bcdedit /bootdebug on
257```
258
259##### Turn on boot manager debug
260
261```cmd
262bcdedit /set {bootmgr} bootdebug on
263```
264
265##### Disable Recovery Screen On Boot Failure
266
267There could be a situation, where a crash is debugged. In such cases, the guest could be left in an inconsistent state. The default Windows behavior would be to boot into the recovery screen, however in some cases it might be not desired. To make Windows ignore failures and always proceed to booting the OS, use the command below:
268
269```cmd
270bcdedit /set {default} bootstatuspolicy ignoreallfailures
271```
272
273### Debugging Process
274
275#### Invoke the WinDbg VM
276
277```shell
278qemu-system-x86_64 \
279	-machine q35,accel=kvm \
280	-cpu host \
281	-smp 1 \
282	-m 4G \
283	-drive if=none,id=root,file=./windbg-disk.raw \
284	-device virtio-blk-pci,drive=root,disable-legacy=on \
285	-serial tcp::4445,server,nowait \
286	-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
287	-netdev user,id=mynet0,net=192.168.178.0/24,host=192.168.178.1,dhcpstart=192.168.178.64,hostname=windbg-host \
288	-vga std
289```
290
291Note, this VM has the networking enabled. It is needed, because symbols and sources might need to be fetched from a network location.
292
293Also, notice the `-serial` parameter - that's what does the magic on exposing the serial port to the guest while connecting the debugger VM with a client VM through the network. SAC/EMS needs to be disabled in the debugger VM, as otherwise the COM device might be blocked.
294
295Hereafter, WinDbg can be started using a command below:
296
297```cmd
298set _NT_DEBUG_PORT=com1
299set _NT_DEBUG_BAUD_RATE=115200
300
301windbg -v -d -k
302```
303
304Once started, WinDbg will wait for an incoming connection which is going to be initialized by the debuggee VM started in the next section.
305
306#### Invoke the Debuggee VM
307
308##### Under QEMU
309
310Essentially it would be the command like depicted in the guest preparation sections, with a few modifications:
311```shell
312qemu-system-x86_64 \
313	-machine q35,accel=kvm \
314	-cpu host \
315	-m 4G \
316	-bios ./$OVMF_DIR/OVMF_CODE.fd \
317	-cdrom ./$WIN_ISO_FILE \
318	-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
319	-drive if=none,id=root,file=./$IMG_FILE \
320	-device virtio-blk-pci,drive=root,disable-legacy=on \
321	-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
322	-netdev user,id=mynet0 \
323	-serial tcp:127.0.0.1:4445 \
324	-vga std
325```
326
327It is to see, that `-serial` parameter is used here, to establish the connection with the debugger VM.
328
329To disable HPET, attach `--no-hpet`. To enable hypervisor reference timer, use `-cpu host,hv-time`. These and other options can be used to achieve better [Hyper-V compatibility](https://archive.fosdem.org/2019/schedule/event/vai_enlightening_kvm/attachments/slides/2860/export/events/attachments/vai_enlightening_kvm/slides/2860/vkuznets_fosdem2019_enlightening_kvm.pdf).
330
331##### Cloud Hypervisor
332
333The `socat` tool is used to establish the QEMU compatible behavior. Here as well, the Cloud Hypervisor command used to run the Windows guest is to be used. Put the command into a shell script:
334
335`socat SYSTEM:"./ch-script",openpty,raw,echo=0 TCP:localhost:4445`
336
337The reason to pack the command into the shell script is that the command might contain a comma. When using SYSTEM, the shell command can't contain `,` or `!!`.
338
339## Links
340
341- [Fedora VirtIO guide for Windows](https://docs.fedoraproject.org/en-US/quick-docs/creating-windows-virtual-machines-using-virtio-drivers/)
342- [VirtIO driver binaries](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/)
343- [VirtIO driver sources](https://github.com/virtio-win/kvm-guest-drivers-windows)
344- [Emergency Management Services](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc787940(v=ws.10))
345- [OpenSSH server/client configuration](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse)
346- [Windows guest debugging under KVM](https://www.linux-kvm.org/page/WindowsGuestDrivers/GuestDebugging)
347- ["ENLIGHTENING" KVM](https://archive.fosdem.org/2019/schedule/event/vai_enlightening_kvm/attachments/slides/2860/export/events/attachments/vai_enlightening_kvm/slides/2860/vkuznets_fosdem2019_enlightening_kvm.pdf)
348