@@ -52,6 +52,7 @@ static inline void monitor_ctrlreg_disable_traps(struct domain *d)
}
}
+/* Implicitly serialized by the domctl lock. */
int monitor_init_domain(struct domain *d)
{
if ( likely(!d->arch.monitor.msr_bitmap) )
@@ -64,6 +65,10 @@ int monitor_init_domain(struct domain *d)
return 0;
}
+/*
+ * Implicitly serialized by the domctl lock,
+ * or on domain cleanup paths only.
+ */
void monitor_cleanup_domain(struct domain *d)
{
xfree(d->arch.monitor.msr_bitmap);
@@ -18,10 +18,11 @@
* License along with this program; If not, see <http://www.gnu.org/licenses/>.
*/
+#include <asm/monitor.h>
#include <asm/vm_event.h>
/* Implicitly serialized by the domctl lock. */
-int vm_event_init_domain(struct domain *d)
+int vm_event_init_domain(struct domain *d, struct vm_event_domain *ved)
{
int rc = 0;
struct vcpu *v;
@@ -40,10 +41,14 @@ int vm_event_init_domain(struct domain *d)
}
}
+ /* Initialize specified subsystem. */
+ if ( &d->vm_event->monitor == ved )
+ rc = monitor_init_domain(d);
+
err:
if ( unlikely(rc) )
/* On fail cleanup whatever resources have been partially allocated. */
- vm_event_cleanup_domain(d);
+ vm_event_cleanup_domain(d, ved);
return rc;
}
@@ -52,10 +57,14 @@ err:
* Implicitly serialized by the domctl lock,
* or on domain cleanup paths only.
*/
-void vm_event_cleanup_domain(struct domain *d)
+void vm_event_cleanup_domain(struct domain *d, struct vm_event_domain *ved)
{
struct vcpu *v;
+ /* Uninitialize specified subsystem. */
+ if ( &d->vm_event->monitor == ved )
+ monitor_cleanup_domain(d);
+
/* Per-vcpu uninitializations. */
for_each_vcpu ( d, v )
{
@@ -41,8 +41,8 @@
static int vm_event_enable(
struct domain *d,
- xen_domctl_vm_event_op_t *vec,
struct vm_event_domain *ved,
+ unsigned long xen_port,
int pause_flag,
int param,
xen_event_channel_notification_t notification_fn)
@@ -64,7 +64,7 @@ static int vm_event_enable(
vm_event_ring_lock_init(ved);
vm_event_ring_lock(ved);
- rc = vm_event_init_domain(d);
+ rc = vm_event_init_domain(d, ved);
if ( rc < 0 )
goto err;
@@ -83,7 +83,7 @@ static int vm_event_enable(
if ( rc < 0 )
goto err;
- ved->xen_port = vec->port = rc;
+ ved->xen_port = xen_port = rc;
/* Prepare ring buffer */
FRONT_RING_INIT(&ved->front_ring,
@@ -232,7 +232,7 @@ static int vm_event_disable(struct domain *d, struct vm_event_domain *ved)
destroy_ring_for_helper(&ved->ring_page,
ved->ring_pg_struct);
- vm_event_cleanup_domain(d);
+ vm_event_cleanup_domain(d, ved);
vm_event_ring_unlock(ved);
}
@@ -630,7 +630,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec,
break;
/* domain_pause() not required here, see XSA-99 */
- rc = vm_event_enable(d, vec, ved, _VPF_mem_paging,
+ rc = vm_event_enable(d, ved, vec->port, _VPF_mem_paging,
HVM_PARAM_PAGING_RING_PFN,
mem_paging_notification);
}
@@ -669,10 +669,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec,
{
case XEN_VM_EVENT_ENABLE:
/* domain_pause() not required here, see XSA-99 */
- rc = monitor_init_domain(d);
- if ( rc )
- break;
- rc = vm_event_enable(d, vec, ved, _VPF_mem_access,
+ rc = vm_event_enable(d, ved, vec->port, _VPF_mem_access,
HVM_PARAM_MONITOR_RING_PFN,
monitor_notification);
break;
@@ -682,7 +679,6 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec,
{
domain_pause(d);
rc = vm_event_disable(d, ved);
- monitor_cleanup_domain(d);
domain_unpause(d);
}
break;
@@ -721,7 +717,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec,
break;
/* domain_pause() not required here, see XSA-99 */
- rc = vm_event_enable(d, vec, ved, _VPF_mem_sharing,
+ rc = vm_event_enable(d, ved, vec->port, _VPF_mem_sharing,
HVM_PARAM_SHARING_RING_PFN,
mem_sharing_notification);
break;
@@ -23,14 +23,23 @@
#include <xen/vm_event.h>
#include <public/domctl.h>
-static inline int vm_event_init_domain(struct domain *d)
+static inline
+int vm_event_init_domain(struct domain *d, struct vm_event_domain *ved)
{
- /* Nothing to do. */
+ /* Initialize specified subsystem. */
+ if ( &d->vm_event->monitor == ved )
+ return monitor_init_domain(d);
+
return 0;
}
-static inline void vm_event_cleanup_domain(struct domain *d)
+static inline
+void vm_event_cleanup_domain(struct domain *d, struct vm_event_domain *ved)
{
+ /* Uninitialize specified subsystem. */
+ if ( &d->vm_event->monitor == ved )
+ monitor_cleanup_domain(d);
+
memset(&d->monitor, 0, sizeof(d->monitor));
}
@@ -31,9 +31,9 @@ struct arch_vm_event {
struct monitor_write_data write_data;
};
-int vm_event_init_domain(struct domain *d);
+int vm_event_init_domain(struct domain *d, struct vm_event_domain *ved);
-void vm_event_cleanup_domain(struct domain *d);
+void vm_event_cleanup_domain(struct domain *d, struct vm_event_domain *ved);
void vm_event_toggle_singlestep(struct domain *d, struct vcpu *v);
For clarity: do init/cleanup of the vm-events subsystems (e.g. functions monitor_init,cleanup_domain()) from the vm-event_init,cleanup_domain() functions. Done by passing-on the ved param from vm_event_enable,disable() functions down to the vm_event_init,cleanup_domain() functions. This makes it easier to follow the init/cleanup sequences for all vm-events subsystems. In the process, we also replace the vec param of vm_event_enable() with a port param, since the op/mode fields of vec are already handled before the function is called. This was also done because conceptually it was strange relying on the ved param in vm_event_init,cleanup_domain() to determine the target vm-event subsystem when we already had vec->mode in vm_event_enable(). Signed-off-by: Corneliu ZUZU <czuzu@bitdefender.com> --- xen/arch/x86/monitor.c | 5 +++++ xen/arch/x86/vm_event.c | 15 ++++++++++++--- xen/common/vm_event.c | 18 +++++++----------- xen/include/asm-arm/vm_event.h | 15 ++++++++++++--- xen/include/asm-x86/vm_event.h | 4 ++-- 5 files changed, 38 insertions(+), 19 deletions(-)