1 /* $NetBSD: vmt.c,v 1.22 2024/05/09 12:09:59 pho Exp $ */
2 /* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */
3 
4 /*
5  * Copyright (c) 2007 David Crawshaw <david@zentus.com>
6  * Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /*
22  * Protocol reverse engineered by Ken Kato:
23  * https://sites.google.com/site/chitchatvmback/backdoor (dead link)
24  * https://web.archive.org/web/20230325103442/https://sites.google.com/site/chitchatvmback/backdoor (archive)
25  */
26 
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <sys/device.h>
30 #include <sys/module.h>
31 #include <machine/cpuvar.h>
32 
33 #include <dev/sysmon/sysmonvar.h>
34 #include <dev/vmt/vmtreg.h>
35 #include <dev/vmt/vmtvar.h>
36 
37 static int          vmt_match(device_t, cfdata_t, void *);
38 static void         vmt_attach(device_t, device_t, void *);
39 static int          vmt_detach(device_t, int);
40 
41 CFATTACH_DECL_NEW(vmt, sizeof(struct vmt_softc),
42           vmt_match, vmt_attach, vmt_detach, NULL);
43 
44 static int
vmt_match(device_t parent,cfdata_t match,void * aux)45 vmt_match(device_t parent, cfdata_t match, void *aux)
46 {
47           struct cpufeature_attach_args *cfaa = aux;
48           struct cpu_info *ci = cfaa->ci;
49 
50           if (strcmp(cfaa->name, "vm") != 0)
51                     return 0;
52           if ((ci->ci_flags & (CPUF_BSP|CPUF_SP|CPUF_PRIMARY)) == 0)
53                     return 0;
54 
55           return vmt_probe();
56 }
57 
58 static void
vmt_attach(device_t parent,device_t self,void * aux)59 vmt_attach(device_t parent, device_t self, void *aux)
60 {
61           struct vmt_softc *sc = device_private(self);
62 
63           aprint_naive("\n");
64           aprint_normal("\n");
65 
66           sc->sc_dev = self;
67           vmt_common_attach(sc);
68 }
69 
70 static int
vmt_detach(device_t self,int flags)71 vmt_detach(device_t self, int flags)
72 {
73           struct vmt_softc *sc = device_private(self);
74 
75           return vmt_common_detach(sc);
76 }
77 
78 MODULE(MODULE_CLASS_DRIVER, vmt, "sysmon_power,sysmon_taskq");
79 
80 #ifdef _MODULE
81 #include "ioconf.c"
82 #endif
83 
84 static int
vmt_modcmd(modcmd_t cmd,void * aux)85 vmt_modcmd(modcmd_t cmd, void *aux)
86 {
87           int error = 0;
88 
89           switch (cmd) {
90           case MODULE_CMD_INIT:
91 #ifdef _MODULE
92                     error = config_init_component(cfdriver_ioconf_vmt,
93                         cfattach_ioconf_vmt, cfdata_ioconf_vmt);
94 #endif
95                     break;
96           case MODULE_CMD_FINI:
97 #ifdef _MODULE
98                     error = config_fini_component(cfdriver_ioconf_vmt,
99                         cfattach_ioconf_vmt, cfdata_ioconf_vmt);
100 #endif
101                     break;
102           case MODULE_CMD_AUTOUNLOAD:
103                     error = EBUSY;
104                     break;
105           default:
106                     error = ENOTTY;
107                     break;
108           }
109 
110           return error;
111 }
112