<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linux-kvm.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vrozenfe</id>
	<title>KVM - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://linux-kvm.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vrozenfe"/>
	<link rel="alternate" type="text/html" href="https://linux-kvm.org/page/Special:Contributions/Vrozenfe"/>
	<updated>2026-04-12T06:56:38Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://linux-kvm.org/index.php?title=WindowsGuestDrivers/UpdatedGuestDebugging&amp;diff=4480</id>
		<title>WindowsGuestDrivers/UpdatedGuestDebugging</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=WindowsGuestDrivers/UpdatedGuestDebugging&amp;diff=4480"/>
		<updated>2011-11-13T18:29:14Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
This page mainly introduce HOWTO use WinDbg to debug windows guest driver based on qemu.&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
To debug windows guest in kernel mode,we generally need a host computer as a remote debugger which runs the WinDbg and a target computer as a debuggee.&lt;br /&gt;
&lt;br /&gt;
==Connection between the host and target==&lt;br /&gt;
To allow debug windows guest kernel on QEMU,we have to connect the two virtual machines by using a virtual non-modem serial cable.The QEMU serial redirection ability can help us.&lt;br /&gt;
The simplest way is creating two windows guest virtual machines (one host,the other as target)on a same physical machine.&lt;br /&gt;
It is feasible that the host virtual machine and target run on two different physical machines by connecting the virtual serial cable via TCP.&lt;br /&gt;
&lt;br /&gt;
==Setting up the host and target virtual machine==&lt;br /&gt;
===Setting up the host VM ===&lt;br /&gt;
====start the host VM and install Windbg====&lt;br /&gt;
 &amp;lt;tt&amp;gt;/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-host.img \-chardev stdio,id=mon0 \-mon chardev=mon0 \-serial tcp::4445,server,nowait&amp;lt;/tt&amp;gt;&lt;br /&gt;
Add the &amp;lt;tt&amp;gt;-serial tcp::4445,server,nowait&amp;lt;/tt&amp;gt; to enable the serial redirection ability.The port number 4445 can be any valid tcp port.&lt;br /&gt;
&amp;lt;br&amp;gt;Using the server option and &amp;lt;tt&amp;gt;nowait&amp;lt;/tt&amp;gt; option QEMU opens a port which a client socket application can connect to it,the host will continue running without any wait.&lt;br /&gt;
&amp;lt;br&amp;gt;After startup,get and install the latest version of the Debugging Tools for Windows.Get them from the website:&amp;lt;tt&amp;gt;http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx&amp;lt;/tt&amp;gt;  or a ISO image file.&lt;br /&gt;
&amp;lt;br&amp;gt;You may need restart the host virtual machine to complete the installation.&lt;br /&gt;
When debugging a windows driver especially kernel-mode driver,symbols typically should be installed.&lt;br /&gt;
====Set Symbols path====&lt;br /&gt;
You can set symbols file path by &amp;lt;tt&amp;gt;File-&amp;gt;Symbol File Path...&amp;lt;/tt&amp;gt;or &amp;lt;tt&amp;gt;[Ctrl+S]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
also by add windows system environment variable &amp;lt;tt&amp;gt;_NT_SYMBOL_PATH&amp;lt;/tt&amp;gt;,set the value to:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
 |&#039;&#039;&#039;symbol &#039;&#039;&#039;&lt;br /&gt;
 |&#039;&#039;&#039;info&#039;&#039;&#039;&lt;br /&gt;
 |-&lt;br /&gt;
 |&amp;lt;nowiki&amp;gt;*SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols*&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |If symbols not found in local symbols,the WinDbg will automatic download symbols from the URL address http://msdl.microsoft.com/download/symbols . And the symbols download will be stored in the directory: c:\symbols\websymbols&lt;br /&gt;
 |-&lt;br /&gt;
 |c:\symbols\local_symbols &lt;br /&gt;
 |The symbols of current windows version.They can be acquired by website: http://msdn.microsoft.com/en-us/windows/hardware/gg463028&lt;br /&gt;
 |-&lt;br /&gt;
 |c:\driver\symbols&lt;br /&gt;
 |This mean the symbols(*.pdb files) will be produced after build process of the driver. We can use the WinDDK debugging tool symstore.exe to create own symbols server.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
====Creating local symbols server====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;C:\WinDDK\7600.16385.1\Debuggers&amp;gt;symstore.exe add /r /f C:\development\virtio-test\kvm-guest-drivers-windows\viotest\objchk_wxp_x86\i386 /s C:\driver\symbols\ /t &amp;quot;DriverSymbols&amp;quot; /v &amp;quot;1.0&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also add that into a *.bat file and create symbols automatically when every building.&lt;br /&gt;
&lt;br /&gt;
====Run WinDbg====&lt;br /&gt;
Then &amp;lt;tt&amp;gt;File-&amp;gt;Kernel Debug...&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;[Ctrl+k]&amp;lt;/tt&amp;gt; select &amp;lt;tt&amp;gt;COM&amp;lt;/tt&amp;gt; tab and set &amp;lt;tt&amp;gt;Baudrate&amp;lt;/tt&amp;gt; to 115200 and set port to &amp;lt;tt&amp;gt;COM1&amp;lt;/tt&amp;gt;,confirm and wait the target to connect.&lt;br /&gt;
===Setting up the target VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-target.img \-chardev stdio,id=mon0 \-mdev=mon0 \-serial tcp:127.0.0.1:4445&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;-serial tcp:127.0.0.1:4445&amp;lt;/tt&amp;gt; to connect to the host by virtual serial,port is same to the server.&lt;br /&gt;
&amp;lt;br&amp;gt;When start up,if Windows XP,2003 or 2000,edit &amp;lt;tt&amp;gt;c:\boot.ini&amp;lt;/tt&amp;gt; and duplicate the default boot line,at the end of the duplicated boot line add&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;/debug /debugport=COM1 /baudrate=115200&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;br&amp;gt;The baudrate and debugport must be identical to kernel mode configure of WinDbg.&lt;br /&gt;
&amp;lt;br&amp;gt;If Windows7,Vista or up,you must use &amp;lt;tt&amp;gt;BCDedit&amp;lt;/tt&amp;gt;(ref:http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx  and http://msdn.microsoft.com/en-us/library/ff542187.aspx ).&lt;br /&gt;
&amp;lt;br&amp;gt;Change the boot opition:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;bcdedit /dbgsettings SERIAL \[DEBUGPORT:COM1\] \[BAUDRATE:115200\]&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=Debug=&lt;br /&gt;
When Host and target setup completely,restart the target virtual machine and select the DEBUG boot option in the boot menu.&lt;br /&gt;
&amp;lt;br&amp;gt;Then WinDbg on host will try to connect to the windows guest(target) kernel to debug.&lt;br /&gt;
&amp;lt;br&amp;gt;You can &amp;lt;tt&amp;gt;Ctrl+Break&amp;lt;/tt&amp;gt; or use the &amp;lt;tt&amp;gt;Pause&amp;lt;/tt&amp;gt; button to break the guest running and also you can do anything which the debug tool support.&lt;br /&gt;
==About WinDbg==&lt;br /&gt;
WinDbg is a multi-purposed debugger for Microsoft Windows, distributed on the web by Microsoft. It can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compile and build==&lt;br /&gt;
&lt;br /&gt;
We first create a simple windows driver for test,it is named &amp;lt;tt&amp;gt;viotest&amp;lt;/tt&amp;gt; and added in the kvm-windows-guest-driver project to maintain.&lt;br /&gt;
The source code:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 #include &amp;quot;virtio_test.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;virtio_test_utils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject );&lt;br /&gt;
&lt;br /&gt;
ULONG DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PVOID RegistryPath ) {&lt;br /&gt;
    ULONG initResult = 0;&lt;br /&gt;
&lt;br /&gt;
    DbgPrint(&amp;quot;Viostor driver started...built on %s %s\n&amp;quot;, \__DATE__, \__TIME__);&lt;br /&gt;
    DriverObject-&amp;gt;DriverUnload = DriverUnload;&lt;br /&gt;
    DbgPrint(&amp;quot;Initialize returned 0x%x\n&amp;quot;, initResult);&lt;br /&gt;
&lt;br /&gt;
    return initResult;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject ) {&lt;br /&gt;
    DbgPrint(&amp;quot;Driver Unload successfully\! \n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SOURCES&amp;lt;/tt&amp;gt; file into the project&lt;br /&gt;
The driver only include &amp;lt;tt&amp;gt;DriverEntry()&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;DriverUnload()&amp;lt;/tt&amp;gt; and some message print.&lt;br /&gt;
The driver is not related to any specific device. All the simplification are done in order to increase the convenience of debug.&lt;br /&gt;
&lt;br /&gt;
Then using WinDDK build tool to build the driver,I use the &amp;lt;tt&amp;gt;&amp;quot;Windows XP x86 checked build&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;viotest&amp;gt;build -cCzg&amp;lt;/tt&amp;gt;&lt;br /&gt;
[[Image:build.png]]&lt;br /&gt;
&lt;br /&gt;
After build completely,the driver(&amp;lt;tt&amp;gt;viotest.sys,viotest.inf&amp;lt;/tt&amp;gt;) will be exported into the &amp;lt;tt&amp;gt;...\viotest\objchk_wxp_x86\i386\&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Load,install and debug the driver==&lt;br /&gt;
&lt;br /&gt;
After the process mentioned below,we copy the &amp;lt;tt&amp;gt;viotest&amp;lt;/tt&amp;gt; directory to the target guest.&lt;br /&gt;
HOST:&lt;br /&gt;
WinDbg is now running in the host guest.&lt;br /&gt;
We &amp;lt;tt&amp;gt;Ctrl+Break&amp;lt;/tt&amp;gt; to pause the debugger,and set breakpoints:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;kd&amp;gt; bu !viotest:DriverEntry&lt;br /&gt;
&amp;lt;br&amp;gt;kd&amp;gt; bu !viotest:DriverUnload&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;&amp;quot;bl&amp;quot;&amp;lt;/tt&amp;gt; to watch breakpoints set.&lt;br /&gt;
&amp;lt;br&amp;gt;F5,continue.&lt;br /&gt;
&amp;lt;br&amp;gt;Using tool [DriverStudio] to load,start,stop the driver on target.&lt;br /&gt;
File-&amp;gt;Open select the &amp;lt;tt&amp;gt;viotest.sys&amp;lt;/tt&amp;gt;, and then start (Go)the driver.&lt;br /&gt;
&amp;lt;br&amp;gt;Meanwhile,the WinDbg will hit the breakpoint at &amp;lt;tt&amp;gt;viotest.c:DriverEntry()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;br&amp;gt;And the related source file will be opened to view.&lt;br /&gt;
&amp;lt;br&amp;gt;You can see the breakpoints position with highlight label in the source code&lt;br /&gt;
[[Image:breakpoint.png]]&lt;br /&gt;
also can watch the variables value,check the callstacks etc. All behaviors of WinDbg are similar to other debuggers.&lt;br /&gt;
[[Image:variable.png]]&lt;br /&gt;
[[Image:stack.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;The debug message will be show in the WinDbg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;quot;viotest driver started...build on Nov 1 2011 05:04:18&amp;quot;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;quot;Initialize return 0x0&amp;quot;&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;When stop(unload) the driver,the breakpoint will also be hit at DriverUnload().&lt;br /&gt;
&amp;lt;br&amp;gt;The debug message will also be show in the WinDbg&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&amp;quot;Driver Unload sucessfully\!&amp;quot;&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==Other Debug Method==&lt;br /&gt;
* Using Debug message(print):&lt;br /&gt;
:The message can be viewed by another tool [http://technet.microsoft.com/en-us/sysinternals/bb896647 DebugView],it can be used in target guest(without WinDbg) only environment to debug the driver with the &amp;lt;tt&amp;gt;DbgPrint()&amp;lt;/tt&amp;gt; debug message. It is also a available method to debug the driver.&lt;br /&gt;
&lt;br /&gt;
* Using crash dump (kernel memory dump)with WinDbg&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TBD.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problems may be encountered==&lt;br /&gt;
&lt;br /&gt;
* WinDbg somtimes exit unexpectedly when connecting to the target&lt;br /&gt;
:I have not found the exact reason,but I found this problem often appears when changing the QEMU virtual hardware configuration or the target is not be shut off normally.It may be the Windows registry conflict cause this issue.&lt;br /&gt;
* WinDbg and virtual machine runs slowly&lt;br /&gt;
:It is recommended by Avi Kivity( avi@redhat.com)using QEMU-KVM which is significantly faster,especially running Windows,but the WinDbg will almost exit everytime when using qemu-kvm git.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
*1).[[WindowsGuestDrivers/GuestDebugging | Guest Debugging]] &lt;br /&gt;
*2).http://msdn.microsoft.com/library/windows/hardware/gg507680 &lt;br /&gt;
*3).Debugging tools for Windows HELP&lt;br /&gt;
*4).Developing_drivers_with_the_Microsoft_Windows_Driver_Foundation by Penny Orwich and Guy Smith,Microsoft Press 2007&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(author: [mailto:mars@linux.vnet.ibm.com Cao,Bing Bu] )&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=WindowsGuestDrivers/UpdatedGuestDebugging&amp;diff=4479</id>
		<title>WindowsGuestDrivers/UpdatedGuestDebugging</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=WindowsGuestDrivers/UpdatedGuestDebugging&amp;diff=4479"/>
		<updated>2011-11-13T18:27:00Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
This page mainly introduce HOWTO use WinDbg to debug windows guest driver based on qemu.&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
To debug windows guest in kernel mode,we generally need a host computer as a remote debugger which runs the WinDbg and a target computer as a debuggee.&lt;br /&gt;
&lt;br /&gt;
==Connection between the host and target==&lt;br /&gt;
To allow debug windows guest kernel on QEMU,we have to connect the two virtual machines by using a virtual non-modem serial cable.The QEMU serial redirection ability can help us.&lt;br /&gt;
The simplest way is creating two windows guest virtual machines (one host,the other as target)on a same physical machine.&lt;br /&gt;
It is feasible that the host virtual machine and target run on two different physical machines by connecting the virtual serial cable via TCP.&lt;br /&gt;
&lt;br /&gt;
==Setting up the host and target virtual machine==&lt;br /&gt;
===Setting up the host VM ===&lt;br /&gt;
====start the host VM and install Windbg====&lt;br /&gt;
 &amp;lt;tt&amp;gt;/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-host.img \-chardev stdio,id=mon0 \-mon chardev=mon0 \-serial tcp::4445,server,nowait&amp;lt;/tt&amp;gt;&lt;br /&gt;
Add the &amp;lt;tt&amp;gt;-serial tcp::4445,server,nowait&amp;lt;/tt&amp;gt; to enable the serial redirection ability.The port number 4445 can be any valid tcp port.&lt;br /&gt;
&amp;lt;br&amp;gt;Using the server option and &amp;lt;tt&amp;gt;nowait&amp;lt;/tt&amp;gt; option QEMU opens a port which a client socket application can connect to it,the host will continue running without any wait.&lt;br /&gt;
&amp;lt;br&amp;gt;After startup,get and install the latest version of the Debugging Tools for Windows.Get them from the website:&amp;lt;tt&amp;gt;http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx&amp;lt;/tt&amp;gt;  or a ISO image file.&lt;br /&gt;
&amp;lt;br&amp;gt;You may need restart the host virtual machine to complete the installation.&lt;br /&gt;
When debugging a windows driver especially kernel-mode driver,symbols typically should be installed.&lt;br /&gt;
====Set Symbols path====&lt;br /&gt;
You can set symbols file path by &amp;lt;tt&amp;gt;File-&amp;gt;Symbol File Path...&amp;lt;/tt&amp;gt;or &amp;lt;tt&amp;gt;[Ctrl+S]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
also by add windows system environment variable &amp;lt;tt&amp;gt;_NT_SYMBOL_PATH&amp;lt;/tt&amp;gt;,set the value to:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
 |&#039;&#039;&#039;symbol &#039;&#039;&#039;&lt;br /&gt;
 |&#039;&#039;&#039;info&#039;&#039;&#039;&lt;br /&gt;
 |-&lt;br /&gt;
 |&amp;lt;nowiki&amp;gt;*SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols*&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |If symbols not found in local symbols,the WinDbg will automatic download symbols from the URL address http://msdl.microsoft.com/download/symbols . And the symbols download will be stored in the directory: c:\symbols\websymbols&lt;br /&gt;
 |-&lt;br /&gt;
 |c:\symbols\local_symbols &lt;br /&gt;
 |The symbols of current windows version.They can be acquired by website: http://msdn.microsoft.com/en-us/windows/hardware/gg463028&lt;br /&gt;
 |-&lt;br /&gt;
 |c:\driver\symbols&lt;br /&gt;
 |This mean the symbols(*.pdb files) will be produced after build process of the driver. We can use the WinDDK debugging tool symstore.exe to create own symbols server.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
====Creating local symbols server====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;C:\WinDDK\7600.16385.1\Debuggers&amp;gt;symstore.exe add /r /f C:\development\virtio-test\kvm-guest-drivers-windows\viotest\objchk_wxp_x86\i386 /s C:\driver\symbols\ /t &amp;quot;DriverSymbols&amp;quot; /v &amp;quot;1.0&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also add that into a *.bat file and create symbols automatically when every building.&lt;br /&gt;
&lt;br /&gt;
====Run WinDbg====&lt;br /&gt;
Then &amp;lt;tt&amp;gt;File-&amp;gt;Kernel Debug...&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;[Ctrl+k]&amp;lt;/tt&amp;gt; select &amp;lt;tt&amp;gt;COM&amp;lt;/tt&amp;gt; tab and set &amp;lt;tt&amp;gt;Baudrate&amp;lt;/tt&amp;gt; to 115200 and set port to &amp;lt;tt&amp;gt;COM1&amp;lt;/tt&amp;gt;,confirm and wait the target to connect.&lt;br /&gt;
===Setting up the target VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-target.img \-chardev stdio,id=mon0 \-mdev=mon0 \-serial tcp:127.0.0.1:4445&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;-serial tcp:127.0.0.1:4445&amp;lt;/tt&amp;gt; to connect to the host by virtual serial,port is same to the server.&lt;br /&gt;
&amp;lt;br&amp;gt;When start up,if Windows XP,2003 or 2000,edit &amp;lt;tt&amp;gt;c:\boot.ini&amp;lt;/tt&amp;gt; and duplicate the default boot line,at the end of the duplicated boot line add&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;/debug /debugport=COM1 /baudrate=115200&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;br&amp;gt;The baudrate and debugport must be identical to kernel mode configure of WinDbg.&lt;br /&gt;
&amp;lt;br&amp;gt;If Windows7,Vista or up,you must use &amp;lt;tt&amp;gt;BCDedit&amp;lt;/tt&amp;gt;(ref:http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx  and http://msdn.microsoft.com/en-us/library/ff542187.aspx ).&lt;br /&gt;
&amp;lt;br&amp;gt;Change the boot opition:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;bcdedit /dbgsettings SERIAL \[DEBUGPORT:COM1\] \[BAUDRATE:115200\]&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=Debug=&lt;br /&gt;
When Host and target setup completely,restart the target virtual machine and select the DEBUG boot option in the boot menu.&lt;br /&gt;
&amp;lt;br&amp;gt;Then WinDbg on host will try to connect to the windows guest(target) kernel to debug.&lt;br /&gt;
&amp;lt;br&amp;gt;You can &amp;lt;tt&amp;gt;Ctrl+Break&amp;lt;/tt&amp;gt; or use the &amp;lt;tt&amp;gt;Pause&amp;lt;/tt&amp;gt; button to break the guest running and also you can do anything which the debug tool support.&lt;br /&gt;
==About WinDbg==&lt;br /&gt;
WinDbg is a multi-purposed debugger for Microsoft Windows, distributed on the web by Microsoft. It can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compile and build==&lt;br /&gt;
&lt;br /&gt;
We first create a simple windows driver for test,it is named &amp;lt;tt&amp;gt;viotest&amp;lt;/tt&amp;gt; and added in the kvm-windows-guest-driver project to maintain.&lt;br /&gt;
The source code:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 #include &amp;quot;virtio_test.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;virtio_test_utils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
VOID DriverUnload(IN PDRIVER_OBJECT DeviceObject);&lt;br /&gt;
&lt;br /&gt;
ULONG DriverEntry( IN PDRIVER_OBJECT&amp;amp; DriverObject, IN PVOID RegistryPath ) {&lt;br /&gt;
    ULONG initResult = 0;&lt;br /&gt;
&lt;br /&gt;
    DbgPrint(&amp;quot;Viostor driver started...built on %s %s\n&amp;quot;, \__DATE__, \__TIME__);&lt;br /&gt;
    DriverObject-&amp;gt;DriverUnload = DriverUnload;&lt;br /&gt;
    DbgPrint(&amp;quot;Initialize returned 0x%x\n&amp;quot;, initResult);&lt;br /&gt;
&lt;br /&gt;
    return initResult;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject ) {&lt;br /&gt;
    DbgPrint(&amp;quot;Driver Unload successfully\! \n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SOURCES&amp;lt;/tt&amp;gt; file into the project&lt;br /&gt;
The driver only include &amp;lt;tt&amp;gt;DriverEntry()&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;DriverUnload()&amp;lt;/tt&amp;gt; and some message print.&lt;br /&gt;
The driver is not related to any specific device. All the simplification are done in order to increase the convenience of debug.&lt;br /&gt;
&lt;br /&gt;
Then using WinDDK build tool to build the driver,I use the &amp;lt;tt&amp;gt;&amp;quot;Windows XP x86 checked build&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;viotest&amp;gt;build -cCzg&amp;lt;/tt&amp;gt;&lt;br /&gt;
[[Image:build.png]]&lt;br /&gt;
&lt;br /&gt;
After build completely,the driver(&amp;lt;tt&amp;gt;viotest.sys,viotest.inf&amp;lt;/tt&amp;gt;) will be exported into the &amp;lt;tt&amp;gt;...\viotest\objchk_wxp_x86\i386\&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Load,install and debug the driver==&lt;br /&gt;
&lt;br /&gt;
After the process mentioned below,we copy the &amp;lt;tt&amp;gt;viotest&amp;lt;/tt&amp;gt; directory to the target guest.&lt;br /&gt;
HOST:&lt;br /&gt;
WinDbg is now running in the host guest.&lt;br /&gt;
We &amp;lt;tt&amp;gt;Ctrl+Break&amp;lt;/tt&amp;gt; to pause the debugger,and set breakpoints:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;kd&amp;gt; bu !viotest:DriverEntry&lt;br /&gt;
&amp;lt;br&amp;gt;kd&amp;gt; bu !viotest:DriverUnload&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;&amp;quot;bl&amp;quot;&amp;lt;/tt&amp;gt; to watch breakpoints set.&lt;br /&gt;
&amp;lt;br&amp;gt;F5,continue.&lt;br /&gt;
&amp;lt;br&amp;gt;Using tool [DriverStudio] to load,start,stop the driver on target.&lt;br /&gt;
File-&amp;gt;Open select the &amp;lt;tt&amp;gt;viotest.sys&amp;lt;/tt&amp;gt;, and then start (Go)the driver.&lt;br /&gt;
&amp;lt;br&amp;gt;Meanwhile,the WinDbg will hit the breakpoint at &amp;lt;tt&amp;gt;viotest.c:DriverEntry()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;br&amp;gt;And the related source file will be opened to view.&lt;br /&gt;
&amp;lt;br&amp;gt;You can see the breakpoints position with highlight label in the source code&lt;br /&gt;
[[Image:breakpoint.png]]&lt;br /&gt;
also can watch the variables value,check the callstacks etc. All behaviors of WinDbg are similar to other debuggers.&lt;br /&gt;
[[Image:variable.png]]&lt;br /&gt;
[[Image:stack.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;The debug message will be show in the WinDbg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;quot;viotest driver started...build on Nov 1 2011 05:04:18&amp;quot;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;quot;Initialize return 0x0&amp;quot;&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;When stop(unload) the driver,the breakpoint will also be hit at DriverUnload().&lt;br /&gt;
&amp;lt;br&amp;gt;The debug message will also be show in the WinDbg&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&amp;quot;Driver Unload sucessfully\!&amp;quot;&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==Other Debug Method==&lt;br /&gt;
* Using Debug message(print):&lt;br /&gt;
:The message can be viewed by another tool [http://technet.microsoft.com/en-us/sysinternals/bb896647 DebugView],it can be used in target guest(without WinDbg) only environment to debug the driver with the &amp;lt;tt&amp;gt;DbgPrint()&amp;lt;/tt&amp;gt; debug message. It is also a available method to debug the driver.&lt;br /&gt;
&lt;br /&gt;
* Using crash dump (kernel memory dump)with WinDbg&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TBD.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problems may be encountered==&lt;br /&gt;
&lt;br /&gt;
* WinDbg somtimes exit unexpectedly when connecting to the target&lt;br /&gt;
:I have not found the exact reason,but I found this problem often appears when changing the QEMU virtual hardware configuration or the target is not be shut off normally.It may be the Windows registry conflict cause this issue.&lt;br /&gt;
* WinDbg and virtual machine runs slowly&lt;br /&gt;
:It is recommended by Avi Kivity( avi@redhat.com)using QEMU-KVM which is significantly faster,especially running Windows,but the WinDbg will almost exit everytime when using qemu-kvm git.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
*1).[[WindowsGuestDrivers/GuestDebugging | Guest Debugging]] &lt;br /&gt;
*2).http://msdn.microsoft.com/library/windows/hardware/gg507680 &lt;br /&gt;
*3).Debugging tools for Windows HELP&lt;br /&gt;
*4).Developing_drivers_with_the_Microsoft_Windows_Driver_Foundation by Penny Orwich and Guy Smith,Microsoft Press 2007&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(author: [mailto:mars@linux.vnet.ibm.com Cao,Bing Bu] )&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3297</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3297"/>
		<updated>2010-09-27T20:20:25Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|In Windows, port enumeration can be done using SetupAPI functions. For&lt;br /&gt;
more information please see [http://git.kernel.org/?p=virt/kvm/kvm-guest-drivers-windows.git;a=blob_plain;f=vioserial/app/device.cpp;hb=48b3a3f78fe4711d1561b32c9a1c0ca6471f85e3#GetDevicePath GetDevicePath] or visit MSDN site [http://msdn.microsoft.com/en-us/library/cc185682%28VS.85%29.aspx#Setup_API Setup API]&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI ReadFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __out        LPVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToRead,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesRead,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI WriteFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __in         LPCVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToWrite,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesWritten,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3296</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3296"/>
		<updated>2010-09-27T20:15:48Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|In Windows, port enumeration can be done using SetupAPI functions. For&lt;br /&gt;
more information please see [http://git.kernel.org/?p=virt/kvm/kvm-guest-drivers-windows.git;a=blob_plain;f=vioserial/app/device.cpp;hb=48b3a3f78fe4711d1561b32c9a1c0ca6471f85e3#GetDevicePath GetDevicePath] or visit [http://msdn.microsoft.com/en-us/library/cc185682%28VS.85%29.aspx#Setup_API Setup API]&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI ReadFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __out        LPVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToRead,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesRead,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI WriteFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __in         LPCVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToWrite,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesWritten,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3295</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3295"/>
		<updated>2010-09-27T20:12:32Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|In Windows, port enumeration can be done using SetupAPI functions. For&lt;br /&gt;
more information please visit [http://git.kernel.org/?p=virt/kvm/kvm-guest-drivers-windows.git;a=blob_plain;f=vioserial/app/device.cpp;hb=48b3a3f78fe4711d1561b32c9a1c0ca6471f85e3#GetDevicePath GetDevicePath] and [http://msdn.microsoft.com/en-us/library/cc185682%28VS.85%29.aspx#Setup_API Setup API]&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI ReadFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __out        LPVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToRead,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesRead,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI WriteFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __in         LPCVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToWrite,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesWritten,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3225</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3225"/>
		<updated>2010-09-04T16:01:27Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI ReadFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __out        LPVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToRead,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesRead,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI WriteFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __in         LPCVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToWrite,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesWritten,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL. &lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3224</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3224"/>
		<updated>2010-09-04T15:59:15Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&amp;lt;code&amp;gt;BOOL WINAPI ReadFile(&lt;br /&gt;
  __in         HANDLE hFile,&lt;br /&gt;
  __out        LPVOID lpBuffer,&lt;br /&gt;
  __in         DWORD nNumberOfBytesToRead,&lt;br /&gt;
  __out_opt    LPDWORD lpNumberOfBytesRead,&lt;br /&gt;
  __inout_opt  LPOVERLAPPED lpOverlapped&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
	<entry>
		<id>https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3223</id>
		<title>Virtio-serial API</title>
		<link rel="alternate" type="text/html" href="https://linux-kvm.org/index.php?title=Virtio-serial_API&amp;diff=3223"/>
		<updated>2010-09-04T15:56:17Z</updated>

		<summary type="html">&lt;p&gt;Vrozenfe: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Guest API ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Function&lt;br /&gt;
!Linux guest&lt;br /&gt;
!Windows guest&lt;br /&gt;
|-&lt;br /&gt;
|Port discovery&lt;br /&gt;
|symlinks from &amp;lt;code&amp;gt; /dev/virtio-port/&amp;lt;portname&amp;gt; &amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt; /dev/vportNpn &amp;lt;/code&amp;gt; as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Opening port&lt;br /&gt;
|&amp;lt;code&amp;gt;open(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Returns &amp;gt;= 0 on success.&lt;br /&gt;
* Only one open allowed at a time for a port.&lt;br /&gt;
|&amp;lt;code&amp;gt;HANDLE WINAPI CreateFile(&lt;br /&gt;
  __in      LPCTSTR lpFileName,&lt;br /&gt;
  __in      DWORD dwDesiredAccess,&lt;br /&gt;
  __in      DWORD dwShareMode,&lt;br /&gt;
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,&lt;br /&gt;
  __in      DWORD dwCreationDisposition,&lt;br /&gt;
  __in      DWORD dwFlagsAndAttributes,&lt;br /&gt;
  __in_opt  HANDLE hTemplateFile&lt;br /&gt;
);&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the function fails, the return value is INVALID_HANDLE_VALUE.&lt;br /&gt;
|-&lt;br /&gt;
|Reading&lt;br /&gt;
|&amp;lt;code&amp;gt;read(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking reads available.&lt;br /&gt;
* Return 0 if host is not connected.&lt;br /&gt;
* Block or &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt; if data not available.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device get hot-unplugged&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Writing&lt;br /&gt;
|&amp;lt;code&amp;gt;write(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Blocking as well as non-blocking.&lt;br /&gt;
* If host is not connected, write blocks or returns &amp;lt;code&amp;gt;-EAGAIN&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Errno will contain &amp;lt;code&amp;gt;-ENODEV&amp;lt;/code&amp;gt; if port or device got hot-unplugged.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Poll&lt;br /&gt;
|&amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLIN, POLLOUT&amp;lt;/code&amp;gt; with usual meaning.&lt;br /&gt;
* &amp;lt;code&amp;gt;POLLHUP&amp;lt;/code&amp;gt; when host is not connected or when port or device got unplugged&lt;br /&gt;
|-&lt;br /&gt;
|Asynchronous notifications&lt;br /&gt;
|&amp;lt;code&amp;gt;signal(7)&amp;lt;/code&amp;gt;&lt;br /&gt;
* From kernel 2.6.37, &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent to guest apps that set &amp;lt;code&amp;gt;O_ASYNC&amp;lt;/code&amp;gt; flag on the fd using &amp;lt;code&amp;gt;fcntl(2)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;SIGIO&amp;lt;/code&amp;gt; will be sent on host connection up, down and port unplug events.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; within signal handler to identify which port(s) changed state and how.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD auto-virtserial-guest.c]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/tree/hw/virtio-serial.h?h=stable-0.13 hw/virtio-serial.h]:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| &amp;lt;code&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
  * Individual ports/apps should call this function to register the port&lt;br /&gt;
  * with the virtio-serial bus&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Open a connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_open(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Close the connection to the port&lt;br /&gt;
  *   Returns 0 on success (always).&lt;br /&gt;
  */&lt;br /&gt;
 int virtio_serial_close(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send data to Guest&lt;br /&gt;
  */&lt;br /&gt;
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,&lt;br /&gt;
                             size_t size);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Query whether a guest is ready to receive data.&lt;br /&gt;
  */&lt;br /&gt;
 size_t virtio_serial_guest_ready(VirtIOSerialPort *port);&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Flow control: Ports can signal to the virtio-serial core to stop&lt;br /&gt;
  * sending data or re-start sending data, depending on the &#039;throttle&#039;&lt;br /&gt;
  * value here.&lt;br /&gt;
  */&lt;br /&gt;
 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In addition to this, the &#039;&#039;&#039;VirtIOSerialPortInfo&#039;&#039;&#039; struct has a function pointer for a callback to be called when guest writes some data to the port:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;code&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * Guest wrote some data to the port. This data is handed over to&lt;br /&gt;
     * the app via this callback.  The app is supposed to consume all&lt;br /&gt;
     * the data that is presented to it.&lt;br /&gt;
     */&lt;br /&gt;
    void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For an example use of this API, see [http://git.qemu.org/qemu.git/tree/hw/virtio-console.c?h=stable-0.13 hw/virtio-console.c]&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* Live Migration&lt;br /&gt;
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination).  Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.&lt;br /&gt;
&lt;br /&gt;
: A future version of qemu may introduce &#039;migration notifiers&#039; that may help chardevs let apps know of migration start / stop.&lt;br /&gt;
&lt;br /&gt;
* qemu chardevs&lt;br /&gt;
: qemu&#039;s chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.&lt;br /&gt;
&lt;br /&gt;
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost.  The various backends (unix, tcp sockets, file, etc.) do work well when used with care.&lt;/div&gt;</summary>
		<author><name>Vrozenfe</name></author>
	</entry>
</feed>