If so, does the pixels parameter of the SDL_surface structure points to a position in the GPU's memory instead of the host's memory?
The "pixels" member is only accessible while the surface is locked or if the SDL_MUSTLOCK macro evaluates as false. In the case of hardware surfaces, the idea is that if necessary SDL_MUSTLOCK would evaluate as true, and that SDL_LockSurface() may copy the pixels into a in-memory buffer where they can be modified, and SDL_UnlockSurface() would update the GPU memory version.
This means that SDL_LockSurface() and SDL_UnlockSurface() would be quite expensive calls in such scenarios.
When you set one with the SDL_HWSURFACE flag, are you storing the buffer to the GPU's memory?
Of course, that all depends on getting a real hardware surface to begin with. My understanding is that SDL's default backends on the major operating systems, as of version 1.2.X, do not support "hardware" surfaces. SDL 1.3/2.0 redesigned the rendering API to allow for hardware accelerated backends to be the default, but I have fallen behind on the status of this project so I don't know whether it is production ready yet. For the older version, I'd strongly recommend Bob Pendleton's SDL articles as particularly excellent.