[Qemu-devel] [RFC] Add a stp file for usage from build directory

2013-05-26 Thread Alon Levy
For systemtap the location of the process being tapped is crucial, so
the existing stp file requires installation to use. A new file providing
qemu.local prefixed probes lets scripts run without an install step.

Signed-off-by: Alon Levy al...@redhat.com
---

 Makefile.target | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/Makefile.target b/Makefile.target
index ce4391f..5d176e2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -35,7 +35,7 @@ config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
 ifdef CONFIG_TRACE_SYSTEMTAP
-stap: $(QEMU_PROG).stp
+stap: $(QEMU_PROG).stp $(QEMU_PROG).local.stp
 
 ifdef CONFIG_USER_ONLY
 TARGET_TYPE=user
@@ -51,6 +51,17 @@ $(QEMU_PROG).stp: $(SRC_PATH)/trace-events
--target-arch=$(TARGET_ARCH) \
--target-type=$(TARGET_TYPE) \
 $  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp)
+
+$(QEMU_PROG).local.stp: $(SRC_PATH)/trace-events
+   $(call quiet-command,$(TRACETOOL) \
+   --format=stap \
+   --backend=$(TRACE_BACKEND) \
+   --binary=$(SRC_PATH)/$(TARGET_DIR)$(QEMU_PROG) \
+   --probe-prefix=qemu.local \
+   --target-arch=$(TARGET_ARCH) \
+   --target-type=$(TARGET_TYPE) \
+$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).local.stp)
+
 else
 stap:
 endif
-- 
1.8.2.1




Re: [Qemu-devel] [RFC] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
On Mon, 2013-05-27 at 08:32 +0200, Paolo Bonzini wrote:
 Il 27/05/2013 04:19, Alon Levy ha scritto:
  For systemtap the location of the process being tapped is crucial, so
  the existing stp file requires installation to use. A new file providing
  qemu.local prefixed probes lets scripts run without an install step.
  
  Signed-off-by: Alon Levy al...@redhat.com
  ---
  
   Makefile.target | 13 -
   1 file changed, 12 insertions(+), 1 deletion(-)
  
  diff --git a/Makefile.target b/Makefile.target
  index ce4391f..5d176e2 100644
  --- a/Makefile.target
  +++ b/Makefile.target
  @@ -35,7 +35,7 @@ config-target.h: config-target.h-timestamp
   config-target.h-timestamp: config-target.mak
   
   ifdef CONFIG_TRACE_SYSTEMTAP
  -stap: $(QEMU_PROG).stp
  +stap: $(QEMU_PROG).stp $(QEMU_PROG).local.stp
   
   ifdef CONFIG_USER_ONLY
   TARGET_TYPE=user
  @@ -51,6 +51,17 @@ $(QEMU_PROG).stp: $(SRC_PATH)/trace-events
  --target-arch=$(TARGET_ARCH) \
  --target-type=$(TARGET_TYPE) \
   $  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp)
  +
  +$(QEMU_PROG).local.stp: $(SRC_PATH)/trace-events
  +   $(call quiet-command,$(TRACETOOL) \
  +   --format=stap \
  +   --backend=$(TRACE_BACKEND) \
  +   --binary=$(SRC_PATH)/$(TARGET_DIR)$(QEMU_PROG) \
 
 This is not the build directory for out-of-tree builds.

I'll fix that.

 
  +   --probe-prefix=qemu.local \
 
 Why change the prefix?

It was one way to verify I was using the correct file. I'll change it
back.

But in general does it make sense for you to have this in addition to
the existing stp file?

 
 Paolo
 
  +   --target-arch=$(TARGET_ARCH) \
  +   --target-type=$(TARGET_TYPE) \
  +$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).local.stp)
  +
   else
   stap:
   endif
  
 
 





Re: [Qemu-devel] [RFC] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
On Tue, 2013-05-28 at 14:18 +0200, Paolo Bonzini wrote:
 Il 28/05/2013 14:09, Alon Levy ha scritto:
  + --probe-prefix=qemu.local \
 
  Why change the prefix?
  
  It was one way to verify I was using the correct file. I'll change it
  back.
  
  But in general does it make sense for you to have this in addition to
  the existing stp file?
 
 I think it does (with the same prefix so that you can share the
 scripts).  But I'm not sure how you'd use it. :)  Can you show an
 example and also put it in the commit message?

I though it would be useful to have a bunch of scripts for developers. I
have the following (didn't fix yet to use the same prefix):

diff --git a/scripts/stap-qxl-generic b/scripts/stap-qxl-generic
new file mode 100755
index 000..1c21911
--- /dev/null
+++ b/scripts/stap-qxl-generic
@@ -0,0 +1,4 @@
+#!/bin/bash -x
+STP=$0.stp
+ROOT=`dirname $0`/../
+sudo stap -v -I $ROOT/x86_64-softmmu $STP
diff --git a/scripts/stap-qxl-generic.stp b/scripts/stap-qxl-generic.stp
new file mode 100644
index 000..e201e69
--- /dev/null
+++ b/scripts/stap-qxl-generic.stp
@@ -0,0 +1,24 @@
+probe begin { printf(starting qxl generic probe\n) }
+
+global call, threads
+
+probe qemu.local.qxl* {
+//printf(%d: %s: %s\n, tid(), pp(), $$vars)
+//print_ubacktrace()
+call[tid(), probefunc()]  1
+threads[tid()]  1
+}
+
+probe timer.s(%( $#  0 %? $1 %: 5 %)) {
+   ansi_clear_screen()
+printf(%10s %45s %s\n, TID, , HITS);
+foreach([t] in threads-) {
+printf(%10d %45s %d\n, t, , @count(threads[t]));
+}
+   printf(%10s %45s %s\n,
+   TID, CALL, HITS)
+   foreach([tid, name] in call-) {
+   printf(%10d %45s %d\n, tid, name,
+   @count(call[tid, name]))
+   }
+}


 
 Paolo
 
 





Re: [Qemu-devel] [RFC] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
 Il 28/05/2013 14:33, Alon Levy ha scritto:
  On Tue, 2013-05-28 at 14:18 +0200, Paolo Bonzini wrote:
  Il 28/05/2013 14:09, Alon Levy ha scritto:
  +   --probe-prefix=qemu.local \
 
  Why change the prefix?
 
  It was one way to verify I was using the correct file. I'll change it
  back.
 
  But in general does it make sense for you to have this in addition to
  the existing stp file?
 
  I think it does (with the same prefix so that you can share the
  scripts).  But I'm not sure how you'd use it. :)  Can you show an
  example and also put it in the commit message?
  
  I though it would be useful to have a bunch of scripts for developers. I
  have the following (didn't fix yet to use the same prefix):
 
 Ok, so it's just a matter of using the -I option to stap.  That's the
 bit that has to be in the commit message.

Yes. Note that you add a directory, not a file. The only sure way to notice 
which hooks were used I found is looking at the generated c file.

 
 Thanks!
 
 Paolo
 
  diff --git a/scripts/stap-qxl-generic b/scripts/stap-qxl-generic
  new file mode 100755
  index 000..1c21911
  --- /dev/null
  +++ b/scripts/stap-qxl-generic
  @@ -0,0 +1,4 @@
  +#!/bin/bash -x
  +STP=$0.stp
  +ROOT=`dirname $0`/../
  +sudo stap -v -I $ROOT/x86_64-softmmu $STP
  diff --git a/scripts/stap-qxl-generic.stp b/scripts/stap-qxl-generic.stp
  new file mode 100644
  index 000..e201e69
  --- /dev/null
  +++ b/scripts/stap-qxl-generic.stp
  @@ -0,0 +1,24 @@
  +probe begin { printf(starting qxl generic probe\n) }
  +
  +global call, threads
  +
  +probe qemu.local.qxl* {
  +//printf(%d: %s: %s\n, tid(), pp(), $$vars)
  +//print_ubacktrace()
  +call[tid(), probefunc()]  1
  +threads[tid()]  1
  +}
  +
  +probe timer.s(%( $#  0 %? $1 %: 5 %)) {
  +   ansi_clear_screen()
  +printf(%10s %45s %s\n, TID, , HITS);
  +foreach([t] in threads-) {
  +printf(%10d %45s %d\n, t, , @count(threads[t]));
  +}
  +   printf(%10s %45s %s\n,
  +   TID, CALL, HITS)
  +   foreach([tid, name] in call-) {
  +   printf(%10d %45s %d\n, tid, name,
  +   @count(call[tid, name]))
  +   }
  +}
  
  
 
  Paolo
 
 
  
  
 
 
 



Re: [Qemu-devel] [RFC] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
On Tue, 2013-05-28 at 09:25 -0400, Alon Levy wrote:
  Il 28/05/2013 14:33, Alon Levy ha scritto:
   On Tue, 2013-05-28 at 14:18 +0200, Paolo Bonzini wrote:
   Il 28/05/2013 14:09, Alon Levy ha scritto:
   + --probe-prefix=qemu.local \
  
   Why change the prefix?

Actually the problem is having two stp files (qemu-system-x86_64.stp 
qemu-system-x86_64.local.stp) in the same directory providing the same
probes is not workable with stap. In pass 2 it doesn't have any specific
order of going through the directory. Solutions
1. have a different prefix
2. introduce another subdirectory
x86_64-softmmu/local.stp/qemu-system-x86_64.stp

  
   It was one way to verify I was using the correct file. I'll change it
   back.
  
   But in general does it make sense for you to have this in addition to
   the existing stp file?
  
   I think it does (with the same prefix so that you can share the
   scripts).  But I'm not sure how you'd use it. :)  Can you show an
   example and also put it in the commit message?
   
   I though it would be useful to have a bunch of scripts for developers. I
   have the following (didn't fix yet to use the same prefix):
  
  Ok, so it's just a matter of using the -I option to stap.  That's the
  bit that has to be in the commit message.
 
 Yes. Note that you add a directory, not a file. The only sure way to notice 
 which hooks were used I found is looking at the generated c file.
 
  
  Thanks!
  
  Paolo
  
   diff --git a/scripts/stap-qxl-generic b/scripts/stap-qxl-generic
   new file mode 100755
   index 000..1c21911
   --- /dev/null
   +++ b/scripts/stap-qxl-generic
   @@ -0,0 +1,4 @@
   +#!/bin/bash -x
   +STP=$0.stp
   +ROOT=`dirname $0`/../
   +sudo stap -v -I $ROOT/x86_64-softmmu $STP
   diff --git a/scripts/stap-qxl-generic.stp b/scripts/stap-qxl-generic.stp
   new file mode 100644
   index 000..e201e69
   --- /dev/null
   +++ b/scripts/stap-qxl-generic.stp
   @@ -0,0 +1,24 @@
   +probe begin { printf(starting qxl generic probe\n) }
   +
   +global call, threads
   +
   +probe qemu.local.qxl* {
   +//printf(%d: %s: %s\n, tid(), pp(), $$vars)
   +//print_ubacktrace()
   +call[tid(), probefunc()]  1
   +threads[tid()]  1
   +}
   +
   +probe timer.s(%( $#  0 %? $1 %: 5 %)) {
   +   ansi_clear_screen()
   +printf(%10s %45s %s\n, TID, , HITS);
   +foreach([t] in threads-) {
   +printf(%10d %45s %d\n, t, , @count(threads[t]));
   +}
   +   printf(%10s %45s %s\n,
   +   TID, CALL, HITS)
   +   foreach([tid, name] in call-) {
   +   printf(%10d %45s %d\n, tid, name,
   +   @count(call[tid, name]))
   +   }
   +}
   
   
  
   Paolo
  
  
   
   
  
  
  
 





[Qemu-devel] [PATCH] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
For systemtap the location of the process being tapped is crucial, as a
result the existing stp file requires installation for use.

There are now two files:
$(TARGET_DIR)/$(QEMU_PROG).stp-installed: copied to $(tapdir)/$(QEMU_PROG).stp
$(TARGET_DIR)/$(QEMU_PROG).stp: usable locally

To use:
stap -I $(TARGET_DIR) ..

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.target | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index ce4391f..54687e2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -35,7 +35,7 @@ config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
 ifdef CONFIG_TRACE_SYSTEMTAP
-stap: $(QEMU_PROG).stp
+stap: $(QEMU_PROG).stp-installed $(QEMU_PROG).local.stp
 
 ifdef CONFIG_USER_ONLY
 TARGET_TYPE=user
@@ -43,14 +43,24 @@ else
 TARGET_TYPE=system
 endif
 
-$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=stap \
--backend=$(TRACE_BACKEND) \
--binary=$(bindir)/$(QEMU_PROG) \
--target-arch=$(TARGET_ARCH) \
--target-type=$(TARGET_TYPE) \
-$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp)
+$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp-installed)
+
+$(QEMU_PROG).local.stp: $(SRC_PATH)/trace-events
+   $(call quiet-command,$(TRACETOOL) \
+   --format=stap \
+   --backend=$(TRACE_BACKEND) \
+   --binary=$(realpath .)/$(QEMU_PROG) \
+   --target-arch=$(TARGET_ARCH) \
+   --target-type=$(TARGET_TYPE) \
+$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).local.stp)
+
 else
 stap:
 endif
@@ -186,7 +196,7 @@ endif
 endif
 ifdef CONFIG_TRACE_SYSTEMTAP
$(INSTALL_DIR) $(DESTDIR)$(qemu_datadir)/../systemtap/tapset
-   $(INSTALL_DATA) $(QEMU_PROG).stp 
$(DESTDIR)$(qemu_datadir)/../systemtap/tapset
+   $(INSTALL_DATA) $(QEMU_PROG).stp-installed 
$(DESTDIR)$(qemu_datadir)/../systemtap/tapset/$(QEMU_PROG).stp
 endif
 
 GENERATED_HEADERS += config-target.h
-- 
1.8.2.1




[Qemu-devel] [PATCH v2] Add a stp file for usage from build directory

2013-05-28 Thread Alon Levy
For systemtap the location of the process being tapped is crucial, as a
result the existing stp file requires installation for use.

There are now two files:
$(TARGET_DIR)/$(QEMU_PROG).stp-installed: copied to $(tapdir)/$(QEMU_PROG).stp
$(TARGET_DIR)/$(QEMU_PROG).stp: pointing to the built binary, usable
without installation

To use:
stap -I $(TARGET_DIR) ...

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.target | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index ce4391f..a44c8ed 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -35,7 +35,7 @@ config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
 ifdef CONFIG_TRACE_SYSTEMTAP
-stap: $(QEMU_PROG).stp
+stap: $(QEMU_PROG).stp-installed $(QEMU_PROG).stp
 
 ifdef CONFIG_USER_ONLY
 TARGET_TYPE=user
@@ -43,14 +43,24 @@ else
 TARGET_TYPE=system
 endif
 
-$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=stap \
--backend=$(TRACE_BACKEND) \
--binary=$(bindir)/$(QEMU_PROG) \
--target-arch=$(TARGET_ARCH) \
--target-type=$(TARGET_TYPE) \
+$  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp-installed)
+
+$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+   $(call quiet-command,$(TRACETOOL) \
+   --format=stap \
+   --backend=$(TRACE_BACKEND) \
+   --binary=$(realpath .)/$(QEMU_PROG) \
+   --target-arch=$(TARGET_ARCH) \
+   --target-type=$(TARGET_TYPE) \
 $  $@,  GEN   $(TARGET_DIR)$(QEMU_PROG).stp)
+
 else
 stap:
 endif
@@ -186,7 +196,7 @@ endif
 endif
 ifdef CONFIG_TRACE_SYSTEMTAP
$(INSTALL_DIR) $(DESTDIR)$(qemu_datadir)/../systemtap/tapset
-   $(INSTALL_DATA) $(QEMU_PROG).stp 
$(DESTDIR)$(qemu_datadir)/../systemtap/tapset
+   $(INSTALL_DATA) $(QEMU_PROG).stp-installed 
$(DESTDIR)$(qemu_datadir)/../systemtap/tapset/$(QEMU_PROG).stp
 endif
 
 GENERATED_HEADERS += config-target.h
-- 
1.8.2.1




[Qemu-devel] [PATCH] libcacard/vscclient: fix leakage of socket on error paths

2013-05-31 Thread Alon Levy
Spotted by Coverity.

Signed-off-by: Alon Levy al...@redhat.com
---
 libcacard/vscclient.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index ac23647..9fcc548 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -618,18 +618,22 @@ connect_to_qemu(
 if (ret != 0) {
 /* Error */
 fprintf(stderr, getaddrinfo failed\n);
-return -1;
+goto cleanup_socket;
 }
 
 if (connect(sock, server-ai_addr, server-ai_addrlen)  0) {
 /* Error */
 fprintf(stderr, Could not connect\n);
-return -1;
+goto cleanup_socket;
 }
 if (verbose) {
 printf(Connected (sizeof Header=%zd)!\n, sizeof(VSCMsgHeader));
 }
 return sock;
+
+cleanup_socket:
+close(sock);
+return -1;
 }
 
 int
-- 
1.8.2.1




Re: [Qemu-devel] [PATCH] libcacard/vscclient: fix leakage of socket on error paths

2013-05-31 Thread Alon Levy
 Spotted by Coverity.
 

Self NACK.

I'll send a more complete patch, and use closesocket.

 Signed-off-by: Alon Levy al...@redhat.com
 ---
  libcacard/vscclient.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)
 
 diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
 index ac23647..9fcc548 100644
 --- a/libcacard/vscclient.c
 +++ b/libcacard/vscclient.c
 @@ -618,18 +618,22 @@ connect_to_qemu(
  if (ret != 0) {
  /* Error */
  fprintf(stderr, getaddrinfo failed\n);
 -return -1;
 +goto cleanup_socket;
  }
  
  if (connect(sock, server-ai_addr, server-ai_addrlen)  0) {
  /* Error */
  fprintf(stderr, Could not connect\n);
 -return -1;
 +goto cleanup_socket;
  }
  if (verbose) {
  printf(Connected (sizeof Header=%zd)!\n, sizeof(VSCMsgHeader));
  }
  return sock;
 +
 +cleanup_socket:
 +close(sock);
 +return -1;
  }
  
  int
 --
 1.8.2.1
 
 
 



[Qemu-devel] [PATCH 1/5] oslib-posix: add qemu_pipe_non_block

2013-06-04 Thread Alon Levy
Used by the followin patch.

Signed-off-by: Alon Levy al...@redhat.com
---
 include/qemu-common.h |  1 +
 util/oslib-posix.c| 19 +++
 2 files changed, 20 insertions(+)

diff --git a/include/qemu-common.h b/include/qemu-common.h
index cb82ef3..c24d75c 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -232,6 +232,7 @@ ssize_t qemu_recv_full(int fd, void *buf, size_t count, int 
flags)
 
 #ifndef _WIN32
 int qemu_pipe(int pipefd[2]);
+int qemu_pipe_non_block(int pipefd[2]);
 #endif
 
 #ifdef _WIN32
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 3dc8b1b..bc2ce2e 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -188,6 +188,25 @@ int qemu_pipe(int pipefd[2])
 return ret;
 }
 
+int qemu_pipe_non_block(int pipefd[2])
+{
+int ret;
+
+ret = qemu_pipe(pipefd);
+if (ret) {
+return ret;
+}
+if (fcntl(card-pipe[0], F_SETFL, O_NONBLOCK) == -1) {
+return -errno;
+}
+if (fcntl(card-pipe[1], F_SETFL, O_NONBLOCK) == -1) {
+return -errno;
+}
+if (fcntl(card-pipe[0], F_SETOWN, getpid()) == -1) {
+return -errno;
+}
+}
+
 int qemu_utimens(const char *path, const struct timespec *times)
 {
 struct timeval tv[2], tv_now;
-- 
1.8.2.1




[Qemu-devel] [PATCH 2/5] use qemu_pipe_non_block

2013-06-04 Thread Alon Levy
This fixes six instances of unchecked fcntl return status, spotted by
Coverity.

Signed-off-by: Alon Levy al...@redhat.com
---
 hw/display/qxl.c| 10 +++---
 hw/usb/ccid-card-emulated.c |  8 +++-
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 9e5b7ad..25c8c5a 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1797,15 +1797,11 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t 
events)
 
 static void init_pipe_signaling(PCIQXLDevice *d)
 {
-if (pipe(d-pipe)  0) {
-fprintf(stderr, %s:%s: qxl pipe creation failed\n,
-__FILE__, __func__);
+if (qxl_pipe_non_block(d-pipe)) {
+fprintf(stderr, %s:%s: qxl pipe creation failed: %s\n,
+__FILE__, __func__, stderror(errno));
 exit(1);
 }
-fcntl(d-pipe[0], F_SETFL, O_NONBLOCK);
-fcntl(d-pipe[1], F_SETFL, O_NONBLOCK);
-fcntl(d-pipe[0], F_SETOWN, getpid());
-
 qemu_thread_get_self(d-main);
 qemu_set_fd_handler(d-pipe[0], pipe_read, NULL, d);
 }
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index deb6d47..2e6942e 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -406,13 +406,11 @@ static void pipe_read(void *opaque)
 
 static int init_pipe_signaling(EmulatedState *card)
 {
-if (pipe(card-pipe)  0) {
-DPRINTF(card, 2, pipe creation failed\n);
+if (qemu_pipe_non_block(card-pipe)  0) {
+DPRINTF(card, 2, pipe creation failed: %s\n,
+strerror(errno));
 return -1;
 }
-fcntl(card-pipe[0], F_SETFL, O_NONBLOCK);
-fcntl(card-pipe[1], F_SETFL, O_NONBLOCK);
-fcntl(card-pipe[0], F_SETOWN, getpid());
 qemu_set_fd_handler(card-pipe[0], pipe_read, NULL, card);
 return 0;
 }
-- 
1.8.2.1




[Qemu-devel] [PATCH 4/5] libcacard/vreader.c: fix possible NULL dereference

2013-06-04 Thread Alon Levy
Reported by Coverity:

Error: FORWARD_NULL (CWE-476):
qemu-1.5.0/libcacard/vreader.c:267: cond_false: Condition card == NULL, 
taking false branch
qemu-1.5.0/libcacard/vreader.c:269: if_end: End of if statement
qemu-1.5.0/libcacard/vreader.c:272: cond_false: Condition apdu == NULL, 
taking false branch
qemu-1.5.0/libcacard/vreader.c:275: else_branch: Reached else branch
qemu-1.5.0/libcacard/vreader.c:280: cond_false: Condition response, taking 
false branch
qemu-1.5.0/libcacard/vreader.c:284: if_end: End of if statement
qemu-1.5.0/libcacard/vreader.c:280: var_compare_op: Comparing response to 
null implies that response might be null.
qemu-1.5.0/libcacard/vreader.c:286: cond_true: Condition card_status == 
VCARD_DONE, taking true branch
qemu-1.5.0/libcacard/vreader.c:287: cond_true: Condition card_status == 
VCARD_DONE, taking true branch
qemu-1.5.0/libcacard/vreader.c:288: var_deref_op: Dereferencing null pointer 
response.

Signed-off-by: Alon Levy al...@redhat.com
---
 libcacard/vreader.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcacard/vreader.c b/libcacard/vreader.c
index 5793d73..60eb43b 100644
--- a/libcacard/vreader.c
+++ b/libcacard/vreader.c
@@ -260,7 +260,7 @@ vreader_xfr_bytes(VReader *reader,
 {
 VCardAPDU *apdu;
 VCardResponse *response = NULL;
-VCardStatus card_status;
+VCardStatus card_status = VCARD_FAIL;
 unsigned short status;
 VCard *card = vreader_get_card(reader);
 
-- 
1.8.2.1




[Qemu-devel] [PATCH 3/5] libcacard/vscclient: fix leakage of socket on error paths

2013-06-04 Thread Alon Levy
Spotted by Coverity.

Signed-off-by: Alon Levy al...@redhat.com
---
 libcacard/vscclient.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index ac23647..5180d29 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -618,18 +618,22 @@ connect_to_qemu(
 if (ret != 0) {
 /* Error */
 fprintf(stderr, getaddrinfo failed\n);
-return -1;
+goto cleanup_socket;
 }
 
 if (connect(sock, server-ai_addr, server-ai_addrlen)  0) {
 /* Error */
 fprintf(stderr, Could not connect\n);
-return -1;
+goto cleanup_socket;
 }
 if (verbose) {
 printf(Connected (sizeof Header=%zd)!\n, sizeof(VSCMsgHeader));
 }
 return sock;
+
+cleanup_socket:
+closesocket(sock);
+return -1;
 }
 
 int
@@ -759,5 +763,6 @@ main(
 g_io_channel_unref(channel_socket);
 g_byte_array_unref(socket_to_send);
 
+closesocket(sock);
 return 0;
 }
-- 
1.8.2.1




[Qemu-devel] [PATCH 5/5] libcacard/vscclient.c: fix use of uninitialized variable

2013-06-04 Thread Alon Levy
Found by Coverity.

Signed-off-by: Alon Levy al...@redhat.com
---
 libcacard/vscclient.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index 5180d29..4275c23 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -645,7 +645,7 @@ main(
 GIOChannel *channel_stdin;
 char *qemu_host;
 char *qemu_port;
-VSCMsgHeader mhHeader;
+VSCMsgHeader mhHeader = {0,};
 
 VCardEmulOptions *command_line_options = NULL;
 
-- 
1.8.2.1




Re: [Qemu-devel] [PATCH 2/5] use qemu_pipe_non_block

2013-06-04 Thread Alon Levy
 On 4 June 2013 21:23, Alon Levy al...@redhat.com wrote:
  --- a/hw/display/qxl.c
  +++ b/hw/display/qxl.c
  @@ -1797,15 +1797,11 @@ static void qxl_send_events(PCIQXLDevice *d,
  uint32_t events)
 
   static void init_pipe_signaling(PCIQXLDevice *d)
   {
  -if (pipe(d-pipe)  0) {
  -fprintf(stderr, %s:%s: qxl pipe creation failed\n,
  -__FILE__, __func__);
  +if (qxl_pipe_non_block(d-pipe)) {
 
 Surely this can't compile? -- this function doesn't exist.

I am abusing my right to post to this list, sorry. I didn't actually try to 
compile.

 
 thanks
 -- PMM
 
 



Re: [Qemu-devel] [PATCH 2/5] use qemu_pipe_non_block

2013-06-04 Thread Alon Levy
 Il 04/06/2013 22:23, Alon Levy ha scritto:
  This fixes six instances of unchecked fcntl return status, spotted by
  Coverity.
 
 I think we're just assuming that they cannot fail...  I don't think we
 need the previous patch and this one, unless they help porting stuff to
 Windows.

This was purely to satisfy coverity, but I thought we would want to check fcntl 
return status? also, shouldn't we be looping if EINTR?

 
 Paolo
 
 



Re: [Qemu-devel] [PATCH 1/5] oslib-posix: add qemu_pipe_non_block

2013-06-04 Thread Alon Levy
 On 06/04/2013 02:23 PM, Alon Levy wrote:
  Used by the followin patch.
 
 s/followin/following/

Thanks.

 
   
  +int qemu_pipe_non_block(int pipefd[2])
  +{
  +int ret;
  +
  +ret = qemu_pipe(pipefd);
 
 qemu_pipe() already uses pipe2() when available; it seems like it would
 be nicer to use pipe2's O_NONBLOCK option directly in one syscall (where
 supported) instead of having to make additional syscalls after the fact.
  Would it just be smarter to change the signature of qemu_pipe() to add
 a bool block parameter, and then change the 5 existing callers to pass
 false with your later patch in the series passing true, and do it
 without creating a new wrapper?

Answered below.

 
  +if (ret) {
  +return ret;
  +}
  +if (fcntl(card-pipe[0], F_SETFL, O_NONBLOCK) == -1) {
  +return -errno;
  +}
  +if (fcntl(card-pipe[1], F_SETFL, O_NONBLOCK) == -1) {
  +return -errno;
 
 Leaks fds.  If you're going to report error, then you must close the fds
 already created.

As Peter pointed out, I should not go here, so I'll drop these checks, instead 
doing naked fcntl calls, so no fd leak possible (no returns).

 
  +}
  +if (fcntl(card-pipe[0], F_SETOWN, getpid()) == -1) {
  +return -errno;
 
 Same comment about fd leaks.
 
 This part seems like a useful change, IF you plan on using SIGIO and
 SIGURG signals; and it is something which pipe2() cannot optimize, so I
 can see why you are adding a new function instead of changing
 qemu_pipe() and adjust all its callers to pass an additional parameter.
  But are you really planning on using SIGIO/SIGURG?

I don't plan on using those signals, so I'll add a parameter instead.

 
 Furthermore, this is undefined behavior.  According to POSIX, use of
 F_SETOWN is only portable on sockets, not pipes.  It may work on Linux,
 but you'll need to be aware of what it does on other platforms.
 http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
 --
 Eric Blake   eblake redhat com+1-919-301-3266
 Libvirt virtualization library http://libvirt.org
 
 



Re: [Qemu-devel] [Qemu-trivial] [PATCH 1/5] oslib-posix: add qemu_pipe_non_block

2013-06-12 Thread Alon Levy
 05.06.2013 00:23, Alon Levy wrote:
 
  [PATCH 1/5] oslib-posix: add qemu_pipe_non_block
  [PATCH 2/5] use qemu_pipe_non_block
  [PATCH 3/5] libcacard/vscclient: fix leakage of socket on error paths
  [PATCH 4/5] libcacard/vreader.c: fix possible NULL dereference
  [PATCH 5/5] libcacard/vscclient.c: fix use of uninitialized variable
 
 So, what happened with this series?

I still plan to do it, but didn't get to it yet.

 
 From the above 5 patches, only 3/5 (leakage of socket on error paths)
 is ready to be applied.  Should I apply it now, or wait for the
 respin of whole series?  (Or both?)

I'll be happy if you do. (Both don't actually make sense :)

 
 Thanks,
 
 /mjt
 
 



Re: [Qemu-devel] [PATCH] qxl: replace pipe signaling with bottom half

2013-10-30 Thread Alon Levy
On 10/30/2013 10:17 AM, Gerd Hoffmann wrote:
 qxl creates a pipe, then writes something to it to wake up the iothread
 from the spice server thread to raise an irq.  These days qemu bottom
 halves can be scheduled from threads and signals, so there is no reason
 to do this any more.  Time to clean it up.
 
 Signed-off-by: Gerd Hoffmann kra...@redhat.com

Reviewed-by: Alon Levy al...@redhat.com

 ---
  hw/display/qxl.c | 33 +++--
  hw/display/qxl.h |  3 +--
  2 files changed, 4 insertions(+), 32 deletions(-)
 
 diff --git a/hw/display/qxl.c b/hw/display/qxl.c
 index de835d6..41c34b1 100644
 --- a/hw/display/qxl.c
 +++ b/hw/display/qxl.c
 @@ -1701,15 +1701,9 @@ static const MemoryRegionOps qxl_io_ops = {
  },
  };
  
 -static void pipe_read(void *opaque)
 +static void qxl_update_irq_bh(void *opaque)
  {
  PCIQXLDevice *d = opaque;
 -char dummy;
 -int len;
 -
 -do {
 -len = read(d-pipe[0], dummy, sizeof(dummy));
 -} while (len == sizeof(dummy));
  qxl_update_irq(d);
  }
  
 @@ -1730,28 +1724,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t 
 events)
  if ((old_pending  le_events) == le_events) {
  return;
  }
 -if (qemu_thread_is_self(d-main)) {
 -qxl_update_irq(d);
 -} else {
 -if (write(d-pipe[1], d, 1) != 1) {
 -dprint(d, 1, %s: write to pipe failed\n, __func__);
 -}
 -}
 -}
 -
 -static void init_pipe_signaling(PCIQXLDevice *d)
 -{
 -if (pipe(d-pipe)  0) {
 -fprintf(stderr, %s:%s: qxl pipe creation failed\n,
 -__FILE__, __func__);
 -exit(1);
 -}
 -fcntl(d-pipe[0], F_SETFL, O_NONBLOCK);
 -fcntl(d-pipe[1], F_SETFL, O_NONBLOCK);
 -fcntl(d-pipe[0], F_SETOWN, getpid());
 -
 -qemu_thread_get_self(d-main);
 -qemu_set_fd_handler(d-pipe[0], pipe_read, NULL, d);
 +qemu_bh_schedule(d-update_irq);
  }
  
  /* graphics console */
 @@ -2044,7 +2017,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
  }
  qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
  
 -init_pipe_signaling(qxl);
 +qxl-update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
  qxl_reset_state(qxl);
  
  qxl-update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
 diff --git a/hw/display/qxl.h b/hw/display/qxl.h
 index 84f0182..c5de3d7 100644
 --- a/hw/display/qxl.h
 +++ b/hw/display/qxl.h
 @@ -81,8 +81,7 @@ typedef struct PCIQXLDevice {
  QemuMutex  track_lock;
  
  /* thread signaling */
 -QemuThread main;
 -intpipe[2];
 +QEMUBH *update_irq;
  
  /* ram pci bar */
  QXLRam *ram;
 




Re: [Qemu-devel] [PATCH 0/2] Try to fix problem with emulated smartcards where invalid PIN succeeds

2013-09-08 Thread Alon Levy
 I started writing a blog post yesterday about virtualized smartcards here:
 
 https://blogs.gnome.org/halfline/2013/09/08/another-smartcard-post/
 
 and while testing what I was writing I noticed an invalid PIN worked when
 it shouldn't have. It turns out that typing a valid PIN once in one program
 in
 the guest, is enough to make all future programs asking for the PIN to
 succeed
 regardless of what gets typed in for the PIN.
 
 I did some digging through the libcacard code, and noticed it uses the
 NSS PK11_Authenticate function which calls a function that has this comment
 above it:
 
 If we're already logged in and this function is called we
 will still prompt for a password, but we will probably succeed
 no matter what the password was.
 
 Also, PK11_Authenticate short-circuits to an early return SECSuccess if the
 token
 is already logged in.
 
 The two patches in this series attempt to correct this problem by calling
 PK11_Logout.
 I'm not 100% certain I've placed the PK11_Logout call in the best place, but
 it does
 seeming to fix the issue.

Hi Ray,

 Thanks for the patches! It looks good to me but I'll defer to Robert,

Alon

 
 
 



Re: [Qemu-devel] [PATCH 1/1] spice: fix display initialization

2013-07-30 Thread Alon Levy
 Spice has two display interface implementations:  One integrated into
 the qxl graphics card, and one generic which can operate with every
 qemu-emulated graphics card.
 
 The generic one is activated in case spice is used without qxl.  The
 logic for that only caught the -vga qxl case, -device qxl-vga goes
 unnoticed.  Fix that by adding a check in the spice interface
 registration so we'll notice the qxl card no matter how it is created.
 
 https://bugzilla.redhat.com/show_bug.cgi?id=981094

Reviewed-by: Alon Levy al...@redhat.com

 
 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  include/sysemu/sysemu.h |1 -
  include/ui/qemu-spice.h |2 ++
  ui/spice-core.c |5 +
  vl.c|2 +-
  4 files changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
 index 3caeb66..d7a77b6 100644
 --- a/include/sysemu/sysemu.h
 +++ b/include/sysemu/sysemu.h
 @@ -103,7 +103,6 @@ typedef enum {
  
  extern int vga_interface_type;
  #define xenfb_enabled (vga_interface_type == VGA_XENFB)
 -#define qxl_enabled (vga_interface_type == VGA_QXL)
  
  extern int graphic_width;
  extern int graphic_height;
 diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
 index eba6d77..c6c756b 100644
 --- a/include/ui/qemu-spice.h
 +++ b/include/ui/qemu-spice.h
 @@ -27,6 +27,7 @@
  #include monitor/monitor.h
  
  extern int using_spice;
 +extern int spice_displays;
  
  void qemu_spice_init(void);
  void qemu_spice_input_init(void);
 @@ -57,6 +58,7 @@ static inline CharDriverState
 *qemu_chr_open_spice_port(const char *name)
  #include monitor/monitor.h
  
  #define using_spice 0
 +#define spice_displays 0
  static inline int qemu_spice_set_passwd(const char *passwd,
  bool fail_if_connected,
  bool disconnect_if_connected)
 diff --git a/ui/spice-core.c b/ui/spice-core.c
 index 033fd89..bd7a248 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
 @@ -48,6 +48,7 @@ static char *auth_passwd;
  static time_t auth_expires = TIME_MAX;
  static int spice_migration_completed;
  int using_spice = 0;
 +int spice_displays;
  
  static QemuThread me;
  
 @@ -836,6 +837,10 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
  qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
  }
  
 +if (strcmp(sin-sif-type, SPICE_INTERFACE_QXL) == 0) {
 +spice_displays++;
 +}
 +
  return spice_server_add_interface(spice_server, sin);
  }
  
 diff --git a/vl.c b/vl.c
 index 25b8f2f..f422a1c 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -4387,7 +4387,7 @@ int main(int argc, char **argv, char **envp)
  }
  #endif
  #ifdef CONFIG_SPICE
 -if (using_spice  !qxl_enabled) {
 +if (using_spice  !spice_displays) {
  qemu_spice_display_init(ds);
  }
  #endif
 --
 1.7.9.7
 
 
 



[Qemu-devel] [PATCH] libcacard/vreader: remove never used define

2013-08-06 Thread Alon Levy
Signed-off-by: Alon Levy al...@redhat.com
---
 libcacard/vreader.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libcacard/vreader.c b/libcacard/vreader.c
index 60eb43b..fd1a9ac 100644
--- a/libcacard/vreader.c
+++ b/libcacard/vreader.c
@@ -21,8 +21,6 @@
 #include vevent.h
 #include cac.h /* just for debugging defines */
 
-#define LIBCACARD_LOG_DOMAIN libcacard
-
 struct VReaderStruct {
 intreference_count;
 VCard *card;
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH 05/21] char: add qemu_chr_fe_event()

2013-11-18 Thread Alon Levy
On 11/18/2013 02:25 PM, Marc-André Lureau wrote:
 From: Marc-André Lureau marcandre.lur...@redhat.com

The patch description is incomplete, or the patch should be split - this
patch also implements qemu_chr_fe_event for spiceport.

 
 Signed-off-by: Marc-André Lureau marcandre.lur...@redhat.com
 ---
  include/sysemu/char.h | 10 ++
  qemu-char.c   |  7 +++
  spice-qemu-char.c | 10 ++
  3 files changed, 27 insertions(+)
 
 diff --git a/include/sysemu/char.h b/include/sysemu/char.h
 index ad101d9..d23c8f1 100644
 --- a/include/sysemu/char.h
 +++ b/include/sysemu/char.h
 @@ -69,6 +69,7 @@ struct CharDriverState {
  void (*chr_accept_input)(struct CharDriverState *chr);
  void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
  void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
 +void (*chr_fe_event)(struct CharDriverState *chr, int event);
  void *opaque;
  char *label;
  char *filename;
 @@ -138,6 +139,15 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, 
 bool echo);
  void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open);
  
  /**
 + * @qemu_chr_fe_event:
 + *
 + * Send an event from the back end to the front end.
 + *
 + * @event the event to send
 + */
 +void qemu_chr_fe_event(CharDriverState *s, int event);
 +
 +/**
   * @qemu_chr_fe_printf:
   *
   * Write to a character backend using a printf style interface.
 diff --git a/qemu-char.c b/qemu-char.c
 index e00f84c..418dc69 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -3353,6 +3353,13 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, 
 int fe_open)
  }
  }
  
 +void qemu_chr_fe_event(struct CharDriverState *chr, int event)
 +{
 +if (chr-chr_fe_event) {
 +chr-chr_fe_event(chr, event);
 +}
 +}
 +
  int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
GIOFunc func, void *user_data)
  {
 diff --git a/spice-qemu-char.c b/spice-qemu-char.c
 index e074d9e..16439c5 100644
 --- a/spice-qemu-char.c
 +++ b/spice-qemu-char.c
 @@ -222,6 +222,15 @@ static void spice_chr_set_fe_open(struct CharDriverState 
 *chr, int fe_open)
  }
  }
  
 +static void spice_chr_fe_event(struct CharDriverState *chr, int event)
 +{
 +#if SPICE_SERVER_VERSION = 0x000c02
 +SpiceCharDriver *s = chr-opaque;
 +
 +spice_server_port_event(s-sin, event);
 +#endif
 +}
 +
  static void print_allowed_subtypes(void)
  {
  const char** psubtype;
 @@ -255,6 +264,7 @@ static CharDriverState *chr_open(const char *subtype)
  chr-chr_close = spice_chr_close;
  chr-chr_set_fe_open = spice_chr_set_fe_open;
  chr-explicit_be_open = true;
 +chr-chr_fe_event = spice_chr_fe_event;
  
  QLIST_INSERT_HEAD(spice_chars, s, next);
  
 




Re: [Qemu-devel] [Spice-devel] [PATCH 20/21] spice-core: allow an interface to be in AIO context

2013-11-18 Thread Alon Levy
On 11/18/2013 02:25 PM, Marc-André Lureau wrote:
 The Spice block driver must be able complete operations within a AIO
 context only.
 
 Spice is currently only running within the main loop, and doesn't allow
 the block driver to complete operations, such as flush during migration.
 
 This patch allows a Spice interface to be associated with a different
 context. Currently, the interface user_data is simply used to
 differentiate main loop from AIO, but could later be used to associate
 an interface with a particular thread.
 
 Signed-off-by: Marc-André Lureau marcandre.lur...@gmail.com
 ---
  include/ui/qemu-spice.h |  2 +-
  qemu-char.c |  2 +-
  spice-qemu-char.c   |  9 +++
  ui/spice-core.c | 62 
 +++--
  4 files changed, 62 insertions(+), 13 deletions(-)
 
 diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
 index a93b4b2..d5ba702 100644
 --- a/include/ui/qemu-spice.h
 +++ b/include/ui/qemu-spice.h
 @@ -48,7 +48,7 @@ int qemu_spice_migrate_info(const char *hostname, int port, 
 int tls_port,
  void do_info_spice_print(Monitor *mon, const QObject *data);
  void do_info_spice(Monitor *mon, QObject **ret_data);
  
 -CharDriverState *qemu_chr_open_spice_vmc(const char *type);
 +CharDriverState *qemu_chr_open_spice_vmc(const char *type, bool aio);
  #if SPICE_SERVER_VERSION = 0x000c02
  CharDriverState *qemu_chr_open_spice_port(const char *name);
  void qemu_spice_register_ports(void);
 diff --git a/qemu-char.c b/qemu-char.c
 index 418dc69..bfac7bf 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -3747,7 +3747,7 @@ ChardevReturn *qmp_chardev_add(const char *id, 
 ChardevBackend *backend,
  #endif
  #ifdef CONFIG_SPICE
  case CHARDEV_BACKEND_KIND_SPICEVMC:
 -chr = qemu_chr_open_spice_vmc(backend-spicevmc-type);
 +chr = qemu_chr_open_spice_vmc(backend-spicevmc-type, false);
  break;
  case CHARDEV_BACKEND_KIND_SPICEPORT:
  chr = qemu_chr_open_spice_port(backend-spiceport-fqdn);
 diff --git a/spice-qemu-char.c b/spice-qemu-char.c
 index 16439c5..421f7de 100644
 --- a/spice-qemu-char.c
 +++ b/spice-qemu-char.c
 @@ -248,7 +248,7 @@ static void print_allowed_subtypes(void)
  fprintf(stderr, \n);
  }
  
 -static CharDriverState *chr_open(const char *subtype)
 +static CharDriverState *chr_open(const char *subtype, bool aio)
  {
  CharDriverState *chr;
  SpiceCharDriver *s;
 @@ -257,6 +257,7 @@ static CharDriverState *chr_open(const char *subtype)
  s = g_malloc0(sizeof(SpiceCharDriver));
  s-chr = chr;
  s-active = false;
 +s-sin.base.user_data = (void*)aio;
  s-sin.subtype = g_strdup(subtype);
  chr-opaque = s;
  chr-chr_write = spice_chr_write;
 @@ -271,7 +272,7 @@ static CharDriverState *chr_open(const char *subtype)
  return chr;
  }
  
 -CharDriverState *qemu_chr_open_spice_vmc(const char *type)
 +CharDriverState *qemu_chr_open_spice_vmc(const char *type, bool aio)
  {
  const char **psubtype = spice_server_char_device_recognized_subtypes();
  
 @@ -291,7 +292,7 @@ CharDriverState *qemu_chr_open_spice_vmc(const char *type)
  return NULL;
  }
  
 -return chr_open(type);
 +return chr_open(type, aio);
  }
  
  #if SPICE_SERVER_VERSION = 0x000c02
 @@ -305,7 +306,7 @@ CharDriverState *qemu_chr_open_spice_port(const char 
 *name)
  return NULL;
  }
  
 -chr = chr_open(port);
 +chr = chr_open(port, false);
  s = chr-opaque;
  s-sin.portname = g_strdup(name);
  
 diff --git a/ui/spice-core.c b/ui/spice-core.c
 index e4d533d..0f69630 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
 @@ -53,34 +53,64 @@ static QemuThread me;
  
  struct SpiceTimer {
  QEMUTimer *timer;
 +QEMUBH *bh;
  QTAILQ_ENTRY(SpiceTimer) next;
  };
  static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
  
 +#if SPICE_INTERFACE_CORE_MAJOR = 2
 +static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque, 
 SpiceBaseInstance *sin)
 +#else
  static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
 +#endif
  {
  SpiceTimer *timer;
  
  timer = g_malloc0(sizeof(*timer));
 -timer-timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
 +
 +#if SPICE_INTERFACE_CORE_MAJOR = 2
 +bool aio = sin ? !!sin-user_data : false;

Shouldn't there be a cast there:
(bool)sin-user_data
?


 +if (aio) {
 +fprintf(stderr, AIO doesn't have timers yet, using BH\n);
 +timer-bh = qemu_bh_new(func, opaque);
 +} else
 +#endif
 +{
 +timer-timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
 +}
 +
  QTAILQ_INSERT_TAIL(timers, timer, next);
 +
  return timer;
  }
  
  static void timer_start(SpiceTimer *timer, uint32_t ms)
  {
 -timer_mod(timer-timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
 +if (timer-bh) {
 +qemu_bh_schedule_idle(timer-bh); /* at least every 10ms, see 
 async.c */
 +} else {
 +

[Qemu-devel] [PATCH] make screendump an async command

2013-06-13 Thread Alon Levy
This fixes the broken screendump behavior for qxl devices in native mode
since 81fb6f1504fb9ef71f2382f44af34756668296e8.

Note: due to QAPI not generating async commands yet I had to remove the
schema screendump definition.

Related RHBZ: 973374
This patch is not enough to fix said bz, with the linux qxl driver you get 
garbage still, just not out of date garbage.

Signed-off-by: Alon Levy al...@redhat.com
---
 hmp.c |  2 +-
 hw/display/qxl-render.c   |  1 +
 hw/display/vga.c  |  1 +
 include/qapi/qmp/qerror.h |  6 +
 include/ui/console.h  | 10 
 qapi-schema.json  | 13 ---
 qmp-commands.hx   |  3 ++-
 ui/console.c  | 58 ++-
 8 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/hmp.c b/hmp.c
index 494a9aa..2a37975 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1346,7 +1346,7 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
 const char *filename = qdict_get_str(qdict, filename);
 Error *err = NULL;
 
-qmp_screendump(filename, err);
+hmp_screen_dump_helper(filename, err);
 hmp_handle_error(mon, err);
 }
 
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index f511a62..d719448 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -139,6 +139,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice 
*qxl)
qxl-dirty[i].bottom - qxl-dirty[i].top);
 }
 qxl-num_dirty_rects = 0;
+console_screendump_complete(vga-con);
 }
 
 /*
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 21a108d..1fc52eb 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1922,6 +1922,7 @@ static void vga_update_display(void *opaque)
 break;
 }
 }
+console_screendump_complete(s-con);
 }
 
 /* force a full display refresh */
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6c0a18d..1bd7efa 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -237,6 +237,12 @@ void assert_no_error(Error *err);
 #define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
 ERROR_CLASS_GENERIC_ERROR, Migration is disabled when VirtFS export path 
'%s' is mounted in the guest using mount_tag '%s'
 
+#define QERR_SCREENDUMP_NOT_AVAILABLE \
+ERROR_CLASS_GENERIC_ERROR, There is no QemuConsole I can screendump from
+
+#define QERR_SCREENDUMP_IN_PROGRESS \
+ERROR_CLASS_GENERIC_ERROR, Existing screendump in progress
+
 #define QERR_SOCKET_CONNECT_FAILED \
 ERROR_CLASS_GENERIC_ERROR, Failed to connect to socket
 
diff --git a/include/ui/console.h b/include/ui/console.h
index 4307b5f..643da45 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -341,4 +341,14 @@ int index_from_keycode(int code);
 void early_gtk_display_init(void);
 void gtk_display_init(DisplayState *ds);
 
+/* hw/display/vga.c hw/display/qxl.c */
+void console_screendump_complete(QemuConsole *con);
+
+/* monitor.c */
+int qmp_screendump(Monitor *mon, const QDict *qdict,
+   MonitorCompletion cb, void *opaque);
+
+/* hmp.c */
+void hmp_screen_dump_helper(const char *filename, Error **errp);
+
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 5ad6894..f5fdc2f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3112,19 +3112,6 @@
   'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
 
 ##
-# @screendump:
-#
-# Write a PPM of the VGA screen to a file.
-#
-# @filename: the path of a new PPM file to store the image
-#
-# Returns: Nothing on success
-#
-# Since: 0.14.0
-##
-{ 'command': 'screendump', 'data': {'filename': 'str'} }
-
-##
 # @nbd-server-start:
 #
 # Start an NBD server listening on the given host and port.  Block
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8cea5e5..bde8f43 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -146,7 +146,8 @@ EQMP
 {
 .name   = screendump,
 .args_type  = filename:F,
-.mhandler.cmd_new = qmp_marshal_input_screendump,
+.mhandler.cmd_async = qmp_screendump,
+.flags  = MONITOR_CMD_ASYNC,
 },
 
 SQMP
diff --git a/ui/console.c b/ui/console.c
index 28bba6d..0efd588 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -116,6 +116,12 @@ typedef enum {
 struct QemuConsole {
 Object parent;
 
+struct {
+char *filename;
+MonitorCompletion *completion_cb;
+void *completion_opaque;
+} screendump;
+
 int index;
 console_type_t console_type;
 DisplayState *ds;
@@ -313,11 +319,61 @@ write_err:
 goto out;
 }
 
-void qmp_screendump(const char *filename, Error **errp)
+int qmp_screendump(Monitor *mon, const QDict *qdict,
+   MonitorCompletion cb, void *opaque)
 {
 QemuConsole *con = qemu_console_lookup_by_index(0);
+const char *filename = qdict_get_str(qdict, filename);
+
+if (con == NULL) {
+qerror_report(QERR_SCREENDUMP_NOT_AVAILABLE);
+return -1;
+}
+if (filename

Re: [Qemu-devel] [PATCH] make screendump an async command

2013-06-13 Thread Alon Levy
 Il 13/06/2013 15:27, Alon Levy ha scritto:
  This fixes the broken screendump behavior for qxl devices in native mode
  since 81fb6f1504fb9ef71f2382f44af34756668296e8.
  
  Note: due to QAPI not generating async commands yet I had to remove the
  schema screendump definition.
  
  Related RHBZ: 973374
  This patch is not enough to fix said bz, with the linux qxl driver you get
  garbage still, just not out of date garbage.
  
  Signed-off-by: Alon Levy al...@redhat.com
  ---
   hmp.c |  2 +-
   hw/display/qxl-render.c   |  1 +
   hw/display/vga.c  |  1 +
   include/qapi/qmp/qerror.h |  6 +
   include/ui/console.h  | 10 
   qapi-schema.json  | 13 ---
   qmp-commands.hx   |  3 ++-
   ui/console.c  | 58
   ++-
   8 files changed, 78 insertions(+), 16 deletions(-)
  
  diff --git a/hmp.c b/hmp.c
  index 494a9aa..2a37975 100644
  --- a/hmp.c
  +++ b/hmp.c
  @@ -1346,7 +1346,7 @@ void hmp_screen_dump(Monitor *mon, const QDict
  *qdict)
   const char *filename = qdict_get_str(qdict, filename);
   Error *err = NULL;
   
  -qmp_screendump(filename, err);
  +hmp_screen_dump_helper(filename, err);
   hmp_handle_error(mon, err);
   }
   
  diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
  index f511a62..d719448 100644
  --- a/hw/display/qxl-render.c
  +++ b/hw/display/qxl-render.c
  @@ -139,6 +139,7 @@ static void
  qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
  qxl-dirty[i].bottom - qxl-dirty[i].top);
   }
   qxl-num_dirty_rects = 0;
  +console_screendump_complete(vga-con);
   }
   
   /*
  diff --git a/hw/display/vga.c b/hw/display/vga.c
  index 21a108d..1fc52eb 100644
  --- a/hw/display/vga.c
  +++ b/hw/display/vga.c
  @@ -1922,6 +1922,7 @@ static void vga_update_display(void *opaque)
   break;
   }
   }
  +console_screendump_complete(s-con);
   }
   
   /* force a full display refresh */
  diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
  index 6c0a18d..1bd7efa 100644
  --- a/include/qapi/qmp/qerror.h
  +++ b/include/qapi/qmp/qerror.h
  @@ -237,6 +237,12 @@ void assert_no_error(Error *err);
   #define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
   ERROR_CLASS_GENERIC_ERROR, Migration is disabled when VirtFS export
   path '%s' is mounted in the guest using mount_tag '%s'
   
  +#define QERR_SCREENDUMP_NOT_AVAILABLE \
  +ERROR_CLASS_GENERIC_ERROR, There is no QemuConsole I can screendump
  from
 
 s/QemuConsole/graphical console/
 
  +#define QERR_SCREENDUMP_IN_PROGRESS \
  +ERROR_CLASS_GENERIC_ERROR, Existing screendump in progress
  +
 
 Please use error_setg instead.

I'm not sure what you are proposing. Something like this?

diff --git a/ui/console.c b/ui/console.c
index 0efd588..3a1e6ed 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -334,7 +334,9 @@ int qmp_screendump(Monitor *mon, const QDict *qdict,
 return -1;
 }
 if (con-screendump.filename != NULL) {
-qerror_report(QERR_SCREENDUMP_IN_PROGRESS);
+QError *err = NULL;
+error_setg(err, Existing screendump in progress);
+monitor_set_error(mon, err);
 return -1;
 }
 con-screendump.filename = g_strdup(filename);

(minus defining err in the inner scope)


 
   #define QERR_SOCKET_CONNECT_FAILED \
   ERROR_CLASS_GENERIC_ERROR, Failed to connect to socket
   
  diff --git a/include/ui/console.h b/include/ui/console.h
  index 4307b5f..643da45 100644
  --- a/include/ui/console.h
  +++ b/include/ui/console.h
  @@ -341,4 +341,14 @@ int index_from_keycode(int code);
   void early_gtk_display_init(void);
   void gtk_display_init(DisplayState *ds);
   
  +/* hw/display/vga.c hw/display/qxl.c */
  +void console_screendump_complete(QemuConsole *con);
  +
  +/* monitor.c */
  +int qmp_screendump(Monitor *mon, const QDict *qdict,
  +   MonitorCompletion cb, void *opaque);
  +
  +/* hmp.c */
  +void hmp_screen_dump_helper(const char *filename, Error **errp);
  +
   #endif
  diff --git a/qapi-schema.json b/qapi-schema.json
  index 5ad6894..f5fdc2f 100644
  --- a/qapi-schema.json
  +++ b/qapi-schema.json
  @@ -3112,19 +3112,6 @@
 'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
   
   ##
  -# @screendump:
  -#
  -# Write a PPM of the VGA screen to a file.
  -#
  -# @filename: the path of a new PPM file to store the image
  -#
  -# Returns: Nothing on success
  -#
  -# Since: 0.14.0
  -##
  -{ 'command': 'screendump', 'data': {'filename': 'str'} }
 
 Please just comment out the declaration with an explanation.
 
 Paolo
 
  -
  -##
   # @nbd-server-start:
   #
   # Start an NBD server listening on the given host and port.  Block
  diff --git a/qmp-commands.hx b/qmp-commands.hx
  index 8cea5e5..bde8f43 100644
  --- a/qmp-commands.hx
  +++ b/qmp-commands.hx
  @@ -146,7 +146,8 @@ EQMP
   {
   .name   = screendump

Re: [Qemu-devel] [PATCH] make screendump an async command

2013-06-14 Thread Alon Levy
 Hi,
 
  Note: due to QAPI not generating async commands yet I had to remove the
  schema screendump definition.
 
 Hmm, that will break libvirt I suspect.  Guess this one has to wait
 until QAPI gained proper async command support.

It doesn't break anything. I've tested, and here is the QMP transcript, the 
only difference is internal to qemu, from libvirt point of view it issues the 
same command and gets the same response:

$ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio
{QMP: {version: {qemu: {micro: 50, minor: 5, major: 1}, package: 
}, capabilities: []}}
{execute:qmp_capabilities}
{return: {}}
{execute:screendump,arguments:{filename:test2.ppm}}
{return: {}}


 
 cheers,
   Gerd
 
 
 
 



Re: [Qemu-devel] [PATCH] make screendump an async command

2013-06-14 Thread Alon Levy
  Hi,
  
   Note: due to QAPI not generating async commands yet I had to remove the
   schema screendump definition.
  
  Hmm, that will break libvirt I suspect.  Guess this one has to wait
  until QAPI gained proper async command support.
 
 It doesn't break anything. I've tested,

To clarify, I tested with virsh screenshot as well.

 and here is the QMP transcript, the
 only difference is internal to qemu, from libvirt point of view it issues
 the same command and gets the same response:
 
 $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio
 {QMP: {version: {qemu: {micro: 50, minor: 5, major: 1},
 package: }, capabilities: []}}
 {execute:qmp_capabilities}
 {return: {}}
 {execute:screendump,arguments:{filename:test2.ppm}}
 {return: {}}
 
 
  
  cheers,
Gerd
  
  
  
  
 
 



Re: [Qemu-devel] [PATCH] make screendump an async command

2013-06-14 Thread Alon Levy
On Fri, 2013-06-14 at 13:21 -0500, Anthony Liguori wrote:
 Alon Levy al...@redhat.com writes:
 
  This fixes the broken screendump behavior for qxl devices in native mode
  since 81fb6f1504fb9ef71f2382f44af34756668296e8.
 
  Note: due to QAPI not generating async commands yet I had to remove the
  schema screendump definition.
 
  Related RHBZ: 973374
  This patch is not enough to fix said bz, with the linux qxl driver you get 
  garbage still, just not out of date garbage.
 
  Signed-off-by: Alon Levy al...@redhat.com
 
 Async commands are badly broken with respect to error handling.

Are there any ideas on how this should work? From the user perspective
nothing changes, so this is an internal qemu design issue afaict.

 
 This needs to be done after we get the new QMP server.

Is there any ETA on this? I'm not pressuring, I'm just trying to figure
out if it is eminent or else I'll add a temporary patch to the
downstream (which is what I'm trying to avoid by sending this patch in
the first place).

 
 Why is QXL unable to do a synchronous screendump?

The qxl device needs to flush all the commands that haven't been
rendered. The rendering is done off thread in the worker thread for that
device. The communication between the threads happens via a pipe that
the io thread is listening to. That is the same thread the qmp command
is received on, so there is no option to block unless I start a new
event loop in there, which is ugly. i.e. I need some kind of bottom
half, like the async command provides, which client_migrate_info uses.

 
 Regards,
 
 Anthony Liguori
 
  ---
   hmp.c |  2 +-
   hw/display/qxl-render.c   |  1 +
   hw/display/vga.c  |  1 +
   include/qapi/qmp/qerror.h |  6 +
   include/ui/console.h  | 10 
   qapi-schema.json  | 13 ---
   qmp-commands.hx   |  3 ++-
   ui/console.c  | 58 
  ++-
   8 files changed, 78 insertions(+), 16 deletions(-)
 
  diff --git a/hmp.c b/hmp.c
  index 494a9aa..2a37975 100644
  --- a/hmp.c
  +++ b/hmp.c
  @@ -1346,7 +1346,7 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
   const char *filename = qdict_get_str(qdict, filename);
   Error *err = NULL;
   
  -qmp_screendump(filename, err);
  +hmp_screen_dump_helper(filename, err);
   hmp_handle_error(mon, err);
   }
   
  diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
  index f511a62..d719448 100644
  --- a/hw/display/qxl-render.c
  +++ b/hw/display/qxl-render.c
  @@ -139,6 +139,7 @@ static void 
  qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
  qxl-dirty[i].bottom - qxl-dirty[i].top);
   }
   qxl-num_dirty_rects = 0;
  +console_screendump_complete(vga-con);
   }
   
   /*
  diff --git a/hw/display/vga.c b/hw/display/vga.c
  index 21a108d..1fc52eb 100644
  --- a/hw/display/vga.c
  +++ b/hw/display/vga.c
  @@ -1922,6 +1922,7 @@ static void vga_update_display(void *opaque)
   break;
   }
   }
  +console_screendump_complete(s-con);
   }
   
   /* force a full display refresh */
  diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
  index 6c0a18d..1bd7efa 100644
  --- a/include/qapi/qmp/qerror.h
  +++ b/include/qapi/qmp/qerror.h
  @@ -237,6 +237,12 @@ void assert_no_error(Error *err);
   #define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
   ERROR_CLASS_GENERIC_ERROR, Migration is disabled when VirtFS export 
  path '%s' is mounted in the guest using mount_tag '%s'
   
  +#define QERR_SCREENDUMP_NOT_AVAILABLE \
  +ERROR_CLASS_GENERIC_ERROR, There is no QemuConsole I can screendump 
  from
  +
  +#define QERR_SCREENDUMP_IN_PROGRESS \
  +ERROR_CLASS_GENERIC_ERROR, Existing screendump in progress
  +
   #define QERR_SOCKET_CONNECT_FAILED \
   ERROR_CLASS_GENERIC_ERROR, Failed to connect to socket
   
  diff --git a/include/ui/console.h b/include/ui/console.h
  index 4307b5f..643da45 100644
  --- a/include/ui/console.h
  +++ b/include/ui/console.h
  @@ -341,4 +341,14 @@ int index_from_keycode(int code);
   void early_gtk_display_init(void);
   void gtk_display_init(DisplayState *ds);
   
  +/* hw/display/vga.c hw/display/qxl.c */
  +void console_screendump_complete(QemuConsole *con);
  +
  +/* monitor.c */
  +int qmp_screendump(Monitor *mon, const QDict *qdict,
  +   MonitorCompletion cb, void *opaque);
  +
  +/* hmp.c */
  +void hmp_screen_dump_helper(const char *filename, Error **errp);
  +
   #endif
  diff --git a/qapi-schema.json b/qapi-schema.json
  index 5ad6894..f5fdc2f 100644
  --- a/qapi-schema.json
  +++ b/qapi-schema.json
  @@ -3112,19 +3112,6 @@
 'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
   
   ##
  -# @screendump:
  -#
  -# Write a PPM of the VGA screen to a file.
  -#
  -# @filename: the path of a new PPM file to store the image
  -#
  -# Returns: Nothing on success
  -#
  -# Since: 0.14.0
  -##
  -{ 'command

Re: [Qemu-devel] [PATCH] make screendump an async command

2013-06-17 Thread Alon Levy
On Mon, 2013-06-17 at 08:06 +0200, Gerd Hoffmann wrote:
   Hi,
 
  Why is QXL unable to do a synchronous screendump?
 
 Lazy rendering.  By default spice-server doesn't render anything, it
 just sends over all drawing ops to the client who does the actual
 rendering for the user.
 
 qemu can kick spice-server and ask it to render stuff locally if needed.
  Happens when either the guest asks for it or when qemu needs it for its
 own purposes.  One reason is screendump, the other is qxl being used
 with gtk/sdl/vnc ui instead of spice.
 
 Today we kick the spice server worker thread to do the rendering, but we
 don't wait for it completing the rendering before writing out the
 screendump.  That isn't perfect of course because you are not guaranteed
 to get a up-to-date dump.  But works good enougth for some use cases
 like autotest, which does screendumps each second anyway, so the actual
 screen dump is at most one second old.
 
 
 Hmm, while thinking about it:  There is another screendump change in the
 pipeline: allow screen dumps from *any* device.  So, I think this is
 actually a very good reason to implement a new screendump command as I
 think we can kill two birds with one stone then:
 
 First we can add a new parameter to specify the device we want dump
 from.  And second we are not bound to the behavior of the existing
 screendump command.  So we could simply send out a qmp event as
 completion (or error) notification.
 
 Comments?

I personally think having an event is not really required, it
complicates things in qemu by requiring the command to return before it
issues any events, i.e. this would be illegal (and breaks libvirt):

Libvirt: { execute: screendump, arguments: { filename:
/tmp/image } }
Qemu: { event: SCREENDUMP_COMPLETE, data : { filename:
screenshot.ppm} }
Qemu: { return: {} }

But on the other hand if this is something that would be acceptable now
and having proper Async error handling is not forthcoming (why btw? is
anyone working on it) . But it would become baggage later on..

 
 cheers,
   Gerd
 
  
  Regards,
  
  Anthony Liguori
  
  ---
   hmp.c |  2 +-
   hw/display/qxl-render.c   |  1 +
   hw/display/vga.c  |  1 +
   include/qapi/qmp/qerror.h |  6 +
   include/ui/console.h  | 10 
   qapi-schema.json  | 13 ---
   qmp-commands.hx   |  3 ++-
   ui/console.c  | 58 
  ++-
   8 files changed, 78 insertions(+), 16 deletions(-)
 
  diff --git a/hmp.c b/hmp.c
  index 494a9aa..2a37975 100644
  --- a/hmp.c
  +++ b/hmp.c
  @@ -1346,7 +1346,7 @@ void hmp_screen_dump(Monitor *mon, const QDict 
  *qdict)
   const char *filename = qdict_get_str(qdict, filename);
   Error *err = NULL;
   
  -qmp_screendump(filename, err);
  +hmp_screen_dump_helper(filename, err);
   hmp_handle_error(mon, err);
   }
   
  diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
  index f511a62..d719448 100644
  --- a/hw/display/qxl-render.c
  +++ b/hw/display/qxl-render.c
  @@ -139,6 +139,7 @@ static void 
  qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
  qxl-dirty[i].bottom - qxl-dirty[i].top);
   }
   qxl-num_dirty_rects = 0;
  +console_screendump_complete(vga-con);
   }
   
   /*
  diff --git a/hw/display/vga.c b/hw/display/vga.c
  index 21a108d..1fc52eb 100644
  --- a/hw/display/vga.c
  +++ b/hw/display/vga.c
  @@ -1922,6 +1922,7 @@ static void vga_update_display(void *opaque)
   break;
   }
   }
  +console_screendump_complete(s-con);
   }
   
   /* force a full display refresh */
  diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
  index 6c0a18d..1bd7efa 100644
  --- a/include/qapi/qmp/qerror.h
  +++ b/include/qapi/qmp/qerror.h
  @@ -237,6 +237,12 @@ void assert_no_error(Error *err);
   #define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
   ERROR_CLASS_GENERIC_ERROR, Migration is disabled when VirtFS export 
  path '%s' is mounted in the guest using mount_tag '%s'
   
  +#define QERR_SCREENDUMP_NOT_AVAILABLE \
  +ERROR_CLASS_GENERIC_ERROR, There is no QemuConsole I can screendump 
  from
  +
  +#define QERR_SCREENDUMP_IN_PROGRESS \
  +ERROR_CLASS_GENERIC_ERROR, Existing screendump in progress
  +
   #define QERR_SOCKET_CONNECT_FAILED \
   ERROR_CLASS_GENERIC_ERROR, Failed to connect to socket
   
  diff --git a/include/ui/console.h b/include/ui/console.h
  index 4307b5f..643da45 100644
  --- a/include/ui/console.h
  +++ b/include/ui/console.h
  @@ -341,4 +341,14 @@ int index_from_keycode(int code);
   void early_gtk_display_init(void);
   void gtk_display_init(DisplayState *ds);
   
  +/* hw/display/vga.c hw/display/qxl.c */
  +void console_screendump_complete(QemuConsole *con);
  +
  +/* monitor.c */
  +int qmp_screendump(Monitor *mon, const QDict *qdict,
  +   MonitorCompletion cb, void *opaque);
  +
  +/* hmp.c */
  +void 

Re: [Qemu-devel] [PATCH] spice: flip streaming video mode to off by default

2013-12-02 Thread Alon Levy
On 12/02/2013 12:27 PM, Gerd Hoffmann wrote:
 Video streaming detection heuristics in spice-server have problems
 keeping modern desktop animations (as done by gnome shell) and real
 video playback apart.  This leads to jpeg compression artefacts on
 your desktop, due to spice using mjpeg to send what it thinks is
 a video stream.
 
 Turn off video detection by default to avoid these artifacts.
 


Reviewed-by: Alon Levy al...@redhat.com

 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  ui/spice-core.c | 2 ++
  1 file changed, 2 insertions(+)
 
 diff --git a/ui/spice-core.c b/ui/spice-core.c
 index e4d533d..9fb9544 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
 @@ -776,6 +776,8 @@ void qemu_spice_init(void)
  if (str) {
  int streaming_video = parse_stream_video(str);
  spice_server_set_streaming_video(spice_server, streaming_video);
 +} else {
 +spice_server_set_streaming_video(spice_server, 
 SPICE_STREAM_VIDEO_OFF);
  }
  
  spice_server_set_agent_mouse
 




Re: [Qemu-devel] [PATCH v2] libcacard: Fix compilation for older versions of glib (bug #1258168)

2013-12-08 Thread Alon Levy
On 12/05/2013 08:41 PM, Stefan Weil wrote:
 See https://bugs.launchpad.net/bugs/1258168
 
 libcacard/vscclient.c: In function 'do_socket_read':
 libcacard/vscclient.c:410: warning: implicit declaration of function 
 'g_warn_if_reached'
 libcacard/vscclient.c:410: warning: nested extern declaration of 
 'g_warn_if_reached'
 libcacard/vscclient.c: In function 'main':
 libcacard/vscclient.c:763: warning: implicit declaration of function 
 'g_byte_array_unref'
 libcacard/vscclient.c:763: warning: nested extern declaration of 
 'g_byte_array_unref'
 ...
 libcacard/vscclient.o: In function `do_socket_read':
 libcacard/vscclient.c:410: undefined reference to `g_warn_if_reached'
 libcacard/vscclient.o: In function `main':
 libcacard/vscclient.c:763: undefined reference to `g_byte_array_unref'
 
 g_warn_if_reached was added in glib 2.16, and g_byte_array_unref is
 supported since glib 2.22. QEMU requires glib 2.12, so both names must
 not be used.
 
 Instead of showing a warning for code which should not be reached, QEMU
 better stops running, so g_warn_if_reached is not useful for QEMU.

Just note that this fix is in vscclient, so this code is not part of
qemu executable. If you are using QEMU (all caps) as the whole project,
the commit message is ok, but it should clarify this is about the
separate vscclient executable.

Other then that ACK, I can send a pull request with the commit message
fixed as I suggested.

 
 In libcacard/vsclient.c, g_byte_array_unref can be replaced by
 g_byte_array_free. This is not generally true, so adding a compatibility
 layer in include/glib-compat.h is no option here.
 
 Reported-by: Laurent Desnogues laurent.desnog...@gmail.com
 Reported-by: Don Slutz dsl...@verizon.com
 Signed-off-by: Stefan Weil s...@weilnetz.de
 ---
 
 v2: Fix commit message and add missing parameter for g_byte_array_free.
 
  libcacard/vscclient.c |4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
 index a3cb776..f1d46d3 100644
 --- a/libcacard/vscclient.c
 +++ b/libcacard/vscclient.c
 @@ -407,7 +407,7 @@ do_socket_read(GIOChannel *source,
  }
  break;
  default:
 -g_warn_if_reached();
 +g_assert_not_reached();
  return FALSE;
  }
  
 @@ -760,7 +760,7 @@ main(
  
  g_io_channel_unref(channel_stdin);
  g_io_channel_unref(channel_socket);
 -g_byte_array_unref(socket_to_send);
 +g_byte_array_free(socket_to_send, TRUE);
  
  closesocket(sock);
  return 0;
 




[Qemu-devel] [PULL] libcacard fixes

2013-12-09 Thread Alon Levy
Anthony,

The following changes since commit a1d22a367d5780c9553b2cd5a24f665534ce6ed6:

  target-cris: Use new qemu_ld/st opcodes (2013-12-08 09:36:02 +0100)

are available in the git repository at:

  git://people.freedesktop.org/~alon/qemu libcacard_ccid.4

for you to fetch changes up to 5ad04fb6f112cf2917909be4c22109dbb65fed18:

  libcacard: Fix compilation for older versions of glib (bug #1258168) 
(2013-12-09 12:19:05 +0200)

Please pull,

Thanks,
Alon


Stefan Weil (1):
  libcacard: Fix compilation for older versions of glib (bug #1258168)

 libcacard/vscclient.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
1.8.4.2




[Qemu-devel] [PULL] libcacard: Fix compilation for older versions of glib (bug #1258168)

2013-12-09 Thread Alon Levy
From: Stefan Weil s...@weilnetz.de

See https://bugs.launchpad.net/bugs/1258168

libcacard/vscclient.c: In function 'do_socket_read':
libcacard/vscclient.c:410: warning: implicit declaration of function 
'g_warn_if_reached'
libcacard/vscclient.c:410: warning: nested extern declaration of 
'g_warn_if_reached'
libcacard/vscclient.c: In function 'main':
libcacard/vscclient.c:763: warning: implicit declaration of function 
'g_byte_array_unref'
libcacard/vscclient.c:763: warning: nested extern declaration of 
'g_byte_array_unref'
...
libcacard/vscclient.o: In function `do_socket_read':
libcacard/vscclient.c:410: undefined reference to `g_warn_if_reached'
libcacard/vscclient.o: In function `main':
libcacard/vscclient.c:763: undefined reference to `g_byte_array_unref'

g_warn_if_reached was added in glib 2.16, and g_byte_array_unref is
supported since glib 2.22. QEMU requires glib 2.12, so both names must
not be used.

Instead of showing a warning for code which should not be reached,
vscclient better stop running, so g_warn_if_reached is not useful for
vscclient.

In libcacard/vsclient.c, g_byte_array_unref can be replaced by
g_byte_array_free. This is not generally true, so adding a compatibility
layer in include/glib-compat.h is no option here.

Reported-by: Laurent Desnogues laurent.desnog...@gmail.com
Reported-by: Don Slutz dsl...@verizon.com
Signed-off-by: Stefan Weil s...@weilnetz.de
---
 libcacard/vscclient.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index a3cb776..f1d46d3 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -407,7 +407,7 @@ do_socket_read(GIOChannel *source,
 }
 break;
 default:
-g_warn_if_reached();
+g_assert_not_reached();
 return FALSE;
 }
 
@@ -760,7 +760,7 @@ main(
 
 g_io_channel_unref(channel_stdin);
 g_io_channel_unref(channel_socket);
-g_byte_array_unref(socket_to_send);
+g_byte_array_free(socket_to_send, TRUE);
 
 closesocket(sock);
 return 0;
-- 
1.8.4.2




Re: [Qemu-devel] [PATCH] monitor: add usb_detach

2010-10-10 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 How is this different than usb_del?  Is it that it detaches it but
 does 
 not delete the device?
 

yes. There is no usb_attach command because it was harder to write (can't
use the bus.addr since a detached device doesn't have them) and I didn't
need it right now, my device attaches itself based on a external event.

 Regards,
 
 Anthony Liguori
 
 On 10/05/2010 09:40 AM, Alon Levy wrote:
  Signed-off-by: Alon Levyal...@redhat.com
 
  ---
qemu-monitor.hx |   17 +
sysemu.h|1 +
vl.c|   41 +
3 files changed, 59 insertions(+), 0 deletions(-)
 
  diff --git a/qemu-monitor.hx b/qemu-monitor.hx
  index 49bcd8d..9c792a9 100644
  --- a/qemu-monitor.hx
  +++ b/qemu-monitor.hx
  @@ -711,6 +711,23 @@ command @code{info usb} to see the devices you
 can remove.
ETEXI
 
{
  +.name   = usb_detach,
  +.args_type  = devname:s,
  +.params = device,
  +.help   = detach USB device 'bus.addr',
  +.mhandler.cmd = do_usb_detach,
  +},
  +
  +STEXI
  +...@item usb_detach @var{devname}
  +...@findex usb_detach
  +
  +Detach the USB device @var{devname} from the QEMU virtual USB
  +hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
  +command @code{info usb} to see the devices you can detach.
  +ETEXI
  +
  +{
.name   = device_add,
.args_type  = device:O,
.params = driver[,prop=value][,...],
  diff --git a/sysemu.h b/sysemu.h
  index a1f6466..ac68863 100644
  --- a/sysemu.h
  +++ b/sysemu.h
  @@ -183,6 +183,7 @@ extern struct soundhw soundhw[];
 
void do_usb_add(Monitor *mon, const QDict *qdict);
void do_usb_del(Monitor *mon, const QDict *qdict);
  +void do_usb_detach(Monitor *mon, const QDict *qdict);
void usb_info(Monitor *mon);
 
void rtc_change_mon_event(struct tm *tm);
  diff --git a/vl.c b/vl.c
  index d352d18..6cfa009 100644
  --- a/vl.c
  +++ b/vl.c
  @@ -891,6 +891,47 @@ void do_usb_del(Monitor *mon, const QDict
 *qdict)
}
}
 
  +static USBDevice *usb_device_from_bus_dot_addr(const char
 *devname)
  +{
  +int bus_num, addr;
  +const char *p;
  +USBBus *bus;
  +USBPort *port;
  +
  +if (!usb_enabled) {
  +return NULL;
  +}
  +p = strchr(devname, '.');
  +if (!p) {
  +return NULL;
  +}
  +bus_num = strtoul(devname, NULL, 0);
  +addr = strtoul(p + 1, NULL, 0);
  +bus = usb_bus_find(bus_num);
  +if (!bus) {
  +return NULL;
  +}
  +QTAILQ_FOREACH(port,bus-used, next) {
  +if (port-dev-addr == addr) {
  +break;
  +}
  +}
  +if (!port) {
  +return NULL;
  +}
  +return port-dev;
  +}
  +
  +void do_usb_detach(Monitor *mon, const QDict *qdict)
  +{
  +const char *devname = qdict_get_str(qdict, devname);
  +USBDevice *dev = usb_device_from_bus_dot_addr(devname);
  +
  +if (dev == NULL || usb_device_detach(dev)  0) {
  +error_report(could not detach USB device '%s', devname);
  +}
  +}
  +
/***/
/* PCMCIA/Cardbus */
 
 



Re: [Qemu-devel] [PATCH] monitor: add usb_detach

2010-10-11 Thread Alon Levy

- Gerd Hoffmann kra...@redhat.com wrote:

 On 10/10/10 13:12, Alon Levy wrote:
 
  - Anthony Liguorianth...@codemonkey.ws  wrote:
 
  How is this different than usb_del?  Is it that it detaches it but
  does
  not delete the device?
 
  yes. There is no usb_attach command because it was harder to write
 (can't
  use the bus.addr since a detached device doesn't have them) and I
 didn't
  need it right now, my device attaches itself based on a external
 event.
 
 Which points out a problem with this patch:  It should better not use
 
 bus.addr.  addr isn't fixed and even can be uninitialized.  Yes,
 usb_del 
 uses it (for historical reasons).  But we better should not use it in
 
 new code.  Better use the device id (like device_del).  Which will
 work 
 for usb_attach too.
 
 Next question:  What is the use case?  attach/detach is used by
 devices 
 internally.  usb-host does attach/detach when devices get plugged-in
 and 
 -out on the host.  The ccid device does simliar things on vsclient 
 connect/disconnect.  So toggeling the attach state via monitor easily
 

debugging. naturally when developing the ccid I had cases where I'd
rather detach the device then bring down qemu. since there is no way
currently to add/remove chardev's from monitor, removing/adding
a device is not enough to reset a device state to the state right
after start.

 could have unwanted side effects ...
 
 cheers,
Gerd



[Qemu-devel] [PATCH 0/2] usb-ccid device (v2)

2010-10-12 Thread Alon Levy
This patch adds a new device, it is described in full in the second patch
intro and also in the documentation in docs. In brief it provides a standard
smart card reader device.

The first patch is the configure change and docs.
The second patch contains the actual device, I couldn't figure out a good
way to split it to ease review.

v2 changed:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (2):
  usb-ccid: add CCID device. add configure option.
  usb-ccid: add CCID device (device itself)

 Makefile.objs  |1 +
 configure  |   12 +
 docs/usb-ccid.txt  |  115 +
 hw/usb-ccid.c  | 1376 
 hw/vscard_common.h |  131 +
 5 files changed, 1635 insertions(+), 0 deletions(-)
 create mode 100644 docs/usb-ccid.txt
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

-- 
1.7.3.1




[Qemu-devel] [PATCH 1/2] usb-ccid: add CCID device. add configure option.

2010-10-12 Thread Alon Levy
This patch adds the configure option --enable-smartcard, adds hw/usb-ccid.c
to Makefile.objs, and adds the documentation. Only an empty hw/usb-ccid.c
is provided (couldn't add an empty file so added initial comment only).

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs  |1 +
 configure  |   12 +
 docs/usb-ccid.txt  |  115 +
 hw/usb-ccid.c  |   13 +
 hw/vscard_common.h |  131 
 5 files changed, 272 insertions(+), 0 deletions(-)
 create mode 100644 docs/usb-ccid.txt
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index 9c13bb3..4b581e7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -170,6 +170,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index e0d34fd..fc59a40 100755
--- a/configure
+++ b/configure
@@ -327,6 +327,7 @@ user_pie=no
 zero_malloc=
 trace_backend=nop
 trace_file=trace
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -730,6 +731,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -921,6 +926,8 @@ echo   --enable-vhost-net   enable vhost-net 
acceleration support
 echo   --trace-backend=BTrace backend nop simple ust
 echo   --trace-file=NAMEFull PATH,NAME of file to store traces
 echoDefault:trace-pid
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2285,6 +2292,7 @@ echo uuid support  $uuid
 echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2540,6 +2548,10 @@ if test $posix_madvise = yes ; then
   echo CONFIG_POSIX_MADVISE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/docs/usb-ccid.txt b/docs/usb-ccid.txt
new file mode 100644
index 000..e418456
--- /dev/null
+++ b/docs/usb-ccid.txt
@@ -0,0 +1,115 @@
+Contents
+1. What is the USB CCID device?
+2. What is it the CCID used for?
+3. How can I remote my smart card reader to the guest?
+4. How do I emulate a smart card using certificates?
+5. Build instructions for qemu with usb-ccid and libcaccard
+6. How does it work?
+
+1. What is the USB CCID device?
+
+The USB CCID device is a USB device implementing the CCID specification, which 
lets one connect smart card readers that implement the same spec. For more 
information see the specification:
+
+ Universal Serial Bus
+ Device Class: Smart Card
+ CCID
+ Specification for
+ Integrated Circuit(s) Cards Interface Devices
+ Revision 1.1
+ April 22rd, 2005
+
+2. What is the CCID used for?
+
+Smartcard are used for authentication, single sign on, decryption in
+public/private schemes and digital signatures. A smartcard reader on the client
+cannot be used on a guest with simple usb passthrough since it will then not be
+available on the client, possibly locking the computer when it is removed. On
+the other hand this device can let you use the smartcard on both the client and
+the guest machine. It is also possible to have a completely virtual smart card
+reader and smart card (i.e. not backed by a physical device) using this device.
+
+3. How do I remote a smartcard reader to the guest?
+
+After following the building instructions for qemu and vscclient run vscclient 
on the client machine (the one with the smart card reader) and qemu on another 
(possibly the same) machine like this:
+
+Assume we use port 2001 on the qemu machine, which we call qemuhost:
+
+on qemuhost: (run this first, qemu acts as the server)
+
+qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb 
-device usb-ccid,chardev=ccid
+
+on client:
+
+vscclient qemuhost 2001
+
+4. How do I emulate a smartcard using certificates?
+
+qmeu side doesn't change.
+
+on client side:
+create the certificates. vscclient uses libcac_card, which currently uses
+NSS as the backend. To create some self signed certificates using nss:
+
+certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s CN=cert1 -n cert1
+
+Note: three certificates are the maximum the emulated card will take.
+
+Then run vscclient with the local

[Qemu-devel] [PATCH 2/2] usb-ccid: add CCID device (device itself)

2010-10-12 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [2].
The usb-ccid device expects a chardev option and uses the VSCARD protocol
defined in vscard_common.h. It starts as an unattached device
unless auto_attach=1.

The utility vscclient, bundled with libcac_card, provides the client side,
together they provide simultaneous access to the card reader an
the card attached to it, both in the guest and client machines, as opposed t
a simple usb host passthrough. You can also use it to provide a virtual card

 [1] libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
 written by Robert Relyea rrel...@redhat.com

 [2] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 hw/usb-ccid.c | 1363 +
 1 files changed, 1363 insertions(+), 0 deletions(-)

diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 98805bb..d9d216c 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -11,3 +11,1366 @@
  * This code is licenced under the LGPL.
  */
 
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. Thsi happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include qemu-char.h
+
+#include hw/vscard_common.h
+
+//#define DEBUG_CCID
+
+static int debug = 0;
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(usb-ccid:  fmt , ## __VA_ARGS__); } } while 
(0)
+
+#define CCID_DEV_NAME usb-ccid
+
+/* The two options for variable sized buffers:
+ * make them constant size, for large enough constant,
+ * or handle the migration complexity - VMState doesn't handle this case.
+ * sizes are expected never to be exceeded, unless client misbehaves. */
+#define BULK_OUT_DATA_SIZE 65536
+#define PENDING_ANSWERS_NUM 128
+#define VSCARD_IN_SIZE 65536
+
+#define BULK_IN_BUF_SIZE 384
+#define BULK_IN_PENDING_NUM 8
+
+#define InterfaceOutClass
((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)8)
+#define InterfaceInClass ((USB_DIR_IN 
|USB_TYPE_CLASS|USB_RECIP_INTERFACE)8)
+
+#define CCID_CONTROL_ABORT  0x1
+#define CCID_CONTROL_GET_CLOCK_FREQUENCIES  0x2
+#define CCID_CONTROL_GET_DATA_RATES 0x3
+
+#define CCID_PRODUCT_DESCRIPTIONQEMU USB CCID
+#define CCID_VENDOR_DESCRIPTION QEMU  QEMU_VERSION
+#define CCID_INTERFACE_NAME CCID Interface
+#define CCID_SERIAL_NUMBER_STRING   1
+/* Using Gemplus Vendor and Product id
+  Effect on various drivers:
+  * usbccid.sys (winxp, others untested) is a class driver so it doesn't care.
+  * linux has a number of class drivers, but openct filters based on
+vendor/product (/etc/openct.conf under fedora), hence Gemplus.
+ */
+#define CCID_VENDOR_ID  0x08e6
+#define CCID_PRODUCT_ID 0x4433
+#define CCID_DEVICE_VERSION 0x
+
+/* BULK_OUT messages from PC to Reader
+   Defined in CCID Rev 1.1 6.1 (page 26)
+ */
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn  0x62
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff 0x63
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus   0x65
+#define CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock0x6f
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters   0x6c
+#define CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters 0x6d
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters   0x61
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Escape  0x6b
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccClock0x6e
+#define CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU  0x6a
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Secure  0x69
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical  0x71
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Abort   0x72
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency 0x73
+
+/* BULK_IN messages from Reader to PC
+   Defined in CCID Rev 1.1 6.2 (page 48)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock   0x80
+#define CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus  0x81
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Parameters  0x82
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Escape  0x83
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataRateAndClockFrequency 0x84
+
+/* INTERRUPT_IN messages from Reader to PC
+   Defined in CCID Rev 1.1 6.3 (page 56)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange0x50
+#define

Re: [Qemu-devel] [PATCH 0/2] usb-ccid device (v2)

2010-10-12 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 On 10/12/2010 07:58 AM, Alon Levy wrote:
  This patch adds a new device, it is described in full in the second
 patch
  intro and also in the documentation in docs. In brief it provides a
 standard
  smart card reader device.
 
  The first patch is the configure change and docs.
  The second patch contains the actual device, I couldn't figure out a
 good
  way to split it to ease review.
 
  v2 changed:
* all QSIMPLEQ turned into fixed sized rings
* all allocated buffers turned into fixed size buffers
* added migration support
* added a message to tell client qemu has migrated to ip:port
 * for lack of monitor commands ip:port are 0:0, which causes the
 updated
  vscclient to connect to one port higher on the same host. will
 add monitor
  commands in a separate patch. tested with current setup.
 
 
 This is way too much magic to live within a device.  Devices manage 
 reconnecting themselves during migration.  When you create the 
 destination qemu instance, you specify what to connect to.
 
 IOW,
 
 On the source:
 
 qemu -chardev tcp:localhost:1025,id=foo -usbdevice ccid,chardev=foo
 ...
 
 On the destination:
 
 qemu -chardev tcp:localhost:1026,id=foo -usbdevice ccid,chardev=foo 
 -incoming tcp:0.0.0.0:1024 ...
 
 A connection happens when the device is created.
 
 But now I'm even further confused then when I first reviewed it..  If
 
 you're now supporting migration, does that mean that you're relying on
 
 the daemon to emulate the device?
 

Let me try to clarify this. Nothing has changed since the last patch except
for what's in the notes, i.e. migration support. The device I'm adding is a
reader. The reader is just a pipe between smart cards and the guest operating
system. The smart card logic does live outside of this device, and is available
in the cac_card sources at http://cgit.freedesktop.org/~alon/cac_card/ (all of
this is in docs/usb_ccid.txt).

So when I speak of vscclient, I'm talking of an application that emulates a 
smart
card and initiates a tcp connection to qemu that connects to the usb-ccid 
device.
vscclient is also in the cac_card sources.

Regarding the method of reconnection: You are absolutely right that if I have 
qemu
connect to the remote instead of the other way around then I remove the need to 
inform
vscclient of the new address. But the way it stands requires the client to know 
the
address of the destination qemu. I have to inform it somehow. You are saying 
that
devices shouldn't know this information? ok, that's why I talked about monitor 
commands.
I come from the world of spice - in spice we use monitor commands for this. I 
could
change this to have qemu connect to vscclient, but I don't see the logic in 
general -
sometimes you do want to have a chardev that is listening (the fact that it is 
implemented
suggests someone found it useful), if you then migrate you have the same 
problem I'm
solving.

 Regards,
 
 Anthony Liguori
 
  Alon Levy (2):
 usb-ccid: add CCID device. add configure option.
 usb-ccid: add CCID device (device itself)
 
Makefile.objs  |1 +
configure  |   12 +
docs/usb-ccid.txt  |  115 +
hw/usb-ccid.c  | 1376
 
hw/vscard_common.h |  131 +
5 files changed, 1635 insertions(+), 0 deletions(-)
create mode 100644 docs/usb-ccid.txt
create mode 100644 hw/usb-ccid.c
create mode 100644 hw/vscard_common.h
 
 



Re: [Qemu-devel] [PATCH 0/2] usb-ccid device (v2)

2010-10-12 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 On 10/12/2010 11:03 AM, Alon Levy wrote:
  - Anthony Liguorianth...@codemonkey.ws  wrote:
 
 
  On 10/12/2010 07:58 AM, Alon Levy wrote:
   
  This patch adds a new device, it is described in full in the
 second
 
  patch
   
  intro and also in the documentation in docs. In brief it provides
 a
 
  standard
   
  smart card reader device.
 
  The first patch is the configure change and docs.
  The second patch contains the actual device, I couldn't figure out
 a
 
  good
   
  way to split it to ease review.
 
  v2 changed:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes
 the
 
  updated
   
   vscclient to connect to one port higher on the same host.
 will
 
  add monitor
   
   commands in a separate patch. tested with current setup.
 
 
  This is way too much magic to live within a device.  Devices
 manage
  reconnecting themselves during migration.  When you create the
  destination qemu instance, you specify what to connect to.
 
  IOW,
 
  On the source:
 
  qemu -chardev tcp:localhost:1025,id=foo -usbdevice
 ccid,chardev=foo
  ...
 
  On the destination:
 
  qemu -chardev tcp:localhost:1026,id=foo -usbdevice
 ccid,chardev=foo
  -incoming tcp:0.0.0.0:1024 ...
 
  A connection happens when the device is created.
 
  But now I'm even further confused then when I first reviewed it.. 
 If
 
  you're now supporting migration, does that mean that you're relying
 on
 
  the daemon to emulate the device?
 
   
  Let me try to clarify this. Nothing has changed since the last patch
 except
  for what's in the notes, i.e. migration support. The device I'm
 adding is a
  reader. The reader is just a pipe between smart cards and the guest
 operating
  system. The smart card logic does live outside of this device, and
 is available
  in the cac_card sources at
 http://cgit.freedesktop.org/~alon/cac_card/ (all of
  this is in docs/usb_ccid.txt).
 
  So when I speak of vscclient, I'm talking of an application that
 emulates a smart
  card and initiates a tcp connection to qemu that connects to the
 usb-ccid device.
  vscclient is also in the cac_card sources.
 
 
 Okay, let me be clear.  We shouldn't be doing device emulation outside
 
 of QEMU's source tree--at least, not in this type of context. 
 External 
 devices present a great deal of challenges and we shouldn't just 
 approach it in an ad-hoc fashion.

There are two devices:
 smart card reader, aka CCID device - emulated inside qemu. Submitted.
 smart card - emulated outside of qemu. Fully available, open source separate 
project.

The idea here is to allow a remote device to be accessed from the guest. The
remote device is not running necessarily on the qemu host, so there has
to be a network connection, which implies some remote client. The only thing
that is changeable is where the card is emulated - at the client side or at qemu
side. I understand you favor qemu. But really this is not that much of a change
as you imply, and there is a good reason for having it on the client side, 
namely
latency of talking to the real card reader. Even if it was local to qemu, it 
would
still have to wait for responses from the network, so I don't see how it would 
be
less fragile.

I don't think the device right now is done ad-hoc, but you are welcome
to comment on anything specific (it is up for review).

(sorry for repeating myself, I guess what follows is the main point): The CCID 
device is a standard USB
class device, some of the USB events are handled without access to the network, 
and some
result in a write to the chardev (==network), which is recorded, and when a 
read from
the chardev happens some resulting USB activity happens. It is not yet without 
errors, but
it is stable, passes migration, and works most of the time. The only exception 
are occasional short
packets that I am still investigating, and hope won't prevent a review of the 
current status.

 
 I'm not opposed to passthrough although I'd prefer QEMU to talk to the
 

passthrough I'm familiar with are all on the same host QEMU is running on,
that goes for pci and usb passthrough (afaik those are the only ones).

 device directly instead of going through a daemon.
 
 There's a lot of delicate integration between QEMU and a device and if
 a 
 device lives outside of QEMU, it makes it extremely difficult for us
 to 
 influence changes to that device to support QEMU new features.
 
  Regarding the method of reconnection: You are absolutely right that
 if I have qemu
  connect to the remote instead of the other way around then I remove
 the need to inform
  vscclient of the new address. But the way it stands requires the
 client

Re: [Qemu-devel] [PATCH 0/2] usb-ccid device (v2)

2010-10-12 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 On 10/12/2010 11:43 AM, Alon Levy wrote:
  - Anthony Liguorianth...@codemonkey.ws  wrote:
 
 
  On 10/12/2010 11:03 AM, Alon Levy wrote:
   
  - Anthony Liguorianth...@codemonkey.ws   wrote:
 
 
 
  On 10/12/2010 07:58 AM, Alon Levy wrote:
 
   
  This patch adds a new device, it is described in full in the
 
  second
   
 
 
  patch
 
   
  intro and also in the documentation in docs. In brief it
 provides
 
  a
   
 
 
  standard
 
   
  smart card reader device.
 
  The first patch is the configure change and docs.
  The second patch contains the actual device, I couldn't figure
 out
 
  a
   
 
 
  good
 
   
  way to split it to ease review.
 
  v2 changed:
  * all QSIMPLEQ turned into fixed sized rings
  * all allocated buffers turned into fixed size buffers
  * added migration support
  * added a message to tell client qemu has migrated to
 ip:port
   * for lack of monitor commands ip:port are 0:0, which
 causes
 
  the
   
 
 
  updated
 
   
vscclient to connect to one port higher on the same host.
 
  will
   
 
 
  add monitor
 
   
commands in a separate patch. tested with current setup.
 
 
 
  This is way too much magic to live within a device.  Devices
   
  manage
   
  reconnecting themselves during migration.  When you create the
  destination qemu instance, you specify what to connect to.
 
  IOW,
 
  On the source:
 
  qemu -chardev tcp:localhost:1025,id=foo -usbdevice
   
  ccid,chardev=foo
   
  ...
 
  On the destination:
 
  qemu -chardev tcp:localhost:1026,id=foo -usbdevice
   
  ccid,chardev=foo
   
  -incoming tcp:0.0.0.0:1024 ...
 
  A connection happens when the device is created.
 
  But now I'm even further confused then when I first reviewed
 it..
   
  If
   
  you're now supporting migration, does that mean that you're
 relying
   
  on
   
  the daemon to emulate the device?
 
 
   
  Let me try to clarify this. Nothing has changed since the last
 patch
 
  except
   
  for what's in the notes, i.e. migration support. The device I'm
 
  adding is a
   
  reader. The reader is just a pipe between smart cards and the
 guest
 
  operating
   
  system. The smart card logic does live outside of this device,
 and
 
  is available
   
  in the cac_card sources at
 
  http://cgit.freedesktop.org/~alon/cac_card/ (all of
   
  this is in docs/usb_ccid.txt).
 
  So when I speak of vscclient, I'm talking of an application that
 
  emulates a smart
   
  card and initiates a tcp connection to qemu that connects to the
 
  usb-ccid device.
   
  vscclient is also in the cac_card sources.
 
 
  Okay, let me be clear.  We shouldn't be doing device emulation
 outside
 
  of QEMU's source tree--at least, not in this type of context.
  External
  devices present a great deal of challenges and we shouldn't just
  approach it in an ad-hoc fashion.
   
  There are two devices:
smart card reader, aka CCID device - emulated inside qemu.
 Submitted.
smart card - emulated outside of qemu. Fully available, open
 source separate project.
 
 
 And how does the smart card state get migrated during migration?  How
 do 
 you keep it synced with QEMU?
The smart card is not being migrated. It is running on the client machine,
which is not being migrated/shutdown (same as vncviewer isn't migrated).

 
 I don't understand the use-case behind this.  Is this so that a local
 
 physical smart card can be passed through to a guest from a Spice
 client 
 and when migration happens, the QEMU instance connects back to the
 Spice 
 client?  So the device is never actually migrated?
 

The *smart card* is never migrated. The ccid device is. Here is the scenario:

Host A: qemu_a
qemu_a: guest

Host B: vscclient
 - physical reader

Host C: qemu_b -incoming ..

yes, we will use this for SPICE, but this is submitted
to qemu on the hopes and with testing ensuring it is perfectly usable as is
without using SPICE, otherwise I wouldn't have sent it upstream.

non-SPICE usage:

1. user on B runs vscclient (and presumably the user has some connection to the 
guest to use the smartcard device, i.e. vnc/ssh/spice, but that's not relevant).
2. vscclient connects via tcp to qemu_a.
3. qemu_a starts migrating to qemu_b.
 (qemu_b is alive at this point, can receive incoming tcp connections on 
chardev - otherwise a migration fails immediately anyway)
4. pre_load for usb-ccid sends a Reconnect message
5. vscclient gets the Reconnect message, closes socket to qemu_a, opens socket 
to qemu_b
6. from guest pov nothing happened (no device detach/attach

Re: [Qemu-devel] [PATCH 0/2] usb-ccid device (v2)

2010-10-13 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 On 10/12/2010 12:09 PM, Alon Levy wrote:
  The smart card is not being migrated. It is running on the client
 machine,
  which is not being migrated/shutdown (same as vncviewer isn't
 migrated).
 
 
 
 Ok, let's look at this compared to another similar use-case: USB 
 passthrough of a webcam device that's remoted using USB over IP.
 
 In this model, you have a USB bus that's modelled as a bus and a 
 device.  Within the USB bus, you have additional devices.  These are
 all 
 qdev devices and they may be emulated or they may be implemented using
 
 passthrough.  While we don't do it today, USB over IP would be just 
 another form of passthrough.
 
 Migration is a rather interesting challenge in this model.  You've got
 a 
 mix of client state and server state on the USB over IP connection. 
 You 
 could marshal up the client state and as long as you reconnected to
 the 
 same server on the destination, I guess it would be okay.
 
 I think the problem with your current implementation is that you've 
 completed skipped the bus modelling and you're also using the Device 
 over IP connection to implement device emulation.
 
 What I would suggest is that you model the bus/device relationship via
 
 qdev and move the Smart Card emulation into QEMU.  I would also
 suggest 
 adding proper passthrough support in QEMU.  CCID over IP is a
 reasonable 
 thing to have but I think you've got way too much outside of QEMU
 right 
 now such that long term maintenance is going to be exceedingly
 difficult.
 

CCID over IP doesn't make any sense (It's just a specific sort of reader), but 
I assume you meant APDU (the smart card protocol) over IP, which is exactly 
what vscard_common.h protocol has (so that's already ready). I'll address the 
modeling of the reader device as a bus and add optional card emulation. You can 
regard the current implementation as exactly passthrough of APDU, that's what 
it does - pushes the APDU's to a remote client, and gets APDUs in return. Since 
I'm using an existing library for the card emulation I will make qemu link with 
it.

Alon

 Regards,
 
 Anthony Liguori
 
  I don't understand the use-case behind this.  Is this so that a
 local
 
  physical smart card can be passed through to a guest from a Spice
  client
  and when migration happens, the QEMU instance connects back to the
  Spice
  client?  So the device is never actually migrated?
 
   
  The *smart card* is never migrated. The ccid device is. Here is the
 scenario:
 
  Host A: qemu_a
  qemu_a: guest
 
  Host B: vscclient
- physical reader
 
  Host C: qemu_b -incoming ..
 
  yes, we will use this for SPICE, but this is submitted
  to qemu on the hopes and with testing ensuring it is perfectly
 usable as is
  without using SPICE, otherwise I wouldn't have sent it upstream.
 
  non-SPICE usage:
 
  1. user on B runs vscclient (and presumably the user has some
 connection to the guest to use the smartcard device, i.e.
 vnc/ssh/spice, but that's not relevant).
  2. vscclient connects via tcp to qemu_a.
  3. qemu_a starts migrating to qemu_b.
(qemu_b is alive at this point, can receive incoming tcp
 connections on chardev - otherwise a migration fails immediately
 anyway)
  4. pre_load for usb-ccid sends a Reconnect message
  5. vscclient gets the Reconnect message, closes socket to qemu_a,
 opens socket to qemu_b
  6. from guest pov nothing happened (no device detach/attach).
 
  I have to stress that the main problem the migration intends to
 solve is to avoid a detach/attach in the guest. Actual
  operations on the smartcard could possibly fail as a result of the
 migration, and it would not be a real problem (i.e.
  we could live without, but we can't leave with a lock of the guest
 screen as a result of a migration). Which is why I
  consider the current code good enough. It is certainly not perfect
 (short packet issue), or tested enough.
 
  The SPICE usage scenario is basically the same, just replace
 vscclient with spicec, and
  we don't need the Reconnect message since SPICE takes care of this
 for us (we just get
  a channel detach/attach event if we care).
  1. user on B runs spicec
  2. spicec connects to qemu via spice channel, smart card channel
 connects to usb-ccid device via spicevmc chardev (so it doesn't care
 it's spice or not).
  3. qemu_a migrates
  4. spicec disconnects from qemu_a and connects to qemu_b
  5. from guest os pov nothing happens on the ccid usb device.
 
 
  Regards,
 
  Anthony Liguori
 



Re: [Qemu-devel] Re: [PATCH] [RFC] Add support for a USB audio device model

2010-10-14 Thread Alon Levy

- H. Peter Anvin h...@zytor.com wrote:

 On 10/14/2010 06:51 AM, Mike Snitzer wrote:
  
  Was just wondering if you've been able to put some time to the
  rate-matching issues?
  
  Has this usb-audio patch evolved and I'm just missing it?
  
  Thanks for doing this work!
  Mike
  
 
 The sad result really is: it doesn't work, and it probably will never
 work.
 

Can you elaborate?

   -hpa
 
 -- 
 H. Peter Anvin, Intel Open Source Technology Center
 I work for Intel.  I don't speak on their behalf.



[Qemu-devel] [PATCH 0/2] usb-ccid (v3)

2010-10-17 Thread Alon Levy
This patchset adds two new devices, usb-ccid and ccid-card-passthru, providing 
a CCID implementation as a bus and a simple passthru protocol implementing card 
requiring a client.

Next patches will add a fully emulated card that can be used standalone to use 
a local (host side) card reader, and documentation (being revised for the new 
bus and multiple cards change)

v3 changes:
 * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
 * removed documentation (being revised).

v2 changed:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (2):
  usb-ccid: add CCID bus
  ccid: add passthru card device

 Makefile.objs   |1 +
 configure   |   12 +
 hw/ccid-card-passthru.c |  284 ++
 hw/ccid.h   |   34 ++
 hw/usb-ccid.c   | 1349 +++
 hw/vscard_common.h  |  130 +
 6 files changed, 1810 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

-- 
1.7.3.1




[Qemu-devel] [PATCH 2/2] ccid: add passthru card device

2010-10-17 Thread Alon Levy
For the client side utility vscclient, see libcac_card:

  libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
  written by Robert Relyea rrel...@redhat.com

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-passthru.c |  284 +++
 hw/vscard_common.h  |  130 +
 3 files changed, 415 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index abcfc5f..3c4a880 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -173,7 +173,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 000..47cf8a0
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,284 @@
+/*
+ * CCID Card Device emulation
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+#include hw/vscard_common.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card:  fmt , ## __VA_ARGS__); } } while 
(0)
+
+static int debug = 0;
+
+/* Passthru card */
+
+
+// TODO: do we still need this?
+uint8_t DEFAULT_ATR[] = {
+/* From some example somewhere
+ 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 
0x13, 0x08
+
+}; /* maximum size of ATR - from 7816-3 */
+
+
+#define PASSTHRU_DEV_NAME ccid-card-passthru
+#define VSCARD_IN_SIZE 65536
+#define MAX_ATR_SIZE40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+CCIDCardState base;
+CharDriverState *cs;
+uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+uint32_t vscard_in_pos;
+uint32_t vscard_in_hdr;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+uint8_t debug;
+};
+
+/* VSCard protocol over chardev
+ * This code should not depend on the card type.
+ * */
+
+static void ccid_card_vscard_send_msg(
+PassthruState *s, VSCMsgType type, reader_id_t reader_id,
+const uint8_t* payload, uint32_t length)
+{
+VSCMsgHeader scr_msg_header;
+
+scr_msg_header.type = type;
+scr_msg_header.reader_id = reader_id;
+scr_msg_header.length = length;
+qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_write(s-cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(
+PassthruState *s, const uint8_t* apdu, uint32_t length)
+{
+ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, 
length);
+}
+
+static void ccid_card_vscard_send_error(
+PassthruState *s, reader_id_t reader_id, VSCErrorCode code)
+{
+VSCMsgError msg = {.code=code};
+
+ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, 
sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+VSCMsgInit msg = {.version=VSCARD_VERSION};
+
+ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+ (uint8_t*)msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+return 65535;
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+VSCMsgHeader* scr_msg_header)
+{
+uint8_t *data = (uint8_t*)scr_msg_header[1];
+
+switch (scr_msg_header-type) {
+case VSC_ATR:
+DPRINTF(1, VSC_ATR %d\n, scr_msg_header-length);
+assert(scr_msg_header-length = MAX_ATR_SIZE);
+memcpy(card-atr, data, scr_msg_header-length);
+card-atr_length = scr_msg_header-length;
+ccid_card_card_inserted(card-base);
+break;
+case VSC_APDU:
+ccid_card_send_apdu_to_guest(card-base, data, 
scr_msg_header-length);
+break;
+case VSC_CardRemove:
+DPRINTF(1, VSC_CardRemove\n);
+ccid_card_card_removed(card-base);
+break;
+case VSC_Init:
+break;
+case VSC_Error:
+ccid_card_card_error(card-base, *(uint64_t*)data);
+break;
+case VSC_ReaderAdd:
+if (ccid_card_ccid_attach(card-base)  0) {
+ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+  VSC_CANNOT_ADD_MORE_READERS);
+} else {
+ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse,
+ VSCARD_MINIMAL_READER_ID, NULL, 
0);
+}
+break

[Qemu-devel] [PATCH 1/2] usb-ccid: add CCID bus

2010-10-17 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs |1 +
 configure |   12 +
 hw/ccid.h |   34 ++
 hw/usb-ccid.c | 1349 +
 4 files changed, 1396 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index 816194a..abcfc5f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -173,6 +173,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 9e65de0..4e05971 100755
--- a/configure
+++ b/configure
@@ -331,6 +331,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -738,6 +739,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -931,6 +936,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2319,6 +2326,7 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2578,6 +2586,10 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 000..a38f971
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,34 @@
+#ifndef __CCID_H__
+#define __CCID_H__
+
+#include qdev.h
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+struct CCIDCardState {
+DeviceState qdev;
+};
+
+struct CCIDCardInfo {
+DeviceInfo qdev;
+void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t 
len);
+int (*exitfn)(CCIDCardState *card);
+int (*initfn)(CCIDCardState *card);
+};
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t 
len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/* support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local) 
*/
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif // __CCID_H__
+
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 000..a7b4c3f
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1349 @@
+/*
+ * CCID Device emulation
+ *
+ * Based on usb-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ * Reused for CCID by Alon Levy.
+ * Contributed to by Robert Relyea
+ * Copyright (c) 2010 Red Hat.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. Thsi happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include monitor.h
+
+#include

[Qemu-devel] [PATCH 0/1] ccid emulated card (v1, for usb-ccid v3)

2010-10-18 Thread Alon Levy
Meant to be applied after the usb-ccid v3 patch on the list.
Causes --enable-smartcard to depend on libcac_card, library for emulating
CAC compliant smart cards at http://cgit.freedesktop.org/~alon/cac_card/

hw/ccid-card-emulated.c: new device
Makefile.objs: add ccid-card-emulated.o if --enable-smartcard
configure: dependency on libcac_card if --enable-smartcard
hw/usb-ccid.c: added a TODO note
hw/ccid-card-passthru.c: removed does-nothing print method.

Alon Levy (1):
  add ccid-card-emulated device

 Makefile.objs   |2 +-
 configure   |   20 ++
 hw/ccid-card-emulated.c |  497 +++
 hw/ccid-card-passthru.c |6 -
 hw/usb-ccid.c   |2 +
 5 files changed, 520 insertions(+), 7 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

-- 
1.7.3.1




[Qemu-devel] [PATCH 1/1] add ccid-card-emulated device

2010-10-18 Thread Alon Levy
Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 configure   |   20 ++
 hw/ccid-card-emulated.c |  497 +++
 hw/ccid-card-passthru.c |6 -
 hw/usb-ccid.c   |2 +
 5 files changed, 520 insertions(+), 7 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 3c4a880..ae12546 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -173,7 +173,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 4e05971..31700b0 100755
--- a/configure
+++ b/configure
@@ -2113,6 +2113,26 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  cat  $TMPC  EOF
+#include vscard_common.h
+int main() { return 0; }
+EOF
+  smartcard_cflags=$($pkgconfig --cflags cac_card cac_card 2/dev/null)
+  smartcard_libs=$($pkgconfig --libs cac_card cac_card 2/dev/null)
+  if $pkgconfig --atleast-version=0.0.1 cac_card \
+ compile_prog $smartcard_cflags $smartcard_libs ; then
+smartcard=yes
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..e28d49c
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,497 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card-emul: %s:  fmt , __func__, ## 
__VA_ARGS__); } } while (0)
+
+static int debug = 0;
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated // the default
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; // and guest_apdu_list mutex
+pthread_mutex_t handle_apdu_mutex;
+pthread_cond_t handle_apdu_cond;
+int  pipe[2];
+int  quit_apdu_thread;
+pthread_mutex_t apdu_thread_quit_mutex;
+pthread_cond_t

[Qemu-devel] [PATCH 1/3] qdev: make qdev_find_recursive public

2010-10-19 Thread Alon Levy
---
 hw/qdev.c |2 +-
 hw/qdev.h |1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 35858cb..d669a9d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -477,7 +477,7 @@ static BusState *qbus_find_recursive(BusState *bus, const 
char *name,
 return NULL;
 }
 
-static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
+DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 {
 DeviceState *dev, *ret;
 BusState *child;
diff --git a/hw/qdev.h b/hw/qdev.h
index 579328a..214066e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -177,6 +177,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
  DeviceState *parent, const char *name);
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
 void qbus_free(BusState *bus);
+DeviceState *qdev_find_recursive(BusState *bus, const char *id);
 
 #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
 
-- 
1.7.3.1




[Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v2)

2010-10-19 Thread Alon Levy
This patchset uses id like device_del for attaching/detaching usb
devices. The first two patches ready the way:
 1. makes qdev_find_recursive non static and in qdev.h
 2. adds a usb_device_by_id which goes over the usb buses calling
  qdev_find_recursive
 3. adds the commands that use usb_device_by_id

Alon Levy (3):
  qdev: make qdev_find_recursive public
  usb: add public usb_device_by_id
  monitor: add usb_attach and usb_detach

 hmp-commands.hx |   34 ++
 hw/qdev.c   |2 +-
 hw/qdev.h   |1 +
 hw/usb-bus.c|   16 
 hw/usb.h|1 +
 sysemu.h|2 ++
 vl.c|   31 +++
 7 files changed, 86 insertions(+), 1 deletions(-)

-- 
1.7.3.1




[Qemu-devel] [PATCH 2/3] usb: add public usb_device_by_id

2010-10-19 Thread Alon Levy
---
 hw/usb-bus.c |   16 
 hw/usb.h |1 +
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index b692503..d732bd3 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -189,6 +189,22 @@ int usb_device_detach(USBDevice *dev)
 return 0;
 }
 
+USBDevice *usb_device_by_id(const char* id)
+{
+USBBus *bus;
+DeviceState *qdev;
+USBDevice *dev;
+
+QTAILQ_FOREACH(bus, busses, next) {
+qdev = qdev_find_recursive(bus-qbus, id);
+if (qdev != NULL) {
+dev = DO_UPCAST(USBDevice, qdev, qdev);
+return dev;
+}
+}
+return NULL;
+}
+
 int usb_device_delete_addr(int busnr, int addr)
 {
 USBBus *bus;
diff --git a/hw/usb.h b/hw/usb.h
index 00d2802..e70fccd 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -317,6 +317,7 @@ void usb_unregister_port(USBBus *bus, USBPort *port);
 int usb_device_attach(USBDevice *dev);
 int usb_device_detach(USBDevice *dev);
 int usb_device_delete_addr(int busnr, int addr);
+USBDevice *usb_device_by_id(const char* id);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
-- 
1.7.3.1




[Qemu-devel] [PATCH 3/3] monitor: add usb_attach and usb_detach

2010-10-19 Thread Alon Levy
---
 hmp-commands.hx |   34 ++
 sysemu.h|2 ++
 vl.c|   31 +++
 3 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 81999aa..660205c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -517,6 +517,40 @@ command @code{info usb} to see the devices you can remove.
 ETEXI
 
 {
+.name   = usb_attach,
+.args_type  = id:s,
+.params = device,
+.help   = attach USB device 'bus.addr',
+.mhandler.cmd = do_usb_attach,
+},
+
+STEXI
+...@item usb_attach @var{devname}
+...@findex usb_attach
+
+Attach the USB device @var{devname} to the QEMU virtual USB
+hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
+command @code{info usb} to see the devices you can attach.
+ETEXI
+
+{
+.name   = usb_detach,
+.args_type  = id:s,
+.params = device,
+.help   = remove USB device 'bus.addr',
+.mhandler.cmd = do_usb_detach,
+},
+
+STEXI
+...@item usb_detach @var{devname}
+...@findex usb_detach
+
+Detach the USB device @var{devname} from the QEMU virtual USB
+hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
+command @code{info usb} to see the devices you can detach.
+ETEXI
+
+{
 .name   = device_add,
 .args_type  = device:O,
 .params = driver[,prop=value][,...],
diff --git a/sysemu.h b/sysemu.h
index b81a70e..1dc0e58 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -182,6 +182,8 @@ extern struct soundhw soundhw[];
 
 void do_usb_add(Monitor *mon, const QDict *qdict);
 void do_usb_del(Monitor *mon, const QDict *qdict);
+void do_usb_attach(Monitor *mon, const QDict *qdict);
+void do_usb_detach(Monitor *mon, const QDict *qdict);
 void usb_info(Monitor *mon);
 
 void rtc_change_mon_event(struct tm *tm);
diff --git a/vl.c b/vl.c
index df414ef..35db6c8 100644
--- a/vl.c
+++ b/vl.c
@@ -894,6 +894,37 @@ void do_usb_del(Monitor *mon, const QDict *qdict)
 }
 }
 
+void do_usb_attach(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_str(qdict, id);
+USBDevice *dev;
+
+dev = usb_device_by_id(id);
+
+if (dev == NULL) {
+error_report(no such USB device '%s', id);
+return;
+}
+if (usb_device_attach(dev)  0) {
+error_report(could not attach USB device '%s', id);
+}
+}
+
+void do_usb_detach(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_str(qdict, id);
+USBDevice *dev;
+
+dev = usb_device_by_id(id);
+if (dev == NULL) {
+error_report(no such USB device '%s', id);
+return;
+}
+if (usb_device_detach(dev)  0) {
+error_report(could not detach USB device '%s', id);
+}
+}
+
 /***/
 /* PCMCIA/Cardbus */
 
-- 
1.7.3.1




[Qemu-devel] [PATCH 0/1] ccid emulated card (v2, for usb-ccid v3)

2010-10-19 Thread Alon Levy
v2 changes:
 fixed a bug that made certificates emulation not work, and some cleanup.

v1 message:

Meant to be applied after the usb-ccid v3 patch on the list.
Causes --enable-smartcard to depend on libcac_card, library for emulating
CAC compliant smart cards at http://cgit.freedesktop.org/~alon/cac_card/

hw/ccid-card-emulated.c: new device
Makefile.objs: add ccid-card-emulated.o if --enable-smartcard
configure: dependency on libcac_card if --enable-smartcard
hw/usb-ccid.c: added a TODO note
hw/ccid-card-passthru.c: removed does-nothing print method.

Alon Levy (1):
  add ccid-card-emulated device (v2)

 Makefile.objs   |2 +-
 configure   |   20 ++
 hw/ccid-card-emulated.c |  495 +++
 hw/ccid-card-passthru.c |6 -
 hw/usb-ccid.c   |2 +
 5 files changed, 518 insertions(+), 7 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

-- 
1.7.3.1




[Qemu-devel] [PATCH 1/1] add ccid-card-emulated device (v2)

2010-10-19 Thread Alon Levy
changes from v1:
remove stale comments, use only c-style comments
bugfix, forgot to set recv_len
change reader name to 'Virtual Reader'

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 configure   |   20 ++
 hw/ccid-card-emulated.c |  495 +++
 hw/ccid-card-passthru.c |6 -
 hw/usb-ccid.c   |2 +
 5 files changed, 518 insertions(+), 7 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 3c4a880..ae12546 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -173,7 +173,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index e1922a3..59b8436 100755
--- a/configure
+++ b/configure
@@ -2112,6 +2112,26 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  cat  $TMPC  EOF
+#include vscard_common.h
+int main() { return 0; }
+EOF
+  smartcard_cflags=$($pkgconfig --cflags cac_card cac_card 2/dev/null)
+  smartcard_libs=$($pkgconfig --libs cac_card cac_card 2/dev/null)
+  if $pkgconfig --atleast-version=0.0.1 cac_card \
+ compile_prog $smartcard_cflags $smartcard_libs ; then
+smartcard=yes
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..9eee6b7
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,495 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card-emul: %s:  fmt , __func__, ## 
__VA_ARGS__); } } while (0)
+
+static int debug = 0;
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated /* the default */
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */
+pthread_mutex_t handle_apdu_mutex

Re: [Qemu-devel] [PATCH 2/3] usb: add public usb_device_by_id

2010-10-19 Thread Alon Levy

- Gerd Hoffmann kra...@redhat.com wrote:

  +USBDevice *usb_device_by_id(const char* id)
  +{
  +USBBus *bus;
  +DeviceState *qdev;
  +USBDevice *dev;
  +
  +QTAILQ_FOREACH(bus,busses, next) {
  +qdev = qdev_find_recursive(bus-qbus, id);
  +if (qdev != NULL) {
  +dev = DO_UPCAST(USBDevice, qdev, qdev);
  +return dev;
  +}
  +}
 
 You don't need qdev_find_recursive here.  Have a look at the
 usb_info() 
 code to see how to loop over all usb devices.  Then compare id with 
 USBDevice-qdev.id.
 
 cheers,
Gerd

There is no problem to loop over all usb devices. But first of all I don't want 
to loop on used, since then I miss any detached devices, so I actually do want 
the same behavior of qdev_find_recursive, and since it's already available, why 
rewrite it in a different compilation unit?

Alon



[Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-10-21 Thread Alon Levy
v2-v3 changes:
 * add configure parameter
 * fix docs

v2 message:
This patchset uses id like device_del for attaching/detaching usb
devices. The first two patches ready the way:
 1. makes qdev_find_recursive non static and in qdev.h
 2. adds a usb_device_by_id which goes over the usb buses calling
  qdev_find_recursive
 3. adds the commands that use usb_device_by_id

Alon Levy (3):
  qdev: make qdev_find_recursive public
  usb: add public usb_device_by_id
  monitor: add usb_attach and usb_detach (v2)

 configure   |9 +
 hmp-commands.hx |   38 ++
 hw/qdev.c   |2 +-
 hw/qdev.h   |1 +
 hw/usb-bus.c|   16 
 hw/usb.h|1 +
 sysemu.h|4 
 vl.c|   33 +
 8 files changed, 103 insertions(+), 1 deletions(-)

-- 
1.7.3.1




[Qemu-devel] [PATCH 2/3] usb: add public usb_device_by_id

2010-10-21 Thread Alon Levy
---
 hw/usb-bus.c |   16 
 hw/usb.h |1 +
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index b692503..d732bd3 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -189,6 +189,22 @@ int usb_device_detach(USBDevice *dev)
 return 0;
 }
 
+USBDevice *usb_device_by_id(const char* id)
+{
+USBBus *bus;
+DeviceState *qdev;
+USBDevice *dev;
+
+QTAILQ_FOREACH(bus, busses, next) {
+qdev = qdev_find_recursive(bus-qbus, id);
+if (qdev != NULL) {
+dev = DO_UPCAST(USBDevice, qdev, qdev);
+return dev;
+}
+}
+return NULL;
+}
+
 int usb_device_delete_addr(int busnr, int addr)
 {
 USBBus *bus;
diff --git a/hw/usb.h b/hw/usb.h
index 00d2802..e70fccd 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -317,6 +317,7 @@ void usb_unregister_port(USBBus *bus, USBPort *port);
 int usb_device_attach(USBDevice *dev);
 int usb_device_detach(USBDevice *dev);
 int usb_device_delete_addr(int busnr, int addr);
+USBDevice *usb_device_by_id(const char* id);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
-- 
1.7.3.1




[Qemu-devel] [PATCH 1/3] qdev: make qdev_find_recursive public

2010-10-21 Thread Alon Levy
---
 hw/qdev.c |2 +-
 hw/qdev.h |1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 35858cb..d669a9d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -477,7 +477,7 @@ static BusState *qbus_find_recursive(BusState *bus, const 
char *name,
 return NULL;
 }
 
-static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
+DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 {
 DeviceState *dev, *ret;
 BusState *child;
diff --git a/hw/qdev.h b/hw/qdev.h
index 579328a..214066e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -177,6 +177,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
  DeviceState *parent, const char *name);
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
 void qbus_free(BusState *bus);
+DeviceState *qdev_find_recursive(BusState *bus, const char *id);
 
 #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
 
-- 
1.7.3.1




[Qemu-devel] [PATCH 0/2] add optional root to info qtree

2010-10-21 Thread Alon Levy
Allow viewing of a part of the large qdev tree. The optional argument
is first looked for as a bus id, if that fails a device id is found and
it's parent bus is the root for printing.

Adds sub_args_type callback for each monitor mon_cmd_t to fascilitate the
existing info_cmds args_type and params strings, so monitor_parse_command
will check the arguments for the do_info sub command do_info_qtree.

Alon Levy (2):
  monitor: add sub_args_type for second level parameters
  monitor info qtree: add optional bus id

 hmp-commands.hx |1 +
 hw/qdev.c   |   17 ++---
 hw/qdev.h   |2 +-
 monitor.c   |   47 +--
 4 files changed, 57 insertions(+), 10 deletions(-)

-- 
1.7.3.1




[Qemu-devel] [PATCH 3/3] monitor: add usb_attach and usb_detach (v2)

2010-10-21 Thread Alon Levy
v1-v2 changes:
 * fixed help text (consistent name for parameter)
 * added configure flag, also enabled with --enable-debug
---
 configure   |9 +
 hmp-commands.hx |   38 ++
 sysemu.h|4 
 vl.c|   33 +
 4 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index a869777..229a71a 100755
--- a/configure
+++ b/configure
@@ -292,6 +292,7 @@ gprof=no
 debug_tcg=no
 debug_mon=no
 debug=no
+usb_monitor_attach_detach=no
 strip_opt=yes
 bigendian=no
 mingw32=no
@@ -590,8 +591,11 @@ for opt do
   debug_tcg=yes
   debug_mon=yes
   debug=yes
+  usb_monitor_attach_detach=yes
   strip_opt=no
   ;;
+  --enable-usb-mon-detach) usb_monitor_attach_detach=yes
+  ;;
   --enable-sparse) sparse=yes
   ;;
   --disable-sparse) sparse=no
@@ -854,6 +858,7 @@ echo   --sysconfdir=PATHinstall config in 
PATH/qemu
 echo   --enable-debug-tcg   enable TCG debugging
 echo   --disable-debug-tcg  disable TCG debugging (default)
 echo   --enable-debug   enable common debug build options
+echo   --enable-usb-mon-detach  enable usb monitor attach  detach commands
 echo   --enable-sparse  enable sparse checker
 echo   --disable-sparse disable sparse checker (default)
 echo   --disable-strip  disable stripping binaries
@@ -2311,6 +2316,7 @@ echo host big endian   $bigendian
 echo target list   $target_list
 echo tcg debug enabled $debug_tcg
 echo Mon debug enabled $debug_mon
+echo usb mon detach$usb_monitor_attach_detach
 echo gprof enabled $gprof
 echo sparse enabled$sparse
 echo strip binaries$strip_opt
@@ -2402,6 +2408,9 @@ fi
 if test $debug = yes ; then
   echo CONFIG_DEBUG_EXEC=y  $config_host_mak
 fi
+if test $usb_monitor_attach_detach = yes ; then
+  echo CONFIG_USB_MONITOR_ATTACH_DETACH=y  $config_host_mak
+fi
 if test $strip_opt = yes ; then
   echo STRIP=${strip}  $config_host_mak
 fi
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 81999aa..3014b17 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -516,6 +516,44 @@ hub. @var{devname} has the syntax @code{bus.addr}. Use the 
monitor
 command @code{info usb} to see the devices you can remove.
 ETEXI
 
+#ifdef CONFIG_USB_MONITOR_ATTACH_DETACH
+{
+.name   = usb_attach,
+.args_type  = id:s,
+.params = device,
+.help   = attach USB device by id,
+.mhandler.cmd = do_usb_attach,
+},
+
+STEXI
+...@item usb_attach @var{id}
+...@findex usb_attach
+
+Attach the USB device with id @var{id} to the QEMU virtual USB
+hub. @var{id} should be a previously detached usb device. Use
+...@code{info qtree} to see devices that can be attached. This
+command is for debugging usage only.
+ETEXI
+
+{
+.name   = usb_detach,
+.args_type  = id:s,
+.params = device,
+.help   = remove USB device by id,
+.mhandler.cmd = do_usb_detach,
+},
+
+STEXI
+...@item usb_detach @var{id}
+...@findex usb_detach
+
+Detach the USB device @var{id} from the QEMU virtual USB
+hub. Use the monitor command @code{info usb} to see the
+devices you can detach. This command is for debugging usage
+only.
+ETEXI
+#endif // CONFIG_USB_MONITOR_ATTACH_DETACH
+
 {
 .name   = device_add,
 .args_type  = device:O,
diff --git a/sysemu.h b/sysemu.h
index b81a70e..2e1df04 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -182,6 +182,10 @@ extern struct soundhw soundhw[];
 
 void do_usb_add(Monitor *mon, const QDict *qdict);
 void do_usb_del(Monitor *mon, const QDict *qdict);
+#ifdef CONFIG_USB_MONITOR_ATTACH_DETACH
+void do_usb_attach(Monitor *mon, const QDict *qdict);
+void do_usb_detach(Monitor *mon, const QDict *qdict);
+#endif
 void usb_info(Monitor *mon);
 
 void rtc_change_mon_event(struct tm *tm);
diff --git a/vl.c b/vl.c
index df414ef..f233c84 100644
--- a/vl.c
+++ b/vl.c
@@ -894,6 +894,39 @@ void do_usb_del(Monitor *mon, const QDict *qdict)
 }
 }
 
+#ifdef CONFIG_USB_MONITOR_ATTACH_DETACH
+void do_usb_attach(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_str(qdict, id);
+USBDevice *dev;
+
+dev = usb_device_by_id(id);
+
+if (dev == NULL) {
+error_report(no such USB device '%s', id);
+return;
+}
+if (usb_device_attach(dev)  0) {
+error_report(could not attach USB device '%s', id);
+}
+}
+
+void do_usb_detach(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_str(qdict, id);
+USBDevice *dev;
+
+dev = usb_device_by_id(id);
+if (dev == NULL) {
+error_report(no such USB device '%s', id);
+return;
+}
+if (usb_device_detach(dev)  0) {
+error_report(could not detach USB device '%s', id);
+}
+}
+#endif // CONFIG_USB_MONITOR_ATTACH_DETACH
+
 /***/
 /* PCMCIA/Cardbus */
 
-- 
1.7.3.1




[Qemu-devel] [PATCH 1/2] monitor: add sub_args_type for second level parameters

2010-10-21 Thread Alon Levy
---
 hmp-commands.hx |1 +
 monitor.c   |   13 -
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 3014b17..289fbcb 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1158,6 +1158,7 @@ ETEXI
 .args_type  = item:s?,
 .params = [subcommand],
 .help   = show various information about the system state,
+.sub_args_type = do_info_sub_args_type,
 .mhandler.cmd = do_info,
 },
 
diff --git a/monitor.c b/monitor.c
index 260cc02..7d1d3b1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -107,6 +107,7 @@ typedef struct mon_cmd_t {
 const char *params;
 const char *help;
 void (*user_print)(Monitor *mon, const QObject *data);
+const char *(*sub_args_type)(const QDict *qdict);
 union {
 void (*info)(Monitor *mon);
 void (*info_new)(Monitor *mon, QObject **ret_data);
@@ -3500,6 +3501,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor 
*mon,
 char cmdname[256];
 char buf[1024];
 char *key;
+int did_sub_args_type = 0;
 
 #ifdef DEBUG
 monitor_printf(mon, command='%s'\n, cmdline);
@@ -3520,8 +3522,17 @@ static const mon_cmd_t *monitor_parse_command(Monitor 
*mon,
 typestr = cmd-args_type;
 for(;;) {
 typestr = key_get_info(typestr, key);
-if (!typestr)
+/* Allow for two level parameters definition. Call sub_args_type only
+ * after finished parsing existing args */
+if (!typestr  cmd-sub_args_type != NULL  !did_sub_args_type) {
+if ((typestr = cmd-sub_args_type(qdict)) != NULL) {
+typestr = key_get_info(typestr, key);
+}
+did_sub_args_type = 1;
+}
+if (!typestr) {
 break;
+}
 c = *typestr;
 typestr++;
 switch(c) {
-- 
1.7.3.1




[Qemu-devel] [PATCH 2/2] monitor info qtree: add optional bus id

2010-10-21 Thread Alon Levy
---
 hw/qdev.c |   17 ++---
 hw/qdev.h |2 +-
 monitor.c |   34 +-
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index d669a9d..e6cf7af 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -774,10 +774,21 @@ static void qbus_print(Monitor *mon, BusState *bus, int 
indent)
 }
 #undef qdev_printf
 
-void do_info_qtree(Monitor *mon)
+void do_info_qtree(Monitor *mon, const QDict *qdict)
 {
-if (main_system_bus)
-qbus_print(mon, main_system_bus, 0);
+const char *id;
+BusState *bus = main_system_bus;
+DeviceState *dev;
+
+if (qdict != NULL  (id = qdict_get_try_str(qdict, id)) != NULL) {
+bus = qbus_find_recursive(main_system_bus, id, NULL);
+if (bus == NULL  (dev = qdev_find_recursive(main_system_bus, id)) != 
NULL) {
+bus = dev-parent_bus;
+}
+}
+if (bus) {
+qbus_print(mon, bus, 0);
+}
 }
 
 void do_info_qdm(Monitor *mon)
diff --git a/hw/qdev.h b/hw/qdev.h
index 214066e..c08a525 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -183,7 +183,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const char 
*id);
 
 /*** monitor commands ***/
 
-void do_info_qtree(Monitor *mon);
+void do_info_qtree(Monitor *mon, const QDict *qdict);
 void do_info_qdm(Monitor *mon);
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
diff --git a/monitor.c b/monitor.c
index 7d1d3b1..69ec651 100644
--- a/monitor.c
+++ b/monitor.c
@@ -640,6 +640,26 @@ static void user_async_info_handler(Monitor *mon, const 
mon_cmd_t *cmd)
 }
 }
 
+static const char* do_info_sub_args_type(const QDict *qdict)
+{
+const mon_cmd_t *cmd;
+const char *item = qdict_get_try_str(qdict, item);
+
+if (!item) {
+return NULL;
+}
+for (cmd = info_cmds; cmd-name != NULL; cmd++) {
+if (compare_cmd(item, cmd-name)) {
+break;
+}
+}
+
+if (cmd-name == NULL) {
+return NULL;
+}
+return cmd-args_type;
+}
+
 static void do_info(Monitor *mon, const QDict *qdict)
 {
 const mon_cmd_t *cmd;
@@ -669,7 +689,11 @@ static void do_info(Monitor *mon, const QDict *qdict)
 qobject_decref(info_data);
 }
 } else {
-cmd-mhandler.info(mon);
+if (cmd-params != NULL  cmd-params[0] != 0) {
+cmd-mhandler.cmd(mon, qdict);
+} else {
+cmd-mhandler.info(mon);
+}
 }
 
 return;
@@ -2586,10 +2610,10 @@ static const mon_cmd_t info_cmds[] = {
 },
 {
 .name   = qtree,
-.args_type  = ,
-.params = ,
-.help   = show device tree,
-.mhandler.info = do_info_qtree,
+.args_type  = id:s?,
+.params = device,
+.help   = show device tree (optional root bus/device),
+.mhandler.cmd = do_info_qtree,
 },
 {
 .name   = qdm,
-- 
1.7.3.1




Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-10-21 Thread Alon Levy
On Thu, Oct 21, 2010 at 08:13:19AM -0500, Anthony Liguori wrote:
 On 10/21/2010 08:03 AM, Gerd Hoffmann wrote:
 On 10/21/10 08:36, Alon Levy wrote:
 v2-v3 changes:
   * add configure parameter
   * fix docs
 
 v2 message:
 This patchset uses id like device_del for attaching/detaching usb
 devices. The first two patches ready the way:
   1. makes qdev_find_recursive non static and in qdev.h
   2. adds a usb_device_by_id which goes over the usb buses calling
qdev_find_recursive
   3. adds the commands that use usb_device_by_id
 
 Alon Levy (3):
qdev: make qdev_find_recursive public
usb: add public usb_device_by_id
monitor: add usb_attach and usb_detach (v2)
 
 
 Acked-by: Gerd Hoffmann kra...@redhat.com
 
 Okay, I am still confused about the use-case for this and I don't
 see any further explanation in the commit messages.  I've seen
 debugging but can you be a bit more specific about which cases
 it's needed for?

To elaborate a little more, when using a certificates based card
there is no hardware event (i.e. removing/inserting the physical card)
that causes a usb_detach/attach to the card (both in passthru and
emulated), but otoh certificates is good for testing since it decouples
it from NSS/tcp. So I needed some way to emulate an insert/remove, and
I saw usb_del, which was pretty close, and voila. This is not the same
as card remove/reinsert, but it is exactly what will happen to the
guest when spicec connects/disconnects, since I detach devices on
disconnect and attach on connect.

 
 This is just adding a HMP command.  Is that the right approach or
 was that an unintentional consequence of rebasing post-HMP/QMP
 split?
 
 Regards,
 
 Anthony Liguori
 
 
 cheers,
   Gerd
 
 
 
 



Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-10-21 Thread Alon Levy
On Thu, Oct 21, 2010 at 08:13:19AM -0500, Anthony Liguori wrote:
 On 10/21/2010 08:03 AM, Gerd Hoffmann wrote:
 On 10/21/10 08:36, Alon Levy wrote:
 v2-v3 changes:
   * add configure parameter
   * fix docs
 
 v2 message:
 This patchset uses id like device_del for attaching/detaching usb
 devices. The first two patches ready the way:
   1. makes qdev_find_recursive non static and in qdev.h
   2. adds a usb_device_by_id which goes over the usb buses calling
qdev_find_recursive
   3. adds the commands that use usb_device_by_id
 
 Alon Levy (3):
qdev: make qdev_find_recursive public
usb: add public usb_device_by_id
monitor: add usb_attach and usb_detach (v2)
 
 
 Acked-by: Gerd Hoffmann kra...@redhat.com
 
 Okay, I am still confused about the use-case for this and I don't
 see any further explanation in the commit messages.  I've seen
 debugging but can you be a bit more specific about which cases
 it's needed for?
 

I use it for debugging the usb-ccid device. I think it's useful for
any other usb device tests as well. The existing commands are not
good enough to do a remove/insert of a usb device, since deleting
a device also deletes any chardev associated with it, and there is
no monitor command to add a chardev. Also sometimes you don't want
to close the chardev, just have the guest see a removal/reinsert of
the device.

 This is just adding a HMP command.  Is that the right approach or
 was that an unintentional consequence of rebasing post-HMP/QMP
 split?
 

yes, my bad, I have not used qmp before, I can add the code but no
idea how to test it easily.

 Regards,
 
 Anthony Liguori
 
 
 cheers,
   Gerd
 
 
 
 



Re: [Qemu-devel] [PATCH 3/3] monitor: add usb_attach and usb_detach

2010-10-21 Thread Alon Levy
On Wed, Oct 20, 2010 at 02:24:20PM -0200, Luiz Capitulino wrote:
 On Tue, 19 Oct 2010 15:35:01 +0200
 Gerd Hoffmann kra...@redhat.com wrote:
 
 Hi,
  
   +.help   = attach USB device 'bus.addr',
  
   +...@item usb_attach @var{devname}
  
  /me sees a mismatch here.
  
  There is still the use case question.  Also note that this might have 
  unwanted side effects when drivers automagically attach/detach devices 
  like usb-host.
 
 Alon, did you check this? I hope it doesn't blowup.

I just did, I created
bus
 usb-serial
 usb-hub id=hub1
  usb-serial
  .. (6 more)
  usb-hub id=hub2
   usb-serial
   (6 more)

(verified the guest sees this tree using lsusb -t)

I did usb_detach hub1, and as expected only the first usb-serial remained.
I then did a usb_attach hub1, and no devices appeared. A second usb_attach
gets the expected warning (you tried to attach a device twice).

So It doesn't blow up, but an info qtree showed it's because the rest of
the devices (those below hub1) were still attached. So I think the detach
should take care to detach anything below. If after that attach still won't
cause attach then hub attaches need fixing as well (it should be just causing
attach for devices under it, since the whole protocol for an attach is already
correctly implemented).

 
  Having this purely for debugging/troubleshooting purposes would be fine 
  with me, but the documentation should clearly say so.
 
 Is this useful in production or only in the development of new devices? If
 it's the letter, then I would even prefer enabling them only when DEBUG
 is enabled.
 



Re: [Qemu-devel] [PATCH 1/2] usb-ccid: add CCID bus

2010-10-23 Thread Alon Levy
On Fri, Oct 22, 2010 at 03:49:38PM +0200, Markus Armbruster wrote:
 Alon Levy al...@redhat.com writes:
 
  A CCID device is a smart card reader. It is a USB device, defined at [1].
  This patch introduces the usb-ccid device that is a ccid bus. Next patches 
  will
  introduce two card types to use it, a passthru card and an emulated card.
 
   [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.
 
  Signed-off-by: Alon Levy al...@redhat.com
  ---
   Makefile.objs |1 +
   configure |   12 +
   hw/ccid.h |   34 ++
   hw/usb-ccid.c | 1349 
  +
   4 files changed, 1396 insertions(+), 0 deletions(-)
   create mode 100644 hw/ccid.h
   create mode 100644 hw/usb-ccid.c
 [...]
  diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
  new file mode 100644
  index 000..a7b4c3f
  --- /dev/null
  +++ b/hw/usb-ccid.c
  @@ -0,0 +1,1349 @@
 [...]
  +struct CCIDBus {
  +BusState qbus;
  +USBCCIDState *ccid;
 
 Where does ccid point to?
 
  +};
 [...]
  +static int ccid_initfn(USBDevice *dev)
  +{
  +USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
  +
  +s-bus = ccid_bus_new(dev-qdev);
  +s-card = NULL;
  +s-cardinfo = NULL;
  +s-bus-ccid = s;
 
 Looks like it points back to the device providing the bus.  Why not use
 bus-qbus-parent ?
 

Thanks, will fix.

  +s-migration_state = MIGRATION_NONE;
  +dev-auto_attach = s-auto_attach;
  +debug = s-debug;
 
 Wait a sec!  Each CCID device has its own property debug (defined
 below), but they all copy to the same static debug on initialization.
 In other words, the device initialized last wins.  Ugh.
 

Thanks again. I'll change the DPRINTF to use the device instance (I think
I have it wherever I use DPRINTF), that will eliminate the static.

  +s-migration_target_ip = 0;
  +s-migration_target_port = 0;
  +s-dev.speed = USB_SPEED_FULL;
  +s-notify_slot_change = false;
  +s-powered = true;
  +s-pending_answers_num = 0;
  +s-last_answer_error = 0;
  +s-bulk_in_pending_start = 0;
  +s-bulk_in_pending_end = 0;
  +s-current_bulk_in = NULL;
  +ccid_reset_error_status(s);
  +s-bulk_out_pos = 0;
  +ccid_reset_parameters(s);
  +ccid_reset(s);
  +return 0;
  +}
 [...]
  +static struct USBDeviceInfo ccid_info = {
  +.product_desc   = QEMU USB CCID,
  +.qdev.name  = CCID_DEV_NAME,
  +.qdev.size  = sizeof(USBCCIDState),
  +.qdev.vmsd  = ccid_vmstate,
  +.init   = ccid_initfn,
  +.handle_packet  = usb_generic_handle_packet,
  +.handle_reset   = ccid_handle_reset,
  +.handle_control = ccid_handle_control,
  +.handle_data= ccid_handle_data,
  +.handle_destroy = ccid_handle_destroy,
  +.usbdevice_name = ccid,
  +.qdev.props = (Property[]) {
  +DEFINE_PROP_UINT8(auto_attach, USBCCIDState, auto_attach, 0),
  +DEFINE_PROP_UINT8(debug, USBCCIDState, debug, 0),
  +DEFINE_PROP_END_OF_LIST(),
  +},
  +};
  +
  +
  +static void ccid_register_devices(void)
  +{
  +usb_qdev_register(ccid_info);
  +}
  +device_init(ccid_register_devices)



[Qemu-devel] [PATCH 0/4] usb-ccid (v4)

2010-10-24 Thread Alon Levy
This patchset adds three new devices, usb-ccid, ccid-card-passthru and 
ccid-card-emulated, providing a CCID bus, a simple passthru protocol 
implementing card requiring a client, and a standalone emulated card.

v4 changes just the bus following Markus remarks, but I'm resending everything 
since nothing has been ack'ed yet and it eases review.

v3-v4:
 * remove ccid field in CCIDBus
 * remove static debug
 * add back docs

v2-v3:
 * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
 * removed documentation (being revised).

v1-v2:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (4):
  usb-ccid: add CCID bus
  ccid: add passthru card device
  add ccid-card-emulated device (v2)
  ccid: add docs

 Makefile.objs   |1 +
 configure   |   32 ++
 docs/ccid.txt   |  133 +
 hw/ccid-card-emulated.c |  495 +
 hw/ccid-card-passthru.c |  278 ++
 hw/ccid.h   |   34 ++
 hw/usb-ccid.c   | 1346 +++
 hw/vscard_common.h  |  130 +
 8 files changed, 2449 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt
 create mode 100644 hw/ccid-card-emulated.c
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

-- 
1.7.3.1




[Qemu-devel] [PATCH 2/4] ccid: add passthru card device

2010-10-24 Thread Alon Levy
For the client side utility vscclient, see libcac_card:

  libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
  written by Robert Relyea rrel...@redhat.com

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-passthru.c |  278 +++
 hw/vscard_common.h  |  130 ++
 3 files changed, 409 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index 5b52625..f2966e3 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -174,7 +174,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 000..ed9a833
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,278 @@
+/*
+ * CCID Card Device emulation
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+#include hw/vscard_common.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card:  fmt , ## __VA_ARGS__); } } while 
(0)
+
+static int debug = 0;
+
+/* Passthru card */
+
+
+// TODO: do we still need this?
+uint8_t DEFAULT_ATR[] = {
+/* From some example somewhere
+ 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 
0x13, 0x08
+
+}; /* maximum size of ATR - from 7816-3 */
+
+
+#define PASSTHRU_DEV_NAME ccid-card-passthru
+#define VSCARD_IN_SIZE 65536
+#define MAX_ATR_SIZE40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+CCIDCardState base;
+CharDriverState *cs;
+uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+uint32_t vscard_in_pos;
+uint32_t vscard_in_hdr;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+uint8_t debug;
+};
+
+/* VSCard protocol over chardev
+ * This code should not depend on the card type.
+ * */
+
+static void ccid_card_vscard_send_msg(
+PassthruState *s, VSCMsgType type, reader_id_t reader_id,
+const uint8_t* payload, uint32_t length)
+{
+VSCMsgHeader scr_msg_header;
+
+scr_msg_header.type = type;
+scr_msg_header.reader_id = reader_id;
+scr_msg_header.length = length;
+qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_write(s-cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(
+PassthruState *s, const uint8_t* apdu, uint32_t length)
+{
+ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, 
length);
+}
+
+static void ccid_card_vscard_send_error(
+PassthruState *s, reader_id_t reader_id, VSCErrorCode code)
+{
+VSCMsgError msg = {.code=code};
+
+ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, 
sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+VSCMsgInit msg = {.version=VSCARD_VERSION};
+
+ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+ (uint8_t*)msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+return 65535;
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+VSCMsgHeader* scr_msg_header)
+{
+uint8_t *data = (uint8_t*)scr_msg_header[1];
+
+switch (scr_msg_header-type) {
+case VSC_ATR:
+DPRINTF(1, VSC_ATR %d\n, scr_msg_header-length);
+assert(scr_msg_header-length = MAX_ATR_SIZE);
+memcpy(card-atr, data, scr_msg_header-length);
+card-atr_length = scr_msg_header-length;
+ccid_card_card_inserted(card-base);
+break;
+case VSC_APDU:
+ccid_card_send_apdu_to_guest(card-base, data, 
scr_msg_header-length);
+break;
+case VSC_CardRemove:
+DPRINTF(1, VSC_CardRemove\n);
+ccid_card_card_removed(card-base);
+break;
+case VSC_Init:
+break;
+case VSC_Error:
+ccid_card_card_error(card-base, *(uint64_t*)data);
+break;
+case VSC_ReaderAdd:
+if (ccid_card_ccid_attach(card-base)  0) {
+ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+  VSC_CANNOT_ADD_MORE_READERS);
+} else {
+ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse,
+ VSCARD_MINIMAL_READER_ID, NULL, 
0);
+}
+break

[Qemu-devel] [PATCH 1/4] usb-ccid: add CCID bus

2010-10-24 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs |1 +
 configure |   12 +
 hw/ccid.h |   34 ++
 hw/usb-ccid.c | 1346 +
 4 files changed, 1393 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index f07fb01..5b52625 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -174,6 +174,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index f62c1fe..15aee9e 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -739,6 +740,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -934,6 +939,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2338,6 +2345,7 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2601,6 +2609,10 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 000..a38f971
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,34 @@
+#ifndef __CCID_H__
+#define __CCID_H__
+
+#include qdev.h
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+struct CCIDCardState {
+DeviceState qdev;
+};
+
+struct CCIDCardInfo {
+DeviceInfo qdev;
+void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t 
len);
+int (*exitfn)(CCIDCardState *card);
+int (*initfn)(CCIDCardState *card);
+};
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t 
len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/* support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local) 
*/
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif // __CCID_H__
+
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 000..157405a
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1346 @@
+/*
+ * CCID Device emulation
+ *
+ * Based on usb-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ * Reused for CCID by Alon Levy.
+ * Contributed to by Robert Relyea
+ * Copyright (c) 2010 Red Hat.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. Thsi happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include monitor.h
+
+#include

[Qemu-devel] [PATCH 4/4] ccid: add docs

2010-10-24 Thread Alon Levy
---
 docs/ccid.txt |  133 +
 1 files changed, 133 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt

diff --git a/docs/ccid.txt b/docs/ccid.txt
new file mode 100644
index 000..5eac611
--- /dev/null
+++ b/docs/ccid.txt
@@ -0,0 +1,133 @@
+Qemu CCID Device Documentation.
+
+Contents
+1. USB CCID device
+2. Building
+3. Using ccid-card-emulated with hardware
+4. Using ccid-card-emulated with certificates
+5. Using ccid-card-passthru with client side hardware
+6. Using ccid-card-passthru with client side certificates
+7. Passthrough protocol scenario
+8. libcaccard
+
+1. USB CCID device
+
+The USB CCID device is a USB device implementing the CCID specification, which
+lets one connect smart card readers that implement the same spec. For more
+information see the specification:
+
+ Universal Serial Bus
+ Device Class: Smart Card
+ CCID
+ Specification for
+ Integrated Circuit(s) Cards Interface Devices
+ Revision 1.1
+ April 22rd, 2005
+
+Smartcard are used for authentication, single sign on, decryption in
+public/private schemes and digital signatures. A smartcard reader on the client
+cannot be used on a guest with simple usb passthrough since it will then not be
+available on the client, possibly locking the computer when it is removed. On
+the other hand this device can let you use the smartcard on both the client and
+the guest machine. It is also possible to have a completely virtual smart card
+reader and smart card (i.e. not backed by a physical device) using this device.
+
+2. Building
+
+prerequisites:
+ libcaccard
+
+At the moment there are no binary or source releases, so it has to be retrieved
+from source control:
+
+git clone git://anongit.freedesktop.org/~alon/cac_card
+
+fedora:
+yum install nss-devel
+ubuntu:
+apt-get install libnss3-dev
+(not tested on ubuntu)
+
+build cac_card:
+cd cac_card
+./configure  make  sudo make install
+
+qemu:
+./configure --enable-smartcard  make
+
+Note that if you install to a non default prefix you need to set
+PKG_CONFIG_PATH to compile qemu successfully.
+
+3. Using ccid-card-emulated with hardware
+
+Assuming you have a working smartcard on the host with the current
+user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
+
+qemu -usb -device usb-ccid -device ccid-card-emualated
+
+4. Using ccid-card-emulated with certificates
+
+You must create the certificates. This is a one time process. We use NSS 
certificates:
+
+certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s CN=cert1 -n cert1
+
+Note: you must have exactly three certificates.
+
+Assuming the current user can access the certificates (use certutil -L to 
verify),
+you can use the emulated card type with the certificates backend:
+
+qemu -usb -device usb-ccid -device 
ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
+
+5. Using ccid-card-passthru with client side hardware
+
+on the host specify the ccid-card-passthru device with a suitable chardev:
+
+qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb 
-device usb-ccid -device ccid-card-passthru,chardev=ccid
+
+on the client run vscclient, built when you built the libcaccard library:
+vscclient qemu-host 2001
+
+6. Using ccid-card-passthru with client side certificates
+
+Run qemu as per #5, and run vscclient as follows:
+(Note: vscclient command line interface is in a state of change)
+
+./vscclient -e db=\/etc/pki/nssdb\ use_hw=no 
soft=(,Test,CAC,,cert1,cert2,cert3) qemu-host 2001
+
+7. Passthrough protocol scenario
+
+This is a typical interchange of messages when using the passthru card device.
+usb-ccid is a usb device. It defaults to an unattached usb device on startup.
+usb-ccid expects a chardev and expects the protocol defined in 
cac_card/vscard_common.h to be passed over that.
+A typical interchange is:
+
+client event  |  vscclient   |passthru| usb-ccid  
|  guest event
+--
+  |  VSC_Init||   |
+  |  VSC_ReaderAdd   || attach|
+  |  ||   
|  sees new usb device.
+card inserted |  ||   |
+  |  VSC_ATR ||   |
+  |  ||   
|  guest operation, APDU transfer via CCID
+  |  |   VSC_APDU |   |
+  |  VSC_APDU||   |
+client-physical |  ||   |
+card APDU exchange|  ||   |
+

[Qemu-devel] [PATCH 3/4] add ccid-card-emulated device (v2)

2010-10-24 Thread Alon Levy
changes from v1:
remove stale comments, use only c-style comments
bugfix, forgot to set recv_len
change reader name to 'Virtual Reader'

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 configure   |   20 ++
 hw/ccid-card-emulated.c |  495 +++
 3 files changed, 516 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index f2966e3..736edf1 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -174,7 +174,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 15aee9e..3a0989b 100755
--- a/configure
+++ b/configure
@@ -2130,6 +2130,26 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  cat  $TMPC  EOF
+#include vscard_common.h
+int main() { return 0; }
+EOF
+  smartcard_cflags=$($pkgconfig --cflags cac_card cac_card 2/dev/null)
+  smartcard_libs=$($pkgconfig --libs cac_card cac_card 2/dev/null)
+  if $pkgconfig --atleast-version=0.0.1 cac_card \
+ compile_prog $smartcard_cflags $smartcard_libs ; then
+smartcard=yes
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..9eee6b7
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,495 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card-emul: %s:  fmt , __func__, ## 
__VA_ARGS__); } } while (0)
+
+static int debug = 0;
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated /* the default */
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */
+pthread_mutex_t handle_apdu_mutex;
+pthread_cond_t handle_apdu_cond;
+int  pipe[2];
+int

Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-10-25 Thread Alon Levy
On Fri, Oct 22, 2010 at 07:55:02AM -0500, Anthony Liguori wrote:
 On 10/22/2010 07:48 AM, Luiz Capitulino wrote:
 On Thu, 21 Oct 2010 15:27:23 +0200
 Alon Levyal...@redhat.com  wrote:
 
 On Thu, Oct 21, 2010 at 08:13:19AM -0500, Anthony Liguori wrote:
 On 10/21/2010 08:03 AM, Gerd Hoffmann wrote:
 On 10/21/10 08:36, Alon Levy wrote:
 v2-v3 changes:
   * add configure parameter
   * fix docs
 
 v2 message:
 This patchset uses id like device_del for attaching/detaching usb
 devices. The first two patches ready the way:
   1. makes qdev_find_recursive non static and in qdev.h
   2. adds a usb_device_by_id which goes over the usb buses calling
qdev_find_recursive
   3. adds the commands that use usb_device_by_id
 
 Alon Levy (3):
qdev: make qdev_find_recursive public
usb: add public usb_device_by_id
monitor: add usb_attach and usb_detach (v2)
 
 Acked-by: Gerd Hoffmannkra...@redhat.com
 Okay, I am still confused about the use-case for this and I don't
 see any further explanation in the commit messages.  I've seen
 debugging but can you be a bit more specific about which cases
 it's needed for?
 To elaborate a little more, when using a certificates based card
 there is no hardware event (i.e. removing/inserting the physical card)
 that causes a usb_detach/attach to the card (both in passthru and
 emulated), but otoh certificates is good for testing since it decouples
 it from NSS/tcp. So I needed some way to emulate an insert/remove, and
 I saw usb_del, which was pretty close, and voila. This is not the same
 as card remove/reinsert, but it is exactly what will happen to the
 guest when spicec connects/disconnects, since I detach devices on
 disconnect and attach on connect.
 Looks reasonable to me, specially because this will be protected by
 #ifdef DEBUG. I don't see a big deal in merging this.
 
 I'd just like to see better documentation.  A command isn't useful
 for debugging if noone knows how to use it.
 
 Guarding with an #ifdef isn't necessary.  It should be
 unconditionally enabled otherwise it will bit rot.
 
 Objections, Anthony?
 
 Not with better docs.
 

ok, so no QMP and better docs. Where should the docs go? just have
more descriptive help messages? or in docs/usb_attach_detach.txt (for
example)?

 Regards,
 
 Anthony Liguori
 
 This is just adding a HMP command.  Is that the right approach or
 was that an unintentional consequence of rebasing post-HMP/QMP
 split?
 I don't think this should be available under QMP, it's more a debugging
 command for USB developers.
 
 Regards,
 
 Anthony Liguori
 
 cheers,
   Gerd
 
 
 
 



[al...@redhat.com: [Qemu-devel] [PATCH 0/2] add optional root to info qtree]

2010-10-27 Thread Alon Levy
bump. Doesn't anyone find it useful to view only a part of the
whole qtree? Is there some easy way to do this with current
qemu monitor?

- Forwarded message from Alon Levy al...@redhat.com -

Date: Thu, 21 Oct 2010 08:37:18 +0200
From: Alon Levy al...@redhat.com
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 0/2] add optional root to info qtree

Allow viewing of a part of the large qdev tree. The optional argument
is first looked for as a bus id, if that fails a device id is found and
it's parent bus is the root for printing.

Adds sub_args_type callback for each monitor mon_cmd_t to fascilitate the
existing info_cmds args_type and params strings, so monitor_parse_command
will check the arguments for the do_info sub command do_info_qtree.

Alon Levy (2):
  monitor: add sub_args_type for second level parameters
  monitor info qtree: add optional bus id

 hmp-commands.hx |1 +
 hw/qdev.c   |   17 ++---
 hw/qdev.h   |2 +-
 monitor.c   |   47 +--
 4 files changed, 57 insertions(+), 10 deletions(-)

-- 
1.7.3.1



- End forwarded message -



Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-01 Thread Alon Levy

- Anthony Liguori anth...@codemonkey.ws wrote:

 On 10/29/2010 06:18 AM, Rusty Russell wrote:
  Fixed - updated patch tested and attached.
   
  OK. FWIW, I think this is an awesome idea.
 
 Paravirtual OpenGL or the actual proposed implementation?  Have you 
 looked at the actual code?
 
 If I understand correctly, the implementation is an RPC of opengl 
 commands across virtio that are then rendered on the host to an 
 offscreen buffer.  The buffer is then sent back to the guest in
 rendered 
 form.
 
 But it's possible to mess around with other guests because the opengl
 
 commands are not scrubbed. There have been other proposals in the past
 
 that include a mini JIT that would translate opengl commands into a
 safe 
 form.
 
 Exposing just an opengl RPC transport doesn't seem that useful either.
  
 It ought to be part of a VGA card in order for it to be integrated
 with 
 the rest of the graphics system without a round trip.
 
 The alternative proposal is Spice which so far noone has mentioned.  
 Right now, Spice seems to be taking the right approach to guest 3d
 support.
 

While we (speaking as part of the SPICE developers) want to have the same
support in our virtual GPU for 3d as we have for 2d, we just don't at this
point of time.

 Regards,
 
 Anthony Liguori
 
 I understand others are skeptical,
  but this seems simple and if it works and you're happy to maintain
 it I'm
  happy to let you do it :)
 
  Cheers,
  Rusty.
 
 



Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-04 Thread Alon Levy
On Wed, Nov 03, 2010 at 06:03:50PM +, Ian Molton wrote:
 On 01/11/10 13:28, Anthony Liguori wrote:
 On 11/01/2010 06:53 AM, Alon Levy wrote:
 
 While we (speaking as part of the SPICE developers) want to have the same
 support in our virtual GPU for 3d as we have for 2d, we just don't at
 this point of time.
 
 Would it be helpful to you to have /something/ that works in the
 interim? I'm happy to work with you guys so that we dont need to
 reinvent the wheel ;-)
 

In case it wasn't clear, I think putting virtio-gl is a good idea, exactly 
because it works right now.

[Snip]



Re: [Qemu-devel] [PATCH 1/4] usb-ccid: add CCID bus

2010-11-09 Thread Alon Levy
On Tue, Nov 09, 2010 at 11:11:21AM +0100, Markus Armbruster wrote:
 Alon Levy al...@redhat.com writes:
 
  A CCID device is a smart card reader. It is a USB device, defined at [1].
  This patch introduces the usb-ccid device that is a ccid bus. Next patches 
  will
  introduce two card types to use it, a passthru card and an emulated card.
 
   [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.
 
 The issues I had with v3's PATCH 1/4 have been addressed satisfactorily.
 
 However, 2+3/4 still have the same static debug issue I pointed out for
 1/4:
 
 Wait a sec!  Each CCID device has its own property debug (defined
 below), but they all copy to the same static debug on
 initialization.  In other words, the device initialized last wins.
 Ugh.

Major oops. I'll correct that. Rest of the comments addressed below.
(actually I seem to have corrected it locally but never sent it since
I expected a review of v4 to notice other issues too).

 
 A few more remarks inline.  Not a thorough review, as I'm not familiar
 enough with our USB code to do that with reasonable efficiency.
 
  Signed-off-by: Alon Levy al...@redhat.com
  ---
   Makefile.objs |1 +
   configure |   12 +
   hw/ccid.h |   34 ++
   hw/usb-ccid.c | 1346 
  +
   4 files changed, 1393 insertions(+), 0 deletions(-)
   create mode 100644 hw/ccid.h
   create mode 100644 hw/usb-ccid.c
 
  diff --git a/Makefile.objs b/Makefile.objs
  index f07fb01..5b52625 100644
  --- a/Makefile.objs
  +++ b/Makefile.objs
  @@ -174,6 +174,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
   hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
   hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
   hw-obj-$(CONFIG_DMA) += dma.o
  +hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
   
   # PPC devices
   hw-obj-$(CONFIG_OPENPIC) += openpic.o
  diff --git a/configure b/configure
  index f62c1fe..15aee9e 100755
  --- a/configure
  +++ b/configure
  @@ -332,6 +332,7 @@ zero_malloc=
   trace_backend=nop
   trace_file=trace
   spice=
  +smartcard=no
   
   # OS specific
   if check_define __linux__ ; then
  @@ -739,6 +740,10 @@ for opt do
 ;;
 --enable-vhost-net) vhost_net=yes
 ;;
  +  --disable-smartcard) smartcard=no
  +  ;;
  +  --enable-smartcard) smartcard=yes
  +  ;;
 --*dir)
 ;;
 *) echo ERROR: unknown option $opt; show_help=yes
  @@ -934,6 +939,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file 
  to store traces
   echoDefault:trace-pid
   echo   --disable-spice  disable spice
   echo   --enable-spice   enable spice
  +echo   --disable-smartcard  disable smartcard support
  +echo   --enable-smartcard   enable smartcard support
   echo 
   echo NOTE: The object files are built at the place where configure is 
  launched
   exit 1
  @@ -2338,6 +2345,7 @@ echo vhost-net support $vhost_net
   echo Trace backend $trace_backend
   echo Trace output file $trace_file-pid
   echo spice support $spice
  +echo smartcard support $smartcard
   
   if test $sdl_too_old = yes; then
   echo - Your SDL version is too old - please upgrade to have SDL support
  @@ -2601,6 +2609,10 @@ if test $spice = yes ; then
 echo CONFIG_SPICE=y  $config_host_mak
   fi
   
  +if test $smartcard = yes ; then
  +  echo CONFIG_SMARTCARD=y  $config_host_mak
  +fi
  +
   # XXX: suppress that
   if [ $bsd = yes ] ; then
 echo CONFIG_BSD=y  $config_host_mak
  diff --git a/hw/ccid.h b/hw/ccid.h
  new file mode 100644
  index 000..a38f971
  --- /dev/null
  +++ b/hw/ccid.h
  @@ -0,0 +1,34 @@
  +#ifndef __CCID_H__
  +#define __CCID_H__
  +
  +#include qdev.h
  +
  +typedef struct CCIDCardState CCIDCardState;
  +typedef struct CCIDCardInfo CCIDCardInfo;
  +
  +struct CCIDCardState {
  +DeviceState qdev;
  +};
  +
  +struct CCIDCardInfo {
  +DeviceInfo qdev;
  +void (*print)(Monitor *mon, CCIDCardState *card, int indent);
  +const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
  +void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, 
  uint32_t len);
  +int (*exitfn)(CCIDCardState *card);
  +int (*initfn)(CCIDCardState *card);
  +};
  +
  +void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, 
  uint32_t len);
  +void ccid_card_card_removed(CCIDCardState *card);
  +void ccid_card_card_inserted(CCIDCardState *card);
  +void ccid_card_card_error(CCIDCardState *card, uint64_t error);
  +void ccid_card_qdev_register(CCIDCardInfo *card);
  +
  +/* support guest visible insertion/removal of ccid devices based on actual
  + * devices connected/removed. Called by card implementation (passthru, 
  local) */
  +int ccid_card_ccid_attach(CCIDCardState *card);
  +void ccid_card_ccid_detach(CCIDCardState *card);
  +
  +#endif // __CCID_H__
  +
  diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
  new file mode 100644
  index 000..157405a
  --- /dev/null
  +++ b/hw/usb-ccid.c
  @@ -0,0 +1,1346

[Qemu-devel] [PATCH 2/4] ccid: add passthru card device

2010-11-09 Thread Alon Levy
For the client side utility vscclient, see libcac_card:

  libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
  written by Robert Relyea rrel...@redhat.com

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-passthru.c |  278 +++
 hw/vscard_common.h  |  130 ++
 3 files changed, 409 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index 221eab4..0327535 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,7 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 000..ed9a833
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,278 @@
+/*
+ * CCID Card Device emulation
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+#include hw/vscard_common.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card:  fmt , ## __VA_ARGS__); } } while 
(0)
+
+static int debug = 0;
+
+/* Passthru card */
+
+
+// TODO: do we still need this?
+uint8_t DEFAULT_ATR[] = {
+/* From some example somewhere
+ 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 
0x13, 0x08
+
+}; /* maximum size of ATR - from 7816-3 */
+
+
+#define PASSTHRU_DEV_NAME ccid-card-passthru
+#define VSCARD_IN_SIZE 65536
+#define MAX_ATR_SIZE40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+CCIDCardState base;
+CharDriverState *cs;
+uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+uint32_t vscard_in_pos;
+uint32_t vscard_in_hdr;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+uint8_t debug;
+};
+
+/* VSCard protocol over chardev
+ * This code should not depend on the card type.
+ * */
+
+static void ccid_card_vscard_send_msg(
+PassthruState *s, VSCMsgType type, reader_id_t reader_id,
+const uint8_t* payload, uint32_t length)
+{
+VSCMsgHeader scr_msg_header;
+
+scr_msg_header.type = type;
+scr_msg_header.reader_id = reader_id;
+scr_msg_header.length = length;
+qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_write(s-cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(
+PassthruState *s, const uint8_t* apdu, uint32_t length)
+{
+ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, 
length);
+}
+
+static void ccid_card_vscard_send_error(
+PassthruState *s, reader_id_t reader_id, VSCErrorCode code)
+{
+VSCMsgError msg = {.code=code};
+
+ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, 
sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+VSCMsgInit msg = {.version=VSCARD_VERSION};
+
+ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+ (uint8_t*)msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+return 65535;
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+VSCMsgHeader* scr_msg_header)
+{
+uint8_t *data = (uint8_t*)scr_msg_header[1];
+
+switch (scr_msg_header-type) {
+case VSC_ATR:
+DPRINTF(1, VSC_ATR %d\n, scr_msg_header-length);
+assert(scr_msg_header-length = MAX_ATR_SIZE);
+memcpy(card-atr, data, scr_msg_header-length);
+card-atr_length = scr_msg_header-length;
+ccid_card_card_inserted(card-base);
+break;
+case VSC_APDU:
+ccid_card_send_apdu_to_guest(card-base, data, 
scr_msg_header-length);
+break;
+case VSC_CardRemove:
+DPRINTF(1, VSC_CardRemove\n);
+ccid_card_card_removed(card-base);
+break;
+case VSC_Init:
+break;
+case VSC_Error:
+ccid_card_card_error(card-base, *(uint64_t*)data);
+break;
+case VSC_ReaderAdd:
+if (ccid_card_ccid_attach(card-base)  0) {
+ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+  VSC_CANNOT_ADD_MORE_READERS);
+} else {
+ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse,
+ VSCARD_MINIMAL_READER_ID, NULL, 
0);
+}
+break

[Qemu-devel] [PATCH 1/4] usb-ccid: add CCID bus

2010-11-09 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs |1 +
 configure |   12 +
 hw/ccid.h |   34 ++
 hw/usb-ccid.c | 1342 +
 4 files changed, 1389 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index faf485e..221eab4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,6 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 7025d2b..d1e96bd 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -739,6 +740,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -934,6 +939,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2338,6 +2345,7 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2601,6 +2609,10 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 000..a38f971
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,34 @@
+#ifndef __CCID_H__
+#define __CCID_H__
+
+#include qdev.h
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+struct CCIDCardState {
+DeviceState qdev;
+};
+
+struct CCIDCardInfo {
+DeviceInfo qdev;
+void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t 
len);
+int (*exitfn)(CCIDCardState *card);
+int (*initfn)(CCIDCardState *card);
+};
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t 
len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/* support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local) 
*/
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif // __CCID_H__
+
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 000..66c1dba
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1342 @@
+/*
+ * CCID Device emulation
+ *
+ * Based on usb-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ * Reused for CCID by Alon Levy.
+ * Contributed to by Robert Relyea
+ * Copyright (c) 2010 Red Hat.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include monitor.h
+
+#include

[Qemu-devel] [PATCH 4/4] ccid: add docs

2010-11-09 Thread Alon Levy
---
 docs/ccid.txt |  133 +
 1 files changed, 133 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt

diff --git a/docs/ccid.txt b/docs/ccid.txt
new file mode 100644
index 000..5eac611
--- /dev/null
+++ b/docs/ccid.txt
@@ -0,0 +1,133 @@
+Qemu CCID Device Documentation.
+
+Contents
+1. USB CCID device
+2. Building
+3. Using ccid-card-emulated with hardware
+4. Using ccid-card-emulated with certificates
+5. Using ccid-card-passthru with client side hardware
+6. Using ccid-card-passthru with client side certificates
+7. Passthrough protocol scenario
+8. libcaccard
+
+1. USB CCID device
+
+The USB CCID device is a USB device implementing the CCID specification, which
+lets one connect smart card readers that implement the same spec. For more
+information see the specification:
+
+ Universal Serial Bus
+ Device Class: Smart Card
+ CCID
+ Specification for
+ Integrated Circuit(s) Cards Interface Devices
+ Revision 1.1
+ April 22rd, 2005
+
+Smartcard are used for authentication, single sign on, decryption in
+public/private schemes and digital signatures. A smartcard reader on the client
+cannot be used on a guest with simple usb passthrough since it will then not be
+available on the client, possibly locking the computer when it is removed. On
+the other hand this device can let you use the smartcard on both the client and
+the guest machine. It is also possible to have a completely virtual smart card
+reader and smart card (i.e. not backed by a physical device) using this device.
+
+2. Building
+
+prerequisites:
+ libcaccard
+
+At the moment there are no binary or source releases, so it has to be retrieved
+from source control:
+
+git clone git://anongit.freedesktop.org/~alon/cac_card
+
+fedora:
+yum install nss-devel
+ubuntu:
+apt-get install libnss3-dev
+(not tested on ubuntu)
+
+build cac_card:
+cd cac_card
+./configure  make  sudo make install
+
+qemu:
+./configure --enable-smartcard  make
+
+Note that if you install to a non default prefix you need to set
+PKG_CONFIG_PATH to compile qemu successfully.
+
+3. Using ccid-card-emulated with hardware
+
+Assuming you have a working smartcard on the host with the current
+user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
+
+qemu -usb -device usb-ccid -device ccid-card-emualated
+
+4. Using ccid-card-emulated with certificates
+
+You must create the certificates. This is a one time process. We use NSS 
certificates:
+
+certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s CN=cert1 -n cert1
+
+Note: you must have exactly three certificates.
+
+Assuming the current user can access the certificates (use certutil -L to 
verify),
+you can use the emulated card type with the certificates backend:
+
+qemu -usb -device usb-ccid -device 
ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
+
+5. Using ccid-card-passthru with client side hardware
+
+on the host specify the ccid-card-passthru device with a suitable chardev:
+
+qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb 
-device usb-ccid -device ccid-card-passthru,chardev=ccid
+
+on the client run vscclient, built when you built the libcaccard library:
+vscclient qemu-host 2001
+
+6. Using ccid-card-passthru with client side certificates
+
+Run qemu as per #5, and run vscclient as follows:
+(Note: vscclient command line interface is in a state of change)
+
+./vscclient -e db=\/etc/pki/nssdb\ use_hw=no 
soft=(,Test,CAC,,cert1,cert2,cert3) qemu-host 2001
+
+7. Passthrough protocol scenario
+
+This is a typical interchange of messages when using the passthru card device.
+usb-ccid is a usb device. It defaults to an unattached usb device on startup.
+usb-ccid expects a chardev and expects the protocol defined in 
cac_card/vscard_common.h to be passed over that.
+A typical interchange is:
+
+client event  |  vscclient   |passthru| usb-ccid  
|  guest event
+--
+  |  VSC_Init||   |
+  |  VSC_ReaderAdd   || attach|
+  |  ||   
|  sees new usb device.
+card inserted |  ||   |
+  |  VSC_ATR ||   |
+  |  ||   
|  guest operation, APDU transfer via CCID
+  |  |   VSC_APDU |   |
+  |  VSC_APDU||   |
+client-physical |  ||   |
+card APDU exchange|  ||   |
+

[Qemu-devel] [PATCH 2/4] ccid: add passthru card device

2010-11-09 Thread Alon Levy
For the client side utility vscclient, see libcac_card:

  libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
  written by Robert Relyea rrel...@redhat.com

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-passthru.c |  277 +++
 hw/vscard_common.h  |  130 ++
 3 files changed, 408 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index 221eab4..0327535 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,7 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 000..fbc4124
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,277 @@
+/*
+ * CCID Card Device emulation
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+#include hw/vscard_common.h
+
+#define DPRINTF(card, lvl, fmt, ...) \
+do { if (lvl = card-debug) { printf(ccid-card:  fmt , ## __VA_ARGS__); } } 
while (0)
+
+/* Passthru card */
+
+
+// TODO: do we still need this?
+uint8_t DEFAULT_ATR[] = {
+/* From some example somewhere
+ 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 
0x13, 0x08
+
+}; /* maximum size of ATR - from 7816-3 */
+
+
+#define PASSTHRU_DEV_NAME ccid-card-passthru
+#define VSCARD_IN_SIZE 65536
+#define MAX_ATR_SIZE40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+CCIDCardState base;
+CharDriverState *cs;
+uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+uint32_t vscard_in_pos;
+uint32_t vscard_in_hdr;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+uint8_t debug;
+};
+
+/* VSCard protocol over chardev
+ * This code should not depend on the card type.
+ * */
+
+static void ccid_card_vscard_send_msg(
+PassthruState *s, VSCMsgType type, reader_id_t reader_id,
+const uint8_t* payload, uint32_t length)
+{
+VSCMsgHeader scr_msg_header;
+
+scr_msg_header.type = type;
+scr_msg_header.reader_id = reader_id;
+scr_msg_header.length = length;
+qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_write(s-cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(
+PassthruState *s, const uint8_t* apdu, uint32_t length)
+{
+ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, 
length);
+}
+
+static void ccid_card_vscard_send_error(
+PassthruState *s, reader_id_t reader_id, VSCErrorCode code)
+{
+VSCMsgError msg = {.code=code};
+
+ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, 
sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+VSCMsgInit msg = {.version=VSCARD_VERSION};
+
+ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+ (uint8_t*)msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+return 65535;
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+VSCMsgHeader* scr_msg_header)
+{
+uint8_t *data = (uint8_t*)scr_msg_header[1];
+
+switch (scr_msg_header-type) {
+case VSC_ATR:
+DPRINTF(card, 1, VSC_ATR %d\n, scr_msg_header-length);
+assert(scr_msg_header-length = MAX_ATR_SIZE);
+memcpy(card-atr, data, scr_msg_header-length);
+card-atr_length = scr_msg_header-length;
+ccid_card_card_inserted(card-base);
+break;
+case VSC_APDU:
+ccid_card_send_apdu_to_guest(card-base, data, 
scr_msg_header-length);
+break;
+case VSC_CardRemove:
+DPRINTF(card, 1, VSC_CardRemove\n);
+ccid_card_card_removed(card-base);
+break;
+case VSC_Init:
+break;
+case VSC_Error:
+ccid_card_card_error(card-base, *(uint64_t*)data);
+break;
+case VSC_ReaderAdd:
+if (ccid_card_ccid_attach(card-base)  0) {
+ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+  VSC_CANNOT_ADD_MORE_READERS);
+} else {
+ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse,
+ VSCARD_MINIMAL_READER_ID, NULL, 
0);
+}
+break

Re: [Qemu-devel] [PATCH 0/4] usb-ccid (v5)

2010-11-09 Thread Alon Levy
NACK self. Forgot the statics.

On Tue, Nov 09, 2010 at 01:40:07PM +0200, Alon Levy wrote:
 This patchset adds three new devices, usb-ccid, ccid-card-passthru and
 ccid-card-emulated, providing a CCID bus, a simple passthru protocol
 implementing card requiring a client, and a standalone emulated card.
 
 v4-v5 changes:
  * rebased to latest
  * remove static debug in card devices
  * fix --enable-smartcard to link
  * stall instead of assert when exceeding BULK_OUT_DATA_SIZE
  * make ccid_reserve_recv_buf for too large len discard message, not exit
  * make ccid_reserve_recv_buf return void*
  * fix typo
  * remove commented code in VMState
 
 v3-v4:
  * remove ccid field in CCIDBus
  * remove static debug in bus
  * add back docs
 
 v2-v3:
  * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
  * removed documentation (being revised).
 
 v1-v2:
  * all QSIMPLEQ turned into fixed sized rings
  * all allocated buffers turned into fixed size buffers
  * added migration support
  * added a message to tell client qemu has migrated to ip:port
   * for lack of monitor commands ip:port are 0:0, which causes the updated
vscclient to connect to one port higher on the same host. will add monitor
commands in a separate patch. tested with current setup.
 
 Alon Levy (4):
   usb-ccid: add CCID bus
   ccid: add passthru card device
   add ccid-card-emulated device (v2)
   ccid: add docs
 
  Makefile.objs   |1 +
  configure   |   33 ++
  docs/ccid.txt   |  133 +
  hw/ccid-card-emulated.c |  495 +
  hw/ccid-card-passthru.c |  278 ++
  hw/ccid.h   |   34 ++
  hw/usb-ccid.c   | 1342 
 +++
  hw/vscard_common.h  |  130 +
  8 files changed, 2446 insertions(+), 0 deletions(-)
  create mode 100644 docs/ccid.txt
  create mode 100644 hw/ccid-card-emulated.c
  create mode 100644 hw/ccid-card-passthru.c
  create mode 100644 hw/ccid.h
  create mode 100644 hw/usb-ccid.c
  create mode 100644 hw/vscard_common.h
 
 -- 
 1.7.3.2
 
 



[Qemu-devel] [PATCH 1/4] usb-ccid: add CCID bus

2010-11-09 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs |1 +
 configure |   12 +
 hw/ccid.h |   34 ++
 hw/usb-ccid.c | 1342 +
 4 files changed, 1389 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index faf485e..221eab4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,6 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 7025d2b..d1e96bd 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -739,6 +740,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -934,6 +939,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2338,6 +2345,7 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2601,6 +2609,10 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 000..a38f971
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,34 @@
+#ifndef __CCID_H__
+#define __CCID_H__
+
+#include qdev.h
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+struct CCIDCardState {
+DeviceState qdev;
+};
+
+struct CCIDCardInfo {
+DeviceInfo qdev;
+void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t 
len);
+int (*exitfn)(CCIDCardState *card);
+int (*initfn)(CCIDCardState *card);
+};
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t 
len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/* support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local) 
*/
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif // __CCID_H__
+
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 000..66c1dba
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1342 @@
+/*
+ * CCID Device emulation
+ *
+ * Based on usb-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ * Reused for CCID by Alon Levy.
+ * Contributed to by Robert Relyea
+ * Copyright (c) 2010 Red Hat.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include monitor.h
+
+#include

[Qemu-devel] [PATCH 0/4] usb-ccid (v6)

2010-11-09 Thread Alon Levy
This patchset adds three new devices, usb-ccid, ccid-card-passthru and
ccid-card-emulated, providing a CCID bus, a simple passthru protocol
implementing card requiring a client, and a standalone emulated card.

v5-v6 changes:
 * really remove static debug (I apologize for claiming to have done so before)

v4-v5 changes:
 * rebased to latest
 * remove static debug in card devices
 * fix --enable-smartcard to link
 * stall instead of assert when exceeding BULK_OUT_DATA_SIZE
 * make ccid_reserve_recv_buf for too large len discard message, not exit
 * make ccid_reserve_recv_buf return void*
 * fix typo
 * remove commented code in VMState

v3-v4:
 * remove ccid field in CCIDBus
 * remove static debug in bus
 * add back docs

v2-v3:
 * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
 * removed documentation (being revised).

v1-v2:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (4):
  usb-ccid: add CCID bus
  ccid: add passthru card device
  add ccid-card-emulated device (v2)
  ccid: add docs

 Makefile.objs   |1 +
 configure   |   33 ++
 docs/ccid.txt   |  133 +
 hw/ccid-card-emulated.c |  492 +
 hw/ccid-card-passthru.c |  277 ++
 hw/ccid.h   |   34 ++
 hw/usb-ccid.c   | 1342 +++
 hw/vscard_common.h  |  130 +
 8 files changed, 2442 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt
 create mode 100644 hw/ccid-card-emulated.c
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

-- 
1.7.3.2




[Qemu-devel] [PATCH 3/4] add ccid-card-emulated device (v2)

2010-11-09 Thread Alon Levy
changes from v1:
remove stale comments, use only c-style comments
bugfix, forgot to set recv_len
change reader name to 'Virtual Reader'

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 configure   |   21 ++
 hw/ccid-card-emulated.c |  495 +++
 3 files changed, 517 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 0327535..d1f9c46 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,7 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index d1e96bd..875f3c3 100755
--- a/configure
+++ b/configure
@@ -2130,6 +2130,27 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  cat  $TMPC  EOF
+#include vscard_common.h
+int main() { return 0; }
+EOF
+  smartcard_cflags=$($pkgconfig --cflags cac_card cac_card 2/dev/null)
+  smartcard_libs=$($pkgconfig --libs cac_card cac_card 2/dev/null)
+  if $pkgconfig --atleast-version=0.0.1 cac_card \
+ compile_prog $smartcard_cflags $smartcard_libs ; then
+smartcard=yes
+libs_softmmu=$smartcard_libs $libs_softmmu
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..9eee6b7
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,495 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(lvl, fmt, ...) \
+do { if (lvl = debug) { printf(ccid-card-emul: %s:  fmt , __func__, ## 
__VA_ARGS__); } } while (0)
+
+static int debug = 0;
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated /* the default */
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */
+pthread_mutex_t handle_apdu_mutex;
+pthread_cond_t

[Qemu-devel] [PATCH 0/4] usb-ccid (v5)

2010-11-09 Thread Alon Levy
This patchset adds three new devices, usb-ccid, ccid-card-passthru and
ccid-card-emulated, providing a CCID bus, a simple passthru protocol
implementing card requiring a client, and a standalone emulated card.

v4-v5 changes:
 * rebased to latest
 * remove static debug in card devices
 * fix --enable-smartcard to link
 * stall instead of assert when exceeding BULK_OUT_DATA_SIZE
 * make ccid_reserve_recv_buf for too large len discard message, not exit
 * make ccid_reserve_recv_buf return void*
 * fix typo
 * remove commented code in VMState

v3-v4:
 * remove ccid field in CCIDBus
 * remove static debug in bus
 * add back docs

v2-v3:
 * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
 * removed documentation (being revised).

v1-v2:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (4):
  usb-ccid: add CCID bus
  ccid: add passthru card device
  add ccid-card-emulated device (v2)
  ccid: add docs

 Makefile.objs   |1 +
 configure   |   33 ++
 docs/ccid.txt   |  133 +
 hw/ccid-card-emulated.c |  495 +
 hw/ccid-card-passthru.c |  278 ++
 hw/ccid.h   |   34 ++
 hw/usb-ccid.c   | 1342 +++
 hw/vscard_common.h  |  130 +
 8 files changed, 2446 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt
 create mode 100644 hw/ccid-card-emulated.c
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h

-- 
1.7.3.2




[Qemu-devel] [PATCH 4/4] ccid: add docs

2010-11-09 Thread Alon Levy
---
 docs/ccid.txt |  133 +
 1 files changed, 133 insertions(+), 0 deletions(-)
 create mode 100644 docs/ccid.txt

diff --git a/docs/ccid.txt b/docs/ccid.txt
new file mode 100644
index 000..5eac611
--- /dev/null
+++ b/docs/ccid.txt
@@ -0,0 +1,133 @@
+Qemu CCID Device Documentation.
+
+Contents
+1. USB CCID device
+2. Building
+3. Using ccid-card-emulated with hardware
+4. Using ccid-card-emulated with certificates
+5. Using ccid-card-passthru with client side hardware
+6. Using ccid-card-passthru with client side certificates
+7. Passthrough protocol scenario
+8. libcaccard
+
+1. USB CCID device
+
+The USB CCID device is a USB device implementing the CCID specification, which
+lets one connect smart card readers that implement the same spec. For more
+information see the specification:
+
+ Universal Serial Bus
+ Device Class: Smart Card
+ CCID
+ Specification for
+ Integrated Circuit(s) Cards Interface Devices
+ Revision 1.1
+ April 22rd, 2005
+
+Smartcard are used for authentication, single sign on, decryption in
+public/private schemes and digital signatures. A smartcard reader on the client
+cannot be used on a guest with simple usb passthrough since it will then not be
+available on the client, possibly locking the computer when it is removed. On
+the other hand this device can let you use the smartcard on both the client and
+the guest machine. It is also possible to have a completely virtual smart card
+reader and smart card (i.e. not backed by a physical device) using this device.
+
+2. Building
+
+prerequisites:
+ libcaccard
+
+At the moment there are no binary or source releases, so it has to be retrieved
+from source control:
+
+git clone git://anongit.freedesktop.org/~alon/cac_card
+
+fedora:
+yum install nss-devel
+ubuntu:
+apt-get install libnss3-dev
+(not tested on ubuntu)
+
+build cac_card:
+cd cac_card
+./configure  make  sudo make install
+
+qemu:
+./configure --enable-smartcard  make
+
+Note that if you install to a non default prefix you need to set
+PKG_CONFIG_PATH to compile qemu successfully.
+
+3. Using ccid-card-emulated with hardware
+
+Assuming you have a working smartcard on the host with the current
+user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
+
+qemu -usb -device usb-ccid -device ccid-card-emualated
+
+4. Using ccid-card-emulated with certificates
+
+You must create the certificates. This is a one time process. We use NSS 
certificates:
+
+certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s CN=cert1 -n cert1
+
+Note: you must have exactly three certificates.
+
+Assuming the current user can access the certificates (use certutil -L to 
verify),
+you can use the emulated card type with the certificates backend:
+
+qemu -usb -device usb-ccid -device 
ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
+
+5. Using ccid-card-passthru with client side hardware
+
+on the host specify the ccid-card-passthru device with a suitable chardev:
+
+qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb 
-device usb-ccid -device ccid-card-passthru,chardev=ccid
+
+on the client run vscclient, built when you built the libcaccard library:
+vscclient qemu-host 2001
+
+6. Using ccid-card-passthru with client side certificates
+
+Run qemu as per #5, and run vscclient as follows:
+(Note: vscclient command line interface is in a state of change)
+
+./vscclient -e db=\/etc/pki/nssdb\ use_hw=no 
soft=(,Test,CAC,,cert1,cert2,cert3) qemu-host 2001
+
+7. Passthrough protocol scenario
+
+This is a typical interchange of messages when using the passthru card device.
+usb-ccid is a usb device. It defaults to an unattached usb device on startup.
+usb-ccid expects a chardev and expects the protocol defined in 
cac_card/vscard_common.h to be passed over that.
+A typical interchange is:
+
+client event  |  vscclient   |passthru| usb-ccid  
|  guest event
+--
+  |  VSC_Init||   |
+  |  VSC_ReaderAdd   || attach|
+  |  ||   
|  sees new usb device.
+card inserted |  ||   |
+  |  VSC_ATR ||   |
+  |  ||   
|  guest operation, APDU transfer via CCID
+  |  |   VSC_APDU |   |
+  |  VSC_APDU||   |
+client-physical |  ||   |
+card APDU exchange|  ||   |
+

[Qemu-devel] [PATCH 3/4] add ccid-card-emulated device (v2)

2010-11-09 Thread Alon Levy
changes from v1:
remove stale comments, use only c-style comments
bugfix, forgot to set recv_len
change reader name to 'Virtual Reader'

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 configure   |   21 ++
 hw/ccid-card-emulated.c |  492 +++
 3 files changed, 514 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 0327535..d1f9c46 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,7 +182,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index d1e96bd..875f3c3 100755
--- a/configure
+++ b/configure
@@ -2130,6 +2130,27 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  cat  $TMPC  EOF
+#include vscard_common.h
+int main() { return 0; }
+EOF
+  smartcard_cflags=$($pkgconfig --cflags cac_card cac_card 2/dev/null)
+  smartcard_libs=$($pkgconfig --libs cac_card cac_card 2/dev/null)
+  if $pkgconfig --atleast-version=0.0.1 cac_card \
+ compile_prog $smartcard_cflags $smartcard_libs ; then
+smartcard=yes
+libs_softmmu=$smartcard_libs $libs_softmmu
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..828cc6c
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,492 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(card, lvl, fmt, ...) \
+do { if (lvl = card-debug) { printf(ccid-card-emul: %s:  fmt , __func__, 
## __VA_ARGS__); } } while (0)
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated /* the default */
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */
+pthread_mutex_t handle_apdu_mutex;
+pthread_cond_t handle_apdu_cond

Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-11-10 Thread Alon Levy
On Wed, Nov 10, 2010 at 04:49:38PM +0100, Markus Armbruster wrote:
 Sorry for coming so late to this thread...
 
 Alon Levy al...@redhat.com writes:
 
  On Thu, Oct 21, 2010 at 08:13:19AM -0500, Anthony Liguori wrote:
  On 10/21/2010 08:03 AM, Gerd Hoffmann wrote:
  On 10/21/10 08:36, Alon Levy wrote:
  v2-v3 changes:
* add configure parameter
* fix docs
  
  v2 message:
  This patchset uses id like device_del for attaching/detaching usb
  devices. The first two patches ready the way:
1. makes qdev_find_recursive non static and in qdev.h
2. adds a usb_device_by_id which goes over the usb buses calling
 qdev_find_recursive
3. adds the commands that use usb_device_by_id
  
  Alon Levy (3):
 qdev: make qdev_find_recursive public
 usb: add public usb_device_by_id
 monitor: add usb_attach and usb_detach (v2)
  
  
  Acked-by: Gerd Hoffmann kra...@redhat.com
  
  Okay, I am still confused about the use-case for this and I don't
  see any further explanation in the commit messages.  I've seen
  debugging but can you be a bit more specific about which cases
  it's needed for?
  
 
  I use it for debugging the usb-ccid device. I think it's useful for
  any other usb device tests as well. The existing commands are not
  good enough to do a remove/insert of a usb device, since deleting
  a device also deletes any chardev associated with it, and there is
  no monitor command to add a chardev. Also sometimes you don't want
  to close the chardev, just have the guest see a removal/reinsert of
  the device.
 [...]
 
 Let's see whether I get you: detach removes the device, but doesn't
 destroy it.  The only thing you can do with a detached device is attach
 it.  Detach+attach is basically the same as del+add with the same
 configuration.  Except shortcomings in our command set make it
 impossible to recreate the configuration sometimes.  Correct?
So the problems with the current commands from my pov:
 - device deletion removes associated chardev
  - no way to do it without removing chardev
  - no way to add chardev later and use it for device add
The outcome of which is that you can't do a guest wise attach/detach
from monitor if your device relies on a chardev association. This
happens with my passthrough ccid device.

 
 Questions:
 
 1. If we add commands so that you can always recreate the configuration,
is detach+attach still useful?  Why?
If you make it so you can do a device_del and not remove the chardev, and
later device_add using the already existing chardev, then that will be
equivalent for me.

 
 2. Why is this a USB problem, and not a general problem?  In other
words, why usb_{detach,attach}, and not device_{detach,attach}?
I guess attach/detach is a don't-free-some-resources del/add. If you
think there are users for a device_attach/detach and it makes sense
conceptually (what's a detach/attach for an ide bus? for a pci it's
pretty clear, for sata, etc.) then you could blow this up to a device
specific callback or something like that (assuming that's how you
would implement this).





Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-11-11 Thread Alon Levy
On Thu, Nov 11, 2010 at 11:29:36AM +0100, Markus Armbruster wrote:
 Alon Levy al...@redhat.com writes:
 
  On Wed, Nov 10, 2010 at 04:49:38PM +0100, Markus Armbruster wrote:
  Sorry for coming so late to this thread...
  
  Alon Levy al...@redhat.com writes:
  
   On Thu, Oct 21, 2010 at 08:13:19AM -0500, Anthony Liguori wrote:
   On 10/21/2010 08:03 AM, Gerd Hoffmann wrote:
   On 10/21/10 08:36, Alon Levy wrote:
   v2-v3 changes:
 * add configure parameter
 * fix docs
   
   v2 message:
   This patchset uses id like device_del for attaching/detaching usb
   devices. The first two patches ready the way:
 1. makes qdev_find_recursive non static and in qdev.h
 2. adds a usb_device_by_id which goes over the usb buses calling
  qdev_find_recursive
 3. adds the commands that use usb_device_by_id
   
   Alon Levy (3):
  qdev: make qdev_find_recursive public
  usb: add public usb_device_by_id
  monitor: add usb_attach and usb_detach (v2)
   
   
   Acked-by: Gerd Hoffmann kra...@redhat.com
   
   Okay, I am still confused about the use-case for this and I don't
   see any further explanation in the commit messages.  I've seen
   debugging but can you be a bit more specific about which cases
   it's needed for?
   
  
   I use it for debugging the usb-ccid device. I think it's useful for
   any other usb device tests as well. The existing commands are not
   good enough to do a remove/insert of a usb device, since deleting
   a device also deletes any chardev associated with it, and there is
   no monitor command to add a chardev. Also sometimes you don't want
   to close the chardev, just have the guest see a removal/reinsert of
   the device.
  [...]
  
  Let's see whether I get you: detach removes the device, but doesn't
  destroy it.  The only thing you can do with a detached device is attach
  it.  Detach+attach is basically the same as del+add with the same
  configuration.  Except shortcomings in our command set make it
  impossible to recreate the configuration sometimes.  Correct?
  So the problems with the current commands from my pov:
   - device deletion removes associated chardev
- no way to do it without removing chardev
- no way to add chardev later and use it for device add
  The outcome of which is that you can't do a guest wise attach/detach
  from monitor if your device relies on a chardev association. This
  happens with my passthrough ccid device.
 
 Commands chardev_add, chardev_del look feasible to me.
 
 I hate device_del destroying chardevs automatically.  If it was created
 separately, it should be destroyed separately.  But any fix needs to be
 backwards compatible somehow.  How to do that without embarrassingly
 ugly warts isn't obvious to me.
 
  Questions:
  
  1. If we add commands so that you can always recreate the configuration,
 is detach+attach still useful?  Why?
  If you make it so you can do a device_del and not remove the chardev, and
  later device_add using the already existing chardev, then that will be
  equivalent for me.
 
 Would chardev_add suffice, or do you need a way to reuse the existing
 chardev?
 
I'd love chardev_add / chardev_del for testing in general, but they don't
work for my use case, because chardev_del closes the socket (in my case).
I could of course fix my client to work with reconnect, but it doesn't make
this pretty.

  2. Why is this a USB problem, and not a general problem?  In other
 words, why usb_{detach,attach}, and not device_{detach,attach}?
  I guess attach/detach is a don't-free-some-resources del/add. If you
  think there are users for a device_attach/detach and it makes sense
  conceptually (what's a detach/attach for an ide bus? for a pci it's
  pretty clear, for sata, etc.) then you could blow this up to a device
  specific callback or something like that (assuming that's how you
  would implement this).
 
 For buses that don't support hot plug, such as IDE, detach makes as much
 sense as delete: none.
 
 For buses that do (USB, PCI, SCSI, virtio-serial-bus), detach looks like
 the first half of delete to me: shut down, remove from device tree
 (second half is destroying the device object).
 
 Likewise, attach looks like the second have of add: insert into device
 tree, start up (first half is creating the device object).
 
 Pitfall: to make re-attach work, qdev method init() needs to work not
 just for newly created objects, but after a qdev exit() as well.  This
 is a change of contract for these two methods.  I wouldn't be surprised
 if not all of our device were happy with that.
 

We could flag which devices can do re-attach. Or you go across the board
and add a info-detach, info-attach, split from info-exit, info-init.
Not a small amount of work :/ Actually, I think you'd need to do that anyway
to get any benefit from the detach/attach commands (apart from not deleting
associated chardevs).




Re: [Qemu-devel] [PATCH 0/3] add usb_detach and usb_attach (v3)

2010-11-11 Thread Alon Levy
On Thu, Nov 11, 2010 at 04:03:14PM +0100, Markus Armbruster wrote:
[snip]
 Agree.
 
 Summary so far:
 
 1. usb_{attach,detach} looks like yet another special-purpose command
where a general command would make sense, namely
device_{attach,detach}.  We have a few of those, e.g. usb_add
vs. device_add.  I'd prefer not to add more, as far as practical.
 
 2. We need chardev_add and chardev_del sooner rather than later.
 
 3. Automatic deletion of host devices (character, block, net) gets in
the way[*].  We need a way to suppress it.
 
 4. If we have 2. and 3., we don't need 1.
 
 Fair?
Yes.

 
 
 [*] Funny coincidence: I just read Neil Brown's essay on the conflated
 design anti-pattern, http://lwn.net/Articles/412131/



Re: [Qemu-devel] [PATCH 0/4] usb-ccid (v6)

2010-11-17 Thread Alon Levy
ping?

On Tue, Nov 09, 2010 at 02:22:06PM +0200, Alon Levy wrote:
 This patchset adds three new devices, usb-ccid, ccid-card-passthru and
 ccid-card-emulated, providing a CCID bus, a simple passthru protocol
 implementing card requiring a client, and a standalone emulated card.
 
 v5-v6 changes:
  * really remove static debug (I apologize for claiming to have done so 
 before)
 
 v4-v5 changes:
  * rebased to latest
  * remove static debug in card devices
  * fix --enable-smartcard to link
  * stall instead of assert when exceeding BULK_OUT_DATA_SIZE
  * make ccid_reserve_recv_buf for too large len discard message, not exit
  * make ccid_reserve_recv_buf return void*
  * fix typo
  * remove commented code in VMState
 
 v3-v4:
  * remove ccid field in CCIDBus
  * remove static debug in bus
  * add back docs
 
 v2-v3:
  * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
  * removed documentation (being revised).
 
 v1-v2:
  * all QSIMPLEQ turned into fixed sized rings
  * all allocated buffers turned into fixed size buffers
  * added migration support
  * added a message to tell client qemu has migrated to ip:port
   * for lack of monitor commands ip:port are 0:0, which causes the updated
vscclient to connect to one port higher on the same host. will add monitor
commands in a separate patch. tested with current setup.
 
 Alon Levy (4):
   usb-ccid: add CCID bus
   ccid: add passthru card device
   add ccid-card-emulated device (v2)
   ccid: add docs
 
  Makefile.objs   |1 +
  configure   |   33 ++
  docs/ccid.txt   |  133 +
  hw/ccid-card-emulated.c |  492 +
  hw/ccid-card-passthru.c |  277 ++
  hw/ccid.h   |   34 ++
  hw/usb-ccid.c   | 1342 
 +++
  hw/vscard_common.h  |  130 +
  8 files changed, 2442 insertions(+), 0 deletions(-)
  create mode 100644 docs/ccid.txt
  create mode 100644 hw/ccid-card-emulated.c
  create mode 100644 hw/ccid-card-passthru.c
  create mode 100644 hw/ccid.h
  create mode 100644 hw/usb-ccid.c
  create mode 100644 hw/vscard_common.h
 
 -- 
 1.7.3.2
 
 



[Qemu-devel] usb-ccid notes for today's meeting

2010-11-23 Thread Alon Levy
Hi,

 I've compiled the list of objections from the previous round of talks between 
Anthony and {Robert and I}, with our answers, for reference in todays talk 
(sorry about late send).

Notes for KVM meeting.

Points raised by anthony:
 1. How does the smart card state get migrated?
 2. How do you benefit from tracing and debugging qemu infrastructure?
 3. Device creation is difficult, you need to launch and configure the external 
daemon.
 4. Why not: use in qemu emulated card, and develop a protocol for connecting 
to the remote card.
 5. I think a remote passthrough protocol who's sole purpose is to allow
 external device emulation is a bad idea for QEMU.
 6. Security concert: possible guest breaking into spice client.

Answers:
 1. in emulated: isn't, there will be a different card on the new host anyway.
in passthru: no need, only usb-ccid state needs migration (and that is 
trivial). the rest has never moved, since it is in the client.
Other important notes on migration:
 1. This is just like passthrough, only with the remote side staying put 
during migration (as noted by anthony himself).
 2. We do emulate on the client side, but that is not required to 
participate in qemu features, it is not expected to migrate for instance, and 
is there to provide the locking (to allow multiple card users, qemu being one 
of them).

 2. we don't for the passthru, we do for the usb-ccid and emulated cards. We 
can test usb-ccid using the emulated card. So far the only problems that were 
not elementary to fix were with usb layer.

 3. for passthrough we already have a daemon, called spicec, which we will 
reuse. For emulated card this is not a problem.

 4. Two protocols seems overkill, although it is doable. A second protocol not 
based on smart card spec may impede our future flexibility wrt new smart cards.

 5. The passthrough usage for spice is to allow locking, and that requires a 
remote emulator. But it can be used by itself with vscclient in passthrough 
mode (vscclient is part of cac_card repository) and then there is no external 
emulation.

 6. We already have an existing daemon, which needs to live with these security 
concerns. 


Alon



[Qemu-devel] [PATCH 2/6] ccid: add passthru card device

2010-11-25 Thread Alon Levy
For the client side utility vscclient, see libcac_card:

  libcac_card http://cgit.freedesktop.org/~alon/cac_card (temporary home)
  written by Robert Relyea rrel...@redhat.com

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-passthru.c |  277 +++
 hw/vscard_common.h  |  130 ++
 3 files changed, 408 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/vscard_common.h

diff --git a/Makefile.objs b/Makefile.objs
index 713131f..2059e89 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -183,7 +183,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 000..fbc4124
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,277 @@
+/*
+ * CCID Card Device emulation
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+#include hw/vscard_common.h
+
+#define DPRINTF(card, lvl, fmt, ...) \
+do { if (lvl = card-debug) { printf(ccid-card:  fmt , ## __VA_ARGS__); } } 
while (0)
+
+/* Passthru card */
+
+
+// TODO: do we still need this?
+uint8_t DEFAULT_ATR[] = {
+/* From some example somewhere
+ 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 
0x13, 0x08
+
+}; /* maximum size of ATR - from 7816-3 */
+
+
+#define PASSTHRU_DEV_NAME ccid-card-passthru
+#define VSCARD_IN_SIZE 65536
+#define MAX_ATR_SIZE40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+CCIDCardState base;
+CharDriverState *cs;
+uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+uint32_t vscard_in_pos;
+uint32_t vscard_in_hdr;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+uint8_t debug;
+};
+
+/* VSCard protocol over chardev
+ * This code should not depend on the card type.
+ * */
+
+static void ccid_card_vscard_send_msg(
+PassthruState *s, VSCMsgType type, reader_id_t reader_id,
+const uint8_t* payload, uint32_t length)
+{
+VSCMsgHeader scr_msg_header;
+
+scr_msg_header.type = type;
+scr_msg_header.reader_id = reader_id;
+scr_msg_header.length = length;
+qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_write(s-cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(
+PassthruState *s, const uint8_t* apdu, uint32_t length)
+{
+ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, 
length);
+}
+
+static void ccid_card_vscard_send_error(
+PassthruState *s, reader_id_t reader_id, VSCErrorCode code)
+{
+VSCMsgError msg = {.code=code};
+
+ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, 
sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+VSCMsgInit msg = {.version=VSCARD_VERSION};
+
+ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+ (uint8_t*)msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+return 65535;
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+VSCMsgHeader* scr_msg_header)
+{
+uint8_t *data = (uint8_t*)scr_msg_header[1];
+
+switch (scr_msg_header-type) {
+case VSC_ATR:
+DPRINTF(card, 1, VSC_ATR %d\n, scr_msg_header-length);
+assert(scr_msg_header-length = MAX_ATR_SIZE);
+memcpy(card-atr, data, scr_msg_header-length);
+card-atr_length = scr_msg_header-length;
+ccid_card_card_inserted(card-base);
+break;
+case VSC_APDU:
+ccid_card_send_apdu_to_guest(card-base, data, 
scr_msg_header-length);
+break;
+case VSC_CardRemove:
+DPRINTF(card, 1, VSC_CardRemove\n);
+ccid_card_card_removed(card-base);
+break;
+case VSC_Init:
+break;
+case VSC_Error:
+ccid_card_card_error(card-base, *(uint64_t*)data);
+break;
+case VSC_ReaderAdd:
+if (ccid_card_ccid_attach(card-base)  0) {
+ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+  VSC_CANNOT_ADD_MORE_READERS);
+} else {
+ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse,
+ VSCARD_MINIMAL_READER_ID, NULL, 
0);
+}
+break

[Qemu-devel] [PATCH 0/6] usb-ccid (v7)

2010-11-25 Thread Alon Levy
This patchset adds three new devices, usb-ccid, ccid-card-passthru and
ccid-card-emulated, providing a CCID bus, a simple passthru protocol
implementing card requiring a client, and a standalone emulated card.

It also introduces a new directory libcaccard with CAC card emulation,
CAC is a type of ISO 7816 smart card.

v6-v7 changes:
 * external libcaccard became internal directory libcaccard
  * statically link object files into qemu
  * produce libcaccard.so for usage by external projects
  * applied coding style to new code (please check me)
  - did not use the qemu options parsing for libcaccard, since
   it seems to draw large amounts of qemu code (monitor for instance).

v5-v6 changes:
 * really remove static debug (I apologize for claiming to have done so before)

v4-v5 changes:
 * rebased to latest
 * remove static debug in card devices
 * fix --enable-smartcard to link
 * stall instead of assert when exceeding BULK_OUT_DATA_SIZE
 * make ccid_reserve_recv_buf for too large len discard message, not exit
 * make ccid_reserve_recv_buf return void*
 * fix typo
 * remove commented code in VMState

v3-v4:
 * remove ccid field in CCIDBus
 * remove static debug in bus
 * add back docs

v2-v3:
 * split into bus (usb-ccid.c, uses ccid.h) and card (ccid-card-passthru.c).
 * removed documentation (being revised).

v1-v2:
 * all QSIMPLEQ turned into fixed sized rings
 * all allocated buffers turned into fixed size buffers
 * added migration support
 * added a message to tell client qemu has migrated to ip:port
  * for lack of monitor commands ip:port are 0:0, which causes the updated
   vscclient to connect to one port higher on the same host. will add monitor
   commands in a separate patch. tested with current setup.

Alon Levy (5):
  usb-ccid: add CCID bus
  ccid: add passthru card device
  libcaccard: update configure to build and use internal libcaccard
  add ccid-card-emulated device (v2)
  ccid: add docs

Robert Relyea (1):
  libcaccard: initial commit after coding style fixes

 Makefile |6 +-
 Makefile.objs|6 +
 Makefile.target  |2 +
 configure|   36 ++
 docs/ccid.txt|  125 
 docs/libcaccard.txt  |  482 +++
 hw/ccid-card-emulated.c  |  492 
 hw/ccid-card-passthru.c  |  277 +
 hw/ccid.h|   34 ++
 hw/usb-ccid.c| 1342 ++
 hw/vscard_common.h   |  130 
 libcaccard/Makefile  |   18 +
 libcaccard/cac.c |  411 +
 libcaccard/cac.h |   20 +
 libcaccard/card_7816.c   |  780 
 libcaccard/card_7816.h   |   60 ++
 libcaccard/card_7816t.h  |  163 +
 libcaccard/config.h  |   81 +++
 libcaccard/event.c   |  112 
 libcaccard/eventt.h  |   28 +
 libcaccard/link_test.c   |   20 +
 libcaccard/mutex.h   |   59 ++
 libcaccard/passthru.c|  608 +++
 libcaccard/passthru.h|   50 ++
 libcaccard/vcard.c   |  350 +++
 libcaccard/vcard.h   |   85 +++
 libcaccard/vcard_emul.h  |   59 ++
 libcaccard/vcard_emul_nss.c  | 1147 
 libcaccard/vcard_emul_type.c |   60 ++
 libcaccard/vcard_emul_type.h |   29 +
 libcaccard/vcardt.h  |   66 ++
 libcaccard/vevent.h  |   26 +
 libcaccard/vreader.c |  515 
 libcaccard/vreader.h |   53 ++
 libcaccard/vreadert.h|   23 +
 libcaccard/vscard_common.h   |  131 
 libcaccard/vscclient.c   |  710 ++
 37 files changed, 8594 insertions(+), 2 deletions(-)
 create mode 100644 docs/ccid.txt
 create mode 100644 docs/libcaccard.txt
 create mode 100644 hw/ccid-card-emulated.c
 create mode 100644 hw/ccid-card-passthru.c
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c
 create mode 100644 hw/vscard_common.h
 create mode 100644 libcaccard/Makefile
 create mode 100644 libcaccard/cac.c
 create mode 100644 libcaccard/cac.h
 create mode 100644 libcaccard/card_7816.c
 create mode 100644 libcaccard/card_7816.h
 create mode 100644 libcaccard/card_7816t.h
 create mode 100644 libcaccard/config.h
 create mode 100644 libcaccard/event.c
 create mode 100644 libcaccard/eventt.h
 create mode 100644 libcaccard/link_test.c
 create mode 100644 libcaccard/mutex.h
 create mode 100644 libcaccard/passthru.c
 create mode 100644 libcaccard/passthru.h
 create mode 100644 libcaccard/vcard.c
 create mode 100644 libcaccard/vcard.h
 create mode 100644 libcaccard/vcard_emul.h
 create mode 100644 libcaccard/vcard_emul_nss.c
 create mode 100644 libcaccard/vcard_emul_type.c
 create mode 100644 libcaccard/vcard_emul_type.h
 create mode 100644 libcaccard/vcardt.h
 create mode 100644 libcaccard/vevent.h
 create mode 100644 libcaccard/vreader.c
 create mode 100644 libcaccard/vreader.h
 create mode 100644

[Qemu-devel] [PATCH 4/6] libcaccard: update configure to build and use internal libcaccard

2010-11-25 Thread Alon Levy
Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile|6 --
 Makefile.objs   |5 +
 Makefile.target |2 ++
 configure   |   24 
 libcaccard/Makefile |   18 ++
 5 files changed, 53 insertions(+), 2 deletions(-)
 create mode 100644 libcaccard/Makefile

diff --git a/Makefile b/Makefile
index 4e120a2..e673bf1 100644
--- a/Makefile
+++ b/Makefile
@@ -172,6 +172,8 @@ check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS)
 check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_DEPS)
 
+QEMULIBS=libhw32 libhw64 libuser libdis libdis-user libcaccard
+
 clean:
 # avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h 
gen-op-arm.h
@@ -183,7 +185,7 @@ clean:
rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
rm -f trace-dtrace.h trace-dtrace.h-timestamp
$(MAKE) -C tests clean
-   for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \
+   for d in $(ALL_SUBDIRS) $(QEMULIBS); do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
rm -f $$d/qemu-options.def; \
 done
@@ -194,7 +196,7 @@ distclean: clean
rm -f roms/seabios/config.mak roms/vgabios/config.mak
rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn 
qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc 
qemu-doc.tp qemu-doc.vr
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi 
qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf 
qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
-   for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; do \
+   for d in $(TARGET_DIRS) $(QEMULIBS); do \
rm -rf $$d || exit 1 ; \
 done
 
diff --git a/Makefile.objs b/Makefile.objs
index 2059e89..82691c0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -297,6 +297,11 @@ user-obj-y += qemu-timer-common.o
 endif
 endif
 
+##
+# smartcard
+
+libcaccard-y = cac.o event.o passthru.o vcard.o vreader.o vcard_emul_nss.o 
vcard_emul_type.o card_7816.o
+
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/Makefile.target b/Makefile.target
index 2800f47..7dd6932 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -341,6 +341,8 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 
 endif # CONFIG_SOFTMMU
 
+obj-y += $(addprefix $(SRC_PATH)/libcaccard/, 
$(libcaccard-$(CONFIG_SMARTCARD)))
+
 obj-y += $(addprefix ../, $(trace-obj-y))
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
diff --git a/configure b/configure
index fb9eac2..4b55904 100755
--- a/configure
+++ b/configure
@@ -2130,6 +2130,25 @@ EOF
   fi
 fi
 
+# check for libcaccard for smartcard support
+if test $smartcard != no ; then
+  smartcard_cflags=-I\$(SRC_PATH)/libcaccard
+  smartcard_libs=-L\$(SRC_PATH)/libcaccard -lcaccard
+  libcaccard_libs=$($pkgconfig --libs nss 2/dev/null)
+  libcaccard_cflags=$($pkgconfig --cflags nss)
+  # TODO - what's the minimal nss version we support?
+  if $pkgconfig --atleast-version=3.12.8 nss; then
+smartcard=yes
+QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags $libcaccard_cflags
+LIBS=$libcaccard_libs $LIBS
+  else
+if test smartcard = yes ; then
+  feature_not_found smartcard
+fi
+smartcard=no
+  fi
+fi
+
 ##
 
 ##
@@ -2956,6 +2975,11 @@ fi
 if test $target_darwin_user = yes ; then
   echo CONFIG_DARWIN_USER=y  $config_target_mak
 fi
+if test $smartcard = yes ; then
+  echo subdir-$target: subdir-libcaccard  $config_host_mak
+  echo libcaccard_libs=$libcaccard_libs  $config_host_mak
+  echo libcaccard_cflags=$libcaccard_cflags  $config_host_mak
+fi
 list=
 if test ! -z $gdb_xml_files ; then
   for x in $gdb_xml_files; do
diff --git a/libcaccard/Makefile b/libcaccard/Makefile
new file mode 100644
index 000..a339af1
--- /dev/null
+++ b/libcaccard/Makefile
@@ -0,0 +1,18 @@
+include ../Makefile.objs
+include ../config-host.mak
+include ../config-all-devices.mak
+include $(SRC_PATH)/rules.mak
+
+CFLAGS+=-fPIC
+
+libcaccard.so: $(libcaccard-y)
+   gcc -shared $(libcaccard_libs) -o $@ $^
+
+vscclient: $(libcaccard-y) vscclient.o
+   gcc $(libcaccard_libs) -o $@ $^
+
+all: libcaccard.so vscclient
+
+clean:
+   rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ libcaccard.so
+
-- 
1.7.3.2




[Qemu-devel] [PATCH 5/6] add ccid-card-emulated device (v2)

2010-11-25 Thread Alon Levy
changes from v1:
remove stale comments, use only c-style comments
bugfix, forgot to set recv_len
change reader name to 'Virtual Reader'

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs   |2 +-
 hw/ccid-card-emulated.c |  492 +++
 2 files changed, 493 insertions(+), 1 deletions(-)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 82691c0..a494ee0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -183,7 +183,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o 
ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 000..828cc6c
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,492 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s 
CN=user$i -n user$i; done 
+ * qemu .. -usb -device usb-ccid -device 
ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using 
the db parameter.
+ *
+ *
+ * Copyright (c) 2010 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+#include pthread.h
+#include eventt.h
+#include vevent.h
+#include vreader.h
+#include vcard_emul.h
+#include qemu-char.h
+#include monitor.h
+#include hw/ccid.h
+
+#define DPRINTF(card, lvl, fmt, ...) \
+do { if (lvl = card-debug) { printf(ccid-card-emul: %s:  fmt , __func__, 
## __VA_ARGS__); } } while (0)
+
+#define EMULATED_DEV_NAME ccid-card-emulated
+
+#define BACKEND_NSS_EMULATED nss-emulated /* the default */
+#define BACKEND_CERTIFICATES certificates
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+EMUL_READER_INSERT = 0,
+EMUL_READER_REMOVE,
+EMUL_CARD_INSERT,
+EMUL_CARD_REMOVE,
+EMUL_GUEST_APDU,
+EMUL_RESPONSE_APDU,
+EMUL_ERROR,
+};
+
+static const char* emul_event_to_string(uint32_t emul_event)
+{
+switch (emul_event) {
+case EMUL_READER_INSERT: return EMUL_READER_INSERT;
+case EMUL_READER_REMOVE: return EMUL_READER_REMOVE;
+case EMUL_CARD_INSERT: return EMUL_CARD_INSERT;
+case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE;
+case EMUL_GUEST_APDU: return EMUL_GUEST_APDU;
+case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU;
+case EMUL_ERROR: return EMUL_ERROR;
+default:
+break;
+}
+return UNKNOWN;
+}
+
+typedef struct EmulEvent {
+QSIMPLEQ_ENTRY(EmulEvent) entry;
+union {
+struct {
+uint32_t type;
+} gen;
+struct {
+uint32_t type;
+uint64_t code;
+} error;
+struct {
+uint32_t type;
+uint32_t len;
+uint8_t data[];
+} data;
+} p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+CCIDCardState base;
+uint8_t  debug;
+char*backend;
+char*cert1;
+char*cert2;
+char*cert3;
+char*db;
+uint8_t  atr[MAX_ATR_SIZE];
+uint8_t  atr_length;
+QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+pthread_mutex_t event_list_mutex;
+VReader *reader;
+QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */
+pthread_mutex_t handle_apdu_mutex;
+pthread_cond_t handle_apdu_cond;
+int  pipe[2];
+int  quit_apdu_thread;
+pthread_mutex_t apdu_thread_quit_mutex;
+pthread_cond_t apdu_thread_quit_cond;
+};
+
+static void emulated_apdu_from_guest(CCIDCardState *base, const uint8_t *apdu, 
uint32_t len)
+{
+EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+EmulEvent *event = (EmulEvent*)malloc(sizeof(EmulEvent) + len);
+
+assert(event);
+event-p.data.type = EMUL_GUEST_APDU;
+event-p.data.len = len;
+memcpy(event-p.data.data, apdu, len);
+pthread_mutex_lock(card-vreader_mutex);
+QSIMPLEQ_INSERT_TAIL(card-guest_apdu_list, event, entry);
+pthread_mutex_unlock(card-vreader_mutex);
+pthread_cond_signal(card-handle_apdu_cond);
+}
+
+static const uint8_t* emulated_get_atr(CCIDCardState *base, uint32_t *len)
+{
+EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+
+*len = card-atr_length

[Qemu-devel] [PATCH 1/6] usb-ccid: add CCID bus

2010-11-25 Thread Alon Levy
A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy al...@redhat.com
---
 Makefile.objs |1 +
 configure |   12 +
 hw/ccid.h |   34 ++
 hw/usb-ccid.c | 1342 +
 4 files changed, 1389 insertions(+), 0 deletions(-)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index 23b17ce..713131f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -183,6 +183,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 2917874..fb9eac2 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+smartcard=no
 
 # OS specific
 if check_define __linux__ ; then
@@ -739,6 +740,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-smartcard) smartcard=no
+  ;;
+  --enable-smartcard) smartcard=yes
+  ;;
   --*dir)
   ;;
   *) echo ERROR: unknown option $opt; show_help=yes
@@ -934,6 +939,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --disable-smartcard  disable smartcard support
+echo   --enable-smartcard   enable smartcard support
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2354,6 +2361,7 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+echo smartcard support $smartcard
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2617,6 +2625,10 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test $smartcard = yes ; then
+  echo CONFIG_SMARTCARD=y  $config_host_mak
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 000..a38f971
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,34 @@
+#ifndef __CCID_H__
+#define __CCID_H__
+
+#include qdev.h
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+struct CCIDCardState {
+DeviceState qdev;
+};
+
+struct CCIDCardInfo {
+DeviceInfo qdev;
+void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t 
len);
+int (*exitfn)(CCIDCardState *card);
+int (*initfn)(CCIDCardState *card);
+};
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t 
len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/* support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local) 
*/
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif // __CCID_H__
+
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 000..66c1dba
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1342 @@
+/*
+ * CCID Device emulation
+ *
+ * Based on usb-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ * Reused for CCID by Alon Levy.
+ * Contributed to by Robert Relyea
+ * Copyright (c) 2010 Red Hat.
+ *
+ * This code is licenced under the LGPL.
+ */
+
+/* References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  Universal Serial Bus, Device Class: Smart Card
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This happens
+ *  when we send a too short packet, seen in uhci-usb.c, resulting from
+ *  a urb requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ *
+ */
+
+#include qemu-common.h
+#include qemu-error.h
+#include usb.h
+#include monitor.h
+
+#include

Re: [Qemu-devel] [PATCH 4/6] libcaccard: update configure to build and use internal libcaccard

2010-11-28 Thread Alon Levy
On Fri, Nov 26, 2010 at 06:50:07PM +, Blue Swirl wrote:
 On Thu, Nov 25, 2010 at 4:22 PM, Alon Levy al...@redhat.com wrote:
  Signed-off-by: Alon Levy al...@redhat.com
  ---
   Makefile            |    6 --
   Makefile.objs       |    5 +
   Makefile.target     |    2 ++
   configure           |   24 
   libcaccard/Makefile |   18 ++
   5 files changed, 53 insertions(+), 2 deletions(-)
   create mode 100644 libcaccard/Makefile
 
  diff --git a/Makefile b/Makefile
  index 4e120a2..e673bf1 100644
  --- a/Makefile
  +++ b/Makefile
  @@ -172,6 +172,8 @@ check-qlist: check-qlist.o qlist.o qint.o 
  $(CHECK_PROG_DEPS)
   check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
   check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o 
  qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o 
  $(CHECK_PROG_DEPS)
 
  +QEMULIBS=libhw32 libhw64 libuser libdis libdis-user libcaccard
  +
   clean:
   # avoid old build problems by removing potentially incorrect old files
         rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h 
  opc-arm.h gen-op-arm.h
  @@ -183,7 +185,7 @@ clean:
         rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
         rm -f trace-dtrace.h trace-dtrace.h-timestamp
         $(MAKE) -C tests clean
  -       for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; 
  do \
  +       for d in $(ALL_SUBDIRS) $(QEMULIBS); do \
         if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
         rm -f $$d/qemu-options.def; \
          done
  @@ -194,7 +196,7 @@ distclean: clean
         rm -f roms/seabios/config.mak roms/vgabios/config.mak
         rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi 
  qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg 
  qemu-doc.toc qemu-doc.tp qemu-doc.vr
         rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi 
  qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf 
  qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
  -       for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; 
  do \
  +       for d in $(TARGET_DIRS) $(QEMULIBS); do \
         rm -rf $$d || exit 1 ; \
          done
 
  diff --git a/Makefile.objs b/Makefile.objs
  index 2059e89..82691c0 100644
  --- a/Makefile.objs
  +++ b/Makefile.objs
  @@ -297,6 +297,11 @@ user-obj-y += qemu-timer-common.o
   endif
   endif
 
  +##
  +# smartcard
  +
  +libcaccard-y = cac.o event.o passthru.o vcard.o vreader.o vcard_emul_nss.o 
  vcard_emul_type.o card_7816.o
  +
   vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
   vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
  diff --git a/Makefile.target b/Makefile.target
  index 2800f47..7dd6932 100644
  --- a/Makefile.target
  +++ b/Makefile.target
  @@ -341,6 +341,8 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 
   endif # CONFIG_SOFTMMU
 
  +obj-y += $(addprefix $(SRC_PATH)/libcaccard/, 
  $(libcaccard-$(CONFIG_SMARTCARD)))
  +
   obj-y += $(addprefix ../, $(trace-obj-y))
   obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
  diff --git a/configure b/configure
  index fb9eac2..4b55904 100755
  --- a/configure
  +++ b/configure
  @@ -2130,6 +2130,25 @@ EOF
    fi
   fi
 
  +# check for libcaccard for smartcard support
  +if test $smartcard != no ; then
  +  smartcard_cflags=-I\$(SRC_PATH)/libcaccard
  +  smartcard_libs=-L\$(SRC_PATH)/libcaccard -lcaccard
  +  libcaccard_libs=$($pkgconfig --libs nss 2/dev/null)
  +  libcaccard_cflags=$($pkgconfig --cflags nss)
  +  # TODO - what's the minimal nss version we support?
  +  if $pkgconfig --atleast-version=3.12.8 nss; then
  +    smartcard=yes
  +    QEMU_CFLAGS=$QEMU_CFLAGS $smartcard_cflags $libcaccard_cflags
  +    LIBS=$libcaccard_libs $LIBS
  +  else
  +    if test smartcard = yes ; then
  +      feature_not_found smartcard
  +    fi
  +    smartcard=no
  +  fi
  +fi
  +
   ##
 
   ##
  @@ -2956,6 +2975,11 @@ fi
   if test $target_darwin_user = yes ; then
    echo CONFIG_DARWIN_USER=y  $config_target_mak
   fi
  +if test $smartcard = yes ; then
  +  echo subdir-$target: subdir-libcaccard  $config_host_mak
  +  echo libcaccard_libs=$libcaccard_libs  $config_host_mak
  +  echo libcaccard_cflags=$libcaccard_cflags  $config_host_mak
  +fi
   list=
   if test ! -z $gdb_xml_files ; then
    for x in $gdb_xml_files; do
  diff --git a/libcaccard/Makefile b/libcaccard/Makefile
  new file mode 100644
  index 000..a339af1
  --- /dev/null
  +++ b/libcaccard/Makefile
  @@ -0,0 +1,18 @@
  +include ../Makefile.objs
  +include ../config-host.mak
  +include ../config-all-devices.mak
  +include $(SRC_PATH)/rules.mak
  +
  +CFLAGS+=-fPIC
  +
  +libcaccard.so: $(libcaccard-y)
  +       gcc -shared $(libcaccard_libs) -o $@ $^
 
 This is not going to work, the shared library would need to be shipped
 with QEMU binaries, with a lot

Re: [Qemu-devel] [PATCH 1/6] usb-ccid: add CCID bus

2010-11-28 Thread Alon Levy
On Fri, Nov 26, 2010 at 07:05:02PM +, Blue Swirl wrote:
 On Thu, Nov 25, 2010 at 4:22 PM, Alon Levy al...@redhat.com wrote:
...
  +/* 6.2.6 RDR_to_PC_SlotStatus definitions */
  +enum {
  +    CLOCK_STATUS_RUNNING = 0,
  +    /* 0 - Clock Running, 1 - Clock stopped in State L, 2 - H,
  +       3 - unkonwn state. rest are RFU
  +     */
  +};
  +
  +typedef struct __attribute__ ((__packed__)) {
 
 Please don't use anonymous structs.
 

ok, fixing for v8.

  +    uint8_t     bMessageType;
 
 Why aHungarian nNotation? It's not QEMU style.
 

These names are taken directly from the spec 
(http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.pdf). I 
did it to make searching in the spec easier for anyone reading the source.

  +    uint32_t    dwLength;
  +    uint8_t     bSlot;
  +    uint8_t     bSeq;
  +} CCID_Header;
 
 Packed structure with unaligned fields. Will this work?
 

Works for x86, same situation for the endianess issue.  I'll change it to 
unpacked and change the writing to the guest to explicitly copy individual 
structs (I'll have to do that for endianess anyway). Should the USB device be 
little endian always? so I need to convert any field written to the guest to 
little endian, and read from the guest to host endianess?

  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_Header hdr;
  +    uint8_t     bStatus;        /* Only used in BULK_IN */
  +    uint8_t     bError;         /* Only used in BULK_IN */
  +} CCID_BULK_IN;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_BULK_IN b;
  +    uint8_t     bClockStatus;
  +} CCID_SlotStatus;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_BULK_IN b;
  +    uint8_t     bProtocolNum;
  +    uint8_t     abProtocolDataStructure[0];
  +} CCID_Parameter;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_BULK_IN b;
  +    uint8_t      bChainParameter;
  +    uint8_t      abData[0];
  +} CCID_DataBlock;
  +
  +/* 6.1.4 PC_to_RDR_XfrBlock */
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_Header  hdr;
  +    uint8_t      bBWI; /* Block Waiting Timeout */
  +    uint16_t     wLevelParameter;
  +    uint8_t      abData[0];
  +} CCID_XferBlock;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_Header hdr;
  +    uint8_t     bPowerSelect;
  +    uint16_t    abRFU;
  +} CCID_IccPowerOn;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_Header hdr;
  +    uint16_t    abRFU;
  +} CCID_IccPowerOff;
  +
  +typedef struct __attribute__ ((__packed__)) {
  +    CCID_Header hdr;
  +    uint8_t     bProtocolNum;
  +    uint8_t    abProtocolDataStructure[0];
  +} CCID_SetParameter;
  +
  +typedef struct {
  +    uint8_t     bMessageType; /* 
  CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange */
  +    uint8_t     bmSlotICCState;
  +} CCID_Notify_Slot_Change;
  +
  +/* used for DataBlock response to XferBlock */
  +typedef struct answer_t {
  +    uint8_t slot;
  +    uint8_t seq;
  +} answer_t;
  +
 
 answer_t is not in line with CODING_STYLE.
 
  +/* pending BULK_IN messages */
  +typedef struct bulk_in_t {
  +    uint8_t  data[BULK_IN_BUF_SIZE];
  +    uint32_t len;
  +    uint32_t pos;
  +} bulk_in_t;
 
 Neither is this.
 

Fixing both for v8.

  +
  +enum {
  +    MIGRATION_NONE,
  +    MIGRATION_MIGRATED,
  +};
  +
  +typedef struct CCIDBus CCIDBus;
  +typedef struct USBCCIDState USBCCIDState;
  +
  +#define MAX_PROTOCOL_SIZE   7
  +
  +/**
  + * powered - defaults to true, changed by PowerOn/PowerOff messages
  + */
  +struct USBCCIDState {
  +    USBDevice dev;
  +    CCIDBus *bus;
  +    CCIDCardState *card;
  +    CCIDCardInfo *cardinfo; /* caching the info pointer */
  +    uint8_t  debug;
  +    uint8_t  auto_attach;
  +    bulk_in_t bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */
  +    uint32_t bulk_in_pending_start;
  +    uint32_t bulk_in_pending_end; /* first free */
  +    uint32_t bulk_in_pending_num;
  +    bulk_in_t *current_bulk_in;
  +    uint8_t  bulk_out_data[BULK_OUT_DATA_SIZE];
  +    uint32_t bulk_out_pos;
  +    uint8_t  bmSlotICCState;
  +    uint8_t  powered;
  +    uint8_t  notify_slot_change;
  +    uint64_t last_answer_error;
  +    answer_t pending_answers[PENDING_ANSWERS_NUM];
  +    uint32_t pending_answers_start;
  +    uint32_t pending_answers_end;
  +    uint32_t pending_answers_num;
  +    uint8_t  bError;
  +    uint8_t  bmCommandStatus;
  +    uint8_t  bProtocolNum;
  +    uint8_t  abProtocolDataStructure[MAX_PROTOCOL_SIZE];
  +    uint32_t ulProtocolDataStructureSize;
  +    uint8_t  attached_vmstate;
  +    uint32_t state_vmstate;
  +    uint8_t  migration_state;
  +    uint32_t migration_target_ip;
  +    uint16_t migration_target_port;
  +};
  +
  +/* Slot specific variables. We emulate a single slot card reader.
  + */
  +
  +
  +/* CCID Spec chapter 4: CCID uses a standard device descriptor per Chapter 
  9,
  + * USB Device Framework, section 9.6.1, in the Universal Serial Bus

  1   2   3   4   5   6   7   8   9   10   >